package design import ( "context" "errors" "sort" "strings" "time" ) var ( ErrInvalidInput = errors.New("invalid input") ErrNotFound = errors.New("project not found") ErrConflict = errors.New("project version conflict") ) type ProjectStatus string const ( StatusDraft ProjectStatus = "draft" StatusExploring ProjectStatus = "exploring" StatusReady ProjectStatus = "ready" StatusFailed ProjectStatus = "failed" ) type NodeType string const ( NodeTypeBrief NodeType = "brief" NodeTypeReference NodeType = "reference" NodeTypeImage NodeType = "image" NodeTypeText NodeType = "text" NodeTypeFrame NodeType = "frame" ) type Viewport struct { X float64 Y float64 K float64 } type MockupPoint struct { X float64 `json:"x"` Y float64 `json:"y"` } type MockupMesh struct { Columns int `json:"columns"` Rows int `json:"rows"` Points []MockupPoint `json:"points"` } type MockupPlacement struct { X float64 `json:"x"` Y float64 `json:"y"` Width float64 `json:"width"` Height float64 `json:"height"` } type MockupSurface struct { TargetID string `json:"targetId"` Polygon []MockupPoint `json:"polygon"` Mesh MockupMesh `json:"mesh"` } type MockupSurfaceResult struct { Placement MockupPlacement Surface MockupSurface } type MockupModelMap struct { DataID string `json:"dataId"` Width int `json:"width"` Height int `json:"height"` URL string `json:"url,omitempty"` Data []float64 `json:"data,omitempty"` } type MockupCameraIntrinsics struct { Matrix []float64 `json:"matrix"` } type MockupModel struct { Version int `json:"version"` DepthMap MockupModelMap `json:"depthMap"` DepthScaleMin float64 `json:"depthScaleMin"` DepthScaleMax float64 `json:"depthScaleMax"` ShadeMap MockupModelMap `json:"shadeMap"` SegmentationMap MockupModelMap `json:"segmentationMap"` XOffsetMap MockupModelMap `json:"xOffsetMap"` YOffsetMap MockupModelMap `json:"yOffsetMap"` CameraIntrinsics MockupCameraIntrinsics `json:"cameraIntrinsics"` ColorCorrection string `json:"colorCorrection"` ForegroundImage string `json:"foregroundImage"` } type MockupModelResult struct { Placement MockupPlacement Model MockupModel } type MockupModelAnalysisRequest struct { Project Project Node Node ImageDataURL string ImageWidth int ImageHeight int } type MockupModelAnalysis struct { Placement MockupPlacement Surface MockupSurface Model MockupModel } type MockupBlobData struct { DataID string Width int Height int Data []byte CreatedAt time.Time } type Node struct { ID string Type NodeType Title string X float64 Y float64 Width float64 Height float64 Content string Tone string Status string ParentID string LayerRole string FontSize float64 FontFamily string FontWeight string Color string TextAlign string LineHeight float64 LetterSpacing float64 TextDecoration string TextTransform string Opacity float64 FillColor string StrokeColor string StrokeWidth float64 StrokeStyle string FlipX bool FlipY bool Rotation float64 ImageAdjustments string MockupSurface MockupSurface MockupModel MockupModel MockupSourceContent string } type NodeActionRequest struct { Action string Prompt string ImageModel string ImageSize string Mask string Selection string Options map[string]string } type Connection struct { ID string FromNodeID string ToNodeID string } type Message struct { ID string Role string Type string Title string Content string ThreadID string ActionID string StepID string ToolCallID string Name string ToolHint string Status string CreatedAt time.Time } type Project struct { ID string UserID string Title string Brief string Status ProjectStatus Thumbnail string UpdatedAt time.Time Version string SnapshotID string Canvas string LastThreadID string Viewport Viewport Nodes []Node Connections []Connection Messages []Message } type ProjectSummary struct { ID string UserID string Title string Brief string Status ProjectStatus Thumbnail string UpdatedAt time.Time } type QuickAction struct { ID string Label string Prompt string Icon string } type InspirationItem struct { ID string Title string Category string Description string Accent string } type Repository interface { List(ctx context.Context) ([]ProjectSummary, error) ListPage(ctx context.Context, limit int64, offset int64) ([]ProjectSummary, error) Get(ctx context.Context, id string) (Project, error) Save(ctx context.Context, project Project) error Delete(ctx context.Context, id string) error } type CanvasRepository interface { SaveCanvas(ctx context.Context, project Project, baseVersion string) error } type MockupBlobRepository interface { SaveMockupBlob(ctx context.Context, blob MockupBlobData) error GetMockupBlob(ctx context.Context, dataID string) (MockupBlobData, error) } type MockupModelAnalyzer interface { AnalyzeMockupModel(ctx context.Context, req MockupModelAnalysisRequest) (MockupModelAnalysis, error) } func NormalizeTitle(title string, fallback string) string { title = strings.TrimSpace(title) if title == "" { return fallback } return title } func NormalizePrompt(prompt string) string { return strings.TrimSpace(prompt) } func SortSummaries(items []ProjectSummary) { sort.SliceStable(items, func(i, j int) bool { return items[i].UpdatedAt.After(items[j].UpdatedAt) }) }