f36222c6c6
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
16 KiB
16 KiB
Task Plan: Server-Backed Brand Kit Canvas Context
Goal
Persist Brand Kits by authenticated user, bind one optional Brand Kit to each project/canvas, expose a canvas-header selector, and make every Agent Chat turn and newly created thread use the selected kit as authoritative creative context.
Current Phase
Phases 21-22
Phases
Phase 1: Architecture Discovery
- Map Brand Kit frontend state, project persistence, chat/thread creation, and generation context flow
- Confirm API generation, storage-driver, schema, and test patterns
- Status: complete
Phase 2: API and Domain Design
- Update the
.apicontract before generated code - Define user-owned Brand Kit storage and project binding invariants
- Define server-side prompt injection behavior for all project chat sessions
- Status: complete
Phase 3: Backend Implementation
- Generate handlers/types from the validated API specification
- Implement memory and PostgreSQL Brand Kit persistence keyed by user ID
- Persist and expose project
brandKitId - Inject selected Brand Kit into Agent Chat and new-thread context
- Add backend tests and API documentation
- Status: complete
Phase 4: Frontend Integration
- Replace local-only Brand Kit persistence with authenticated API persistence
- Add canvas-title Brand Kit selector with None and user-owned kits
- Add a Brand Kit selector to the Home prompt composer, including an empty create action
- Keep Brand Kit editor, defaults, and project binding synchronized
- Status: complete
Phase 5: Verification
- Run API validation, generation checks, Go tests/build, frontend typecheck/build
- Verify CRUD, user isolation, project binding, chat context, and selector behavior
- Inspect desktop and mobile browser layouts
- Status: in_progress
Phase 6: Delivery
- Review scope, generated files, and prohibited product references
- Provide preview URL and concise implementation notes
- Status: pending
Phase 7: Device Management Discovery and Design
- Trace the existing account dialog, authentication gateway, and device API behavior
- Define production-grade loading, empty, error, current-device, and destructive-action states
- Status: complete
Phase 8: Device Management Implementation
- Implement the device management view and responsive styling in the existing account surface
- Wire list/remove-all behavior to the authenticated device API without changing unrelated account flows
- Make desktop/mobile session limits configuration-driven and return the effective policy from the device API
- Enforce each configured device-type limit atomically and render last-active timestamps in the browser timezone
- Add focused backend or frontend coverage where the repository supports it
- Status: in_progress
Phase 9: Device Management Verification
- Run focused tests, frontend typecheck/build, and Go verification if backend code changes
- Inspect the authenticated desktop and mobile UI in a real browser
- Status: pending
Phase 10: Device Management Delivery
- Review scope and final diff
- Provide the working preview URL and concise implementation notes
- Status: pending
Phase 11: Visual Annotation Discovery and Design
- Map image toolbar/action generation, canvas transforms, and reusable panel conventions
- Translate the supplied annotation reference into the repository's interaction and visual language
- Status: complete
Phase 12: Visual Annotation Implementation
- Add an image-toolbar entry and visual annotation editing mode
- Support brush, circle, rectangle, and cross marks on the selected image
- Make each mark's AI edit instruction directly editable and removable
- Submit the annotated source through the existing image action generation flow
- Preserve the source node and write generation state/results only to a sibling copy
- Status: in_progress
Phase 13: Visual Annotation Verification
- Add focused interaction/serialization coverage where supported
- Run frontend typecheck/build and inspect desktop/mobile behavior in a real browser
- Status: pending
Phase 14: Visual Annotation Delivery
- Review scope and final diff without altering unrelated user changes
- Provide the working preview URL and concise implementation notes
- Status: pending
Phase 15: CAD Import Discovery and Design
- Trace the canvas asset import, upload, persistence, rendering, and export paths
- Define the supported DWG/DXF conversion boundary and failure states
- Status: complete
Phase 16: CAD Import Implementation
- Confirm no backend API change is required for browser-side conversion
- Add DWG/DXF selection, conversion, SVG/canvas rendering, and user feedback
- Add focused tests and documentation
- Status: complete
Phase 17: CAD Import Verification and Delivery
- Run relevant frontend tests/builds
- Inspect CAD import and canvas behavior in a browser with the exact R12 file
- Review scope and deliver concise support/limitation notes
- Status: complete
Phase 18: General CAD Compatibility Follow-up
- Reproduce the block-heavy DWG timeout and isolate its dominant output path
- Replace recursive INSERT/DIMENSION expansion with reusable SVG block definitions and full insert transforms
- Cover nested blocks, repeated inserts, MINSERT arrays, malformed references, and recursion cycles
- Status: complete
Phase 19: Vector Image Toolbar Follow-up
- Recognize uploaded SVG and CAD-derived SVG nodes as vector images
- Hide the raster image toolbar and show the compact vector/download toolbar for vector nodes
- Preserve original SVG download behavior
- Status: complete
Phase 20: Follow-up Verification and Delivery
- Verify both user-provided CAD files plus representative DWG/DXF regression fixtures
- Run focused tests, typecheck, and production builds
- Verify vector toolbar, rendering, download, and persistence in a real browser
- Status: complete
Phase 21: Vector Reference Message Rendering
- Reproduce CAD-derived SVG references falling back to raw prompt directives
- Parse SVG/CAD reference names with nested parentheses into the existing message capsule
- Verify SVG directives enter the existing thumbnail/hover/copy component path; run tests and production build
- Status: complete
Phase 22: Model-Compatible SVG References
- Identify every canvas frontend submission path that can pass an SVG image reference to image generation
- Rasterize SVG references to transparent WebP only at the model submission boundary
- Cache and replace submitted reference URLs without mutating SVG canvas nodes or display names
- Add focused regression coverage and verify prepared model content receives a WebP asset URL
- Status: complete
Invariants
- Brand Kits are owned and queried only through the authenticated user ID from request context.
- A project may reference zero or one Brand Kit owned by the same user.
- Selecting None clears the binding without deleting the Brand Kit.
- Server-side Agent Chat context is derived from the persisted project binding, never trusted from a client-supplied prompt.
- Home may request a Brand Kit ID only from the authenticated user's list; the server revalidates ownership before binding it.
- Deleting a Brand Kit clears project bindings to it.
- Device sessions are always scoped from the authenticated server-side user identity.
- Bulk device removal preserves the current session unless the product contract explicitly requires otherwise.
- New access and refresh tokens carry an opaque random session ID; the server validates that session before accepting the bearer token.
- Legacy access tokens without a session ID are migrated once from a stable token digest after user validation, preserving existing signed-in users.
- Revoked and expired sessions never authenticate or appear in the active-device list.
- Device metadata is derived from request headers for display only and never used as an authorization signal.
- Device timestamps cross the API boundary as RFC3339 UTC instants and are localized only in the browser's timezone.
- Visual annotation actions never mutate the source image node; their copied result node is the only generation target.
- Desktop and mobile web-session limits come from server configuration; the API returns the effective values and the UI never hard-codes them.
- Imported CAD files are read without mutation; only a sanitized derived SVG is uploaded and rendered, with explicit size, timeout, empty-drawing, and conversion errors.
- Repeated and nested CAD block references are represented once and instanced with SVG references; conversion cost must scale with unique block geometry, not insert count.
- SVG-backed image nodes use vector-only actions and download their source SVG rather than exposing raster editing actions.
- User-message image directives render through one attachment capsule/preview path regardless of raster or SVG source format.
- SVG remains the persisted canvas source; transparent WebP derivatives exist only for model-compatible image inputs.
Errors Encountered
| Error | Attempt | Resolution |
|---|---|---|
zsh rejected an unmatched HomePage/*.css glob |
1 | Replaced the glob with explicit files discovered via rg --files. |
Assumed CanvasWorkspace/index.css, which does not exist |
1 | Locate the workspace stylesheet from its imports before reading it. |
rg treated a pattern beginning with -- name: as a flag |
1 | Use rg -- <pattern> when searching SQLC query annotations. |
Assumed AuthProvider.tsx instead of the component directory entry |
1 | Locate the file with rg --files before any further auth-provider reads. |
| PostgreSQL package test failed after adding project mapping because text conversion helpers were not yet defined | 1 | Add nullable pgtype.Text conversion helpers and rerun the package tests. |
One patch to remove a temporary err = nil line used the wrong surrounding field name |
1 | Reapplied the patch against the exact current lines; no code change was lost. |
Workspace import patch assumed a nonexistent BrandMark import |
1 | Located the actual import block and applied the selector change against current source. |
| First i18n patch used an inexact Chinese source string | 1 | Re-read the locale file and patched the exact key/value context. |
| Existing account-device test called removal without an authenticated session context | 1 | Update the test to resolve the issued bearer identity and assert the new current-session contract. |
Preview backend rejected /dev/stdin because go-zero infers config format from the filename extension |
1 | Use a .yaml symlink to stdin so the transformed preview config retains a recognized extension without creating a repository config file. |
| A second Next development server refused to start because the existing repo-wide dev lock is active | 1 | Use the already-built Next production server on the alternate preview port. |
BSD sed did not support the GNU 0,/pattern/ address used for the preview port substitution |
1 | Replace it with a portable anchored substitution; the backend now listens on 8889. |
| The in-app browser runtime reported no available browser backends | 1 | Keep the verified local preview running and report the browser-only visual inspection gap; do not substitute an unrelated browser surface against the browser skill rules. |
Escaping the psql \d meta-command through Docker produced an invalid command |
1 | Query information_schema.columns and pg_indexes with regular SQL instead. |
| Desktop limit regression test observed two valid desktop sessions when the configured limit was 1 | 1 | Confirmed the limit was presentation-only; enforce it atomically during session creation and reconcile pre-fix sessions during device listing. |
Launching mcp-zero from server/ used a repository-root relative path |
1 | Relaunch with ../.tools/bin/mcp-zero while keeping generation output rooted in server/. |
NPM lookup for a nonexistent @loaders.gl/dxf package returned 404 and stopped the chained lookup |
1 | Use independent package searches and validate the chosen converter package before installation. |
| Package inspection commands raced the tar extraction and looked under the wrong transient path | 1 | Inspect the extracted tree first, then run dependent file reads sequentially against the discovered path. |
npm install inherited a parent workspace containing an unsupported workspace:* URL |
1 | Inspect local package-manager metadata and run installation with workspace discovery disabled or use the repository's actual package manager. |
TypeScript rejected .length on the CAD library's entity collection |
1 | Use the collection's declared count/iteration API instead of assuming it is an array. |
Next 16 Turbopack emitted the module worker as raw .ts instead of executable bundled JavaScript |
1 | Run Next dev/build through its supported webpack mode, which handles new Worker(new URL(...)); retain Vite's native worker bundling. |
Used nonexistent Playwright CLI command network |
1 | Use the CLI's documented requests and response-body commands for network inspection. |
| First Vite DXF upload triggered dependency pre-bundling and a development-page reload | 1 | Retry after Vite finishes one-time dependency optimization; production worker output is already bundled. |
Real upstream DXF fixture parsed to an empty model space in @node-projects/acad-ts |
1 | Validate the library's document assembly in Node, then replace the DXF path or reader entirely if real fixtures remain empty. |
| Directory-wide listing of the WeChat file folder stalled on container-managed storage | 1 | Use the exact user-provided path directly; metadata access confirms the file is readable. |
| The exact R12 DXF crashed while serializing the first inherited-color POINT | 1 | Resolve non-renderable ByLayer/ByBlock colors through the entity and layer before calling the third-party SVG writer; lock the case with a minimal R12 regression test. |
| Next production minification reduced valid DXF geometry to zero-valued entities | 1 | Restore acad-ts constructor names from stable export keys before its name-based metadata lookup; keep the normal minified build and cover the mangled-name path in the regression test. |
| Reusing one entity writer and slicing its cumulative string exhausted the Node heap on the exact R12 drawing | 1 | Give each entity a short-lived fragment writer so output assembly stays linear in total geometry size. |
| Node's strip-only TypeScript test runner rejected constructor parameter properties | 1 | Use explicit class fields and constructor assignments, which preserve the project test runner's supported syntax subset. |
| Vector reference regression suite failed on nested English and Chinese CAD filenames | 1 | Expected red phase confirmed: the directive regex stops before the final filename parenthesis; update it to bind the closing delimiter adjacent to the URL separator. |
First post-fix parser assertion still expected no index property |
1 | The production parser correctly emits index: undefined; align the regression fixture with the stable result shape. |
| In-app browser discovery returned no available browser backend | 1 | Followed the browser skill troubleshooting flow and confirmed an empty backend list; retain automated tests/builds and report the interactive verification gap. |
| Combined final planning patch targeted progress lines as task-plan context | 1 | Split the update by file and apply each change against its exact current section. |