From 59f2b02458e9fbc069f50f056925e72754b32153 Mon Sep 17 00:00:00 2001 From: liangxu Date: Fri, 10 Jul 2026 22:19:28 +0800 Subject: [PATCH] chore: add planning notes for brand kit and agent starter work Co-Authored-By: Claude Opus 4.8 (1M context) --- findings.md | 39 +++++++++++++++++++++++++++++++ progress.md | 37 +++++++++++++++++++++++++++++ task_plan.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 findings.md create mode 100644 progress.md create mode 100644 task_plan.md diff --git a/findings.md b/findings.md new file mode 100644 index 0000000..fa90e9f --- /dev/null +++ b/findings.md @@ -0,0 +1,39 @@ +# Findings: Server-Backed Brand Kit Canvas Context + +## Requirements +- The previous implementation is frontend-only and insufficient for durable user ownership. +- The canvas header needs a compact Brand Kit selector beside the project name. +- The selector contains None plus the authenticated user's Brand Kits and shows the active selection. +- Agent Chat and every new session within that canvas must use the selected Brand Kit as a creative baseline. +- The Home prompt composer also needs a Brand Kit picker. Its empty state provides a direct `创建 Brand Kit` action. + +## Initial Decisions +- Persist the project-to-kit relation on the server and inject context server-side so clients cannot silently omit it. +- Preserve the existing restrained Moteva canvas visual language and use the supplied interaction hierarchy without copying product identifiers. + +## Repository Discovery +- The server is an existing go-zero REST service with one `img_infinite_canvas.api`, generated handlers/types, thin logic files, and a shared `ServiceContext`. +- PostgreSQL persistence is SQLC-based (`server/sqlc.yaml`, `schema.sql`, `query.sql`) while memory storage supports local development and tests. +- The local `mcp-zero` binary and `/Users/liangxu/go/bin/goctl` are both available; API generation can follow the required spec-first workflow. +- The frontend Brand Kit implementation is still uncommitted and browser-local, so it must be migrated carefully without discarding its editor/model work. +- Playwright prerequisites are available, and the user has an authenticated browser session for final integration testing. +- `design.Project` is the common object passed through chat planning, conversation, and image-prompt generation, so adding resolved Brand Kit context there gives one reliable injection point for all Agent Chat flows. +- `design.Repository` currently owns project CRUD; both memory and PostgreSQL implementations enforce user scope through `design.UserIDFromContext`. +- Projects currently persist title/canvas/thread state but no `brandKitId`; SQLC generates PostgreSQL accessors from `schema.sql` and `query.sql`. +- Agent messages already carry `thread_id`, and the request can start a new thread; the selected kit should therefore be loaded from the project before every chat operation rather than copied into individual messages. +- `DesignService.AgentChat` reloads the project before planning every turn, then passes project-scoped copies to planning, research, conversation, and background generation. Hydrating the Brand Kit immediately after that load covers existing and newly created threads. +- Creative-agent prompt builders already centralize project identity through `projectBriefContext`, while deterministic/fallback image generation reads `design.Project`; Brand Kit context should be added to both centralized context builders and agent memory. +- Project creation has synchronous and asynchronous paths. Both should accept an optional requested kit and otherwise bind the authenticated user's default kit server-side. +- An explicit Home selection should override the default kit; the server must still verify that the selected kit belongs to the authenticated user. +- Home's composer has a compact action row with existing Radix Popovers for model selection, making a palette-icon Brand Kit popover a native extension rather than a new interaction pattern. +- Home currently appends a browser-local default kit prompt. This must be removed once project creation sends `brandKitId`, preventing duplicated or client-controlled brand instructions. +- Frontend `Project` and canvas snapshot merge paths need to preserve `brandKitId`; the direct project-document endpoint remains the authoritative source. +- Canvas workspace already centralizes title rendering and project updates, so the selector can live beside `WorkspaceTitle` and update the same in-memory project after a binding API call. +- The existing Brand Kit document is already versioned and contains the requested grouped colors, uploaded fonts with optional sizes/descriptions, logos, cover, references, voice, and visual direction. The server can validate this exact version-1 shape and compile it into authoritative prompt context. +- The project repository abstraction has a single `Save` operation and user-scoped `Get`; adding `BrandKitID` to `design.Project` will naturally flow through memory/cache/realtime wrappers as long as PostgreSQL mapping and API mappers are updated. +- `ServiceContext` constructs storage-specific modules beside the project repository. A dedicated Brand Kit service/store should follow the existing auth/sharing module pattern and use the same configured memory/PostgreSQL driver. +- All `/api/*` routes except the explicit public allowlist already require a valid bearer session, so new `/api/brand-kits` routes automatically enforce login before logic runs. +- SQLC is installed locally. The existing PostgreSQL repository runs the idempotent schema at startup, making schema/query changes plus SQLC regeneration the consistent persistence path. +- Direct image mode currently sends the raw user prompt to image generation, bypassing the creative planner. Brand context therefore must also be added to the direct/fallback image prompt builders, not only long-term memory and `projectBriefContext`. +- Asynchronous create/follow-up jobs reload projects from persistence, so Brand Kit context must be re-resolved inside those job execution paths; hydrating only the initial HTTP turn would be insufficient. +- Uploaded Brand Kit logos, cover images, and reference images are resolved server-side as ephemeral project inputs. Image generation appends them after user-supplied references so existing inline reference numbering remains stable. diff --git a/progress.md b/progress.md new file mode 100644 index 0000000..5fce9cb --- /dev/null +++ b/progress.md @@ -0,0 +1,37 @@ +# Progress Log + +## Session: 2026-07-10 + +### Phase 1: Architecture Discovery +- **Status:** in_progress +- Read repository instructions and the applicable Go, frontend, planning, and browser verification skills. +- Captured the missing backend ownership, project binding, selector, and chat-context requirements. +- Confirmed the existing go-zero API, SQLC/PostgreSQL, memory-store, and code-generation toolchain. +- Located the project domain/repository and established the project object as the server-side Brand Kit context boundary for chat and generation. +- Traced Agent Chat through planning, research, conversation, and asynchronous generation; identified one project-hydration point plus shared prompt builders for complete coverage. +- Added the Home composer Brand Kit picker and empty create action to the implementation scope. +- Mapped the Home composer action row and frontend project hydration paths for `brandKitId` integration. +- Re-read the active plan after session recovery and confirmed the existing frontend edits are limited to the Brand Kit feature surface. +- Loaded the project go-zero workflow plus the applicable planning, Go, and frontend implementation guidance. +- Completed architecture discovery, including authentication enforcement, SQLC persistence, async job reloads, direct image prompts, and frontend project hydration. +- Chose a versioned JSON document API with server-side schema validation and prompt compilation; project responses expose only `brandKitId`, never compiled context. +- Added and validated the API-first contract for Brand Kit list/upsert/delete, project binding, optional project-creation selection, and project response hydration. +- Generated go-zero handlers, logic shells, routes, and types through the local `mcp-zero` stdio server. +- Added SQLC schema and queries for user-owned versioned Brand Kits and optional project bindings, then regenerated SQLC code. +- Implemented memory/PostgreSQL stores, document validation, single-default enforcement, server-side context compilation, project binding cleanup, and API logic. +- Hydrated the active Brand Kit for synchronous chat, asynchronous create/follow-up jobs, conversations, planner memory, creative prompts, and direct/fallback image prompts. +- Added focused ownership/default/binding/context-injection tests. +- Replaced browser-local Brand Kit persistence with authenticated APIs, including a one-time per-user migration. +- Added reusable Brand Kit selectors to the Home composer and canvas title bar; project creation and binding now send only the selected ID. +- Added server-side Brand Kit asset resolution so uploaded logos, covers, and references reach image generation after user references. +- Added Brand Kit API documentation and ownership/default/binding semantics to the server docs. + +## Test Results +| Test | Result | Status | +|------|--------|--------| +| `goctl api validate -api img_infinite_canvas.api` | `api format ok` | pass | +| Targeted Go tests: application, PostgreSQL/memory repositories, logic, service context, error mapping, and prompt agents | all pass | pass | +| `go test ./...` | all packages pass | pass | +| `go build ./...` | build succeeds | pass | +| `npx tsc -b` | typecheck succeeds | pass | +| `npm run build` | Next.js and Vite production builds succeed; existing large-chunk warning only | pass | diff --git a/task_plan.md b/task_plan.md new file mode 100644 index 0000000..979889e --- /dev/null +++ b/task_plan.md @@ -0,0 +1,66 @@ +# 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 5 + +## 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 + +## 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. + +## 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. |