# 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 Phase 12 ## Phases ### Phase 1: Architecture Discovery - [x] Map Brand Kit frontend state, project persistence, chat/thread creation, and generation context flow - [x] Confirm API generation, storage-driver, schema, and test patterns - **Status:** complete ### Phase 2: API and Domain Design - [x] Update the `.api` contract before generated code - [x] Define user-owned Brand Kit storage and project binding invariants - [x] Define server-side prompt injection behavior for all project chat sessions - **Status:** complete ### Phase 3: Backend Implementation - [x] Generate handlers/types from the validated API specification - [x] Implement memory and PostgreSQL Brand Kit persistence keyed by user ID - [x] Persist and expose project `brandKitId` - [x] Inject selected Brand Kit into Agent Chat and new-thread context - [x] Add backend tests and API documentation - **Status:** complete ### Phase 4: Frontend Integration - [x] Replace local-only Brand Kit persistence with authenticated API persistence - [x] Add canvas-title Brand Kit selector with None and user-owned kits - [x] Add a Brand Kit selector to the Home prompt composer, including an empty create action - [x] Keep Brand Kit editor, defaults, and project binding synchronized - **Status:** complete ### Phase 5: Verification - [x] 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 - [x] Trace the existing account dialog, authentication gateway, and device API behavior - [x] 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 - [x] Map image toolbar/action generation, canvas transforms, and reusable panel conventions - [x] 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 ## 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. ## 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 -- ` 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/`. |