docs: record CAD semantic context and vector crop planning notes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-16 16:42:34 +08:00
parent ac6f1d84af
commit e7a0cc0b86
3 changed files with 264 additions and 1 deletions
+87 -1
View File
@@ -4,7 +4,7 @@
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
Phase 32
## Phases
@@ -139,6 +139,72 @@ Phases 21-22
- [x] Add focused regression coverage and verify prepared model content receives a WebP asset URL
- **Status:** complete
### Phase 23: CAD Semantics and Crop Discovery
- [x] Map CAD entity/layer/block/text data through conversion, canvas persistence, references, and Agent Chat generation
- [x] Map the existing crop overlay, sibling-node placement, vector toolbar, and upload/save paths
- [x] Define bounded semantic metadata and crop-output contracts for large drawings
- **Status:** complete
### Phase 24: CAD Semantics and Crop Implementation
- [x] Preserve bounded CAD semantics during DWG/DXF conversion and canvas persistence
- [x] Attach CAD semantic context to model-bound references without exposing it in user-visible chat text
- [x] Add vector crop action that preserves the source and creates a cropped sibling asset
- [x] Make cropped CAD regions attachable and reusable in Agent Chat
- **Status:** complete
### Phase 25: CAD Semantics and Crop Verification
- [x] Add conversion, persistence, semantic-payload, crop, and source-preservation regression coverage
- [x] Verify both supplied CAD files, focused Go/frontend tests, typecheck, and production builds
- [x] Attempt real-browser crop/reference inspection and record the unavailable browser backend
- **Status:** complete
### Phase 26: CAD Semantics and Crop Delivery
- [x] Review scope and generated files without altering unrelated changes
- [x] Document the semantic contract, crop behavior, and preview URL
- **Status:** complete
### Phase 27: Non-Passive Canvas Wheel Regression
- [x] Add a deterministic regression test for non-passive element-level wheel listener registration and cleanup
- [x] Replace the React synthetic canvas wheel handler with a native `{ passive: false }` listener
- [x] Verify zoom behavior, DWG upload flow, focused/full tests, and production build
- **Status:** complete
### Phase 28: Workspace Toolbar Crop Action
- [x] Add a persistent Crop icon immediately after the Text tool
- [x] Enable it only for a selected, ready image/vector node and reuse the existing crop overlay
- [x] Verify icon order, disabled/active states, crop entry, tests, and production build
- **Status:** complete
### Phase 29: Enlarged Single-Image Crop
- [x] Add regression coverage for translating the visible viewport intersection into normalized crop coordinates
- [x] Let workspace Crop automatically target the only visible image when none is selected
- [x] Anchor the crop selection and controls inside the visible viewport for oversized images
- [x] Verify enlarged-image crop entry, multi-image ambiguity, tests, and production build
- **Status:** complete
### Phase 30: Native-Resolution Vector Crop Fidelity
- [x] Reproduce the CAD SVG crop stroke/text degradation with a deterministic regression seam
- [x] Crop SVGs by rewriting their viewBox and render once at the final WebP resolution
- [x] Preserve SVG structure, transparency, CAD semantics, source immutability, and raster crop behavior
- [x] Verify crop output dimensions/display sizing, focused tests, production builds, and browser behavior
- **Status:** complete
### Phase 31: Canvas Performance and LeaferJS Evaluation
- [x] Build a repeatable browser performance baseline for pan, zoom, selection, and large CAD nodes
- [x] Isolate React/DOM reconciliation, SVG rasterization, overlays, persistence, and event-path costs
- [x] Map LeaferJS capabilities and integration constraints against the existing canvas domain model
- [x] Recommend the smallest migration boundary with measurable acceptance criteria
- **Status:** complete
### Phase 32: Leafer Renderer and Vector Texture Cache
- [ ] Extend the API/domain/storage contract with an optional vector render-preview URL
- [ ] Generate and upload transparent WebP previews while preserving original SVG/CAD source and semantics
- [ ] Add a LeaferJS visual renderer adapter for image and manual-frame nodes behind the existing canvas domain
- [ ] Move wheel/pan and node drag hot paths to imperative engine/DOM updates with commit-on-end state synchronization
- [ ] Preserve crop, export, selection, context menus, overlays, Agent Chat references, and persistence behavior
- [ ] Add focused regression/performance coverage and run full frontend/backend/build/browser verification
- **Status:** in_progress
## 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.
@@ -160,6 +226,8 @@ Phases 21-22
- 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.
- CAD source nodes are immutable during crop; every crop is a sibling asset positioned beside the source.
- CAD semantic context is bounded, persisted with the relevant source/crop, and sent as model context without becoming visible user-message copy.
## Errors Encountered
| Error | Attempt | Resolution |
@@ -197,3 +265,21 @@ Phases 21-22
| 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. |
| Local `mcp-zero` stdio initialization returned no JSON-RPC response | 1 | API validation succeeded; use the documented `goctl api go` fallback with the existing `go_zero` style. |
| TypeScript did not infer that a crop existed from the derived crop-bounds check | 1 | Guard the scope line with both `crop` and `cropBounds`; Go targeted tests already pass. |
| One combined patch contained a malformed hunk boundary | 1 | Reissued the same two-file edit with valid patch boundaries; no source change was lost. |
| Node's strip-types test runner could not resolve the new extensionless runtime import | 1 | Keep the shared semantic types as a stripped type-only import and define the stable metadata element ID locally in the worker module. |
| Synthetic text-only CAD fixture did not expose a library bounding box | 1 | Add a simple visible line to establish drawing bounds while keeping the text-encoding assertion focused. |
| A second planning/error patch initially repeated the malformed hunk separator | 1 | Removed the empty hunk marker and applied the intended fixture/error update cleanly. |
| Isolated Next dev preview was rejected by an existing repository-wide dev lock | 1 | Keep the updated backend on 8889 and run the verified production Next build on 5175 with its API proxy pointed at 8889. |
| zsh rejected the optional `frontend/.env*` inspection glob because no env file exists | 1 | Search the concrete Next/Vite config and source paths without an unmatched optional glob. |
| Combined toolbar patch expected the wrong `onChooseShapeKind` callback name | 1 | Re-read the exact `WorkspaceToolbar` prop block and apply the component and call-site changes against current code. |
| First browser wheel probe stayed at 100% because the stage listener was never attached | 1 | The initial effect ran while the project-loading view had no `.canvas-stage`; re-run listener binding when `project.id` mounts the canvas. |
| Playwright `run-code` rejected a bare `await page...` snippet despite the abbreviated skill example | 1 | Read command help and pass an `async (page) => { ... }` function as required by the installed CLI. |
| The first mocked route handler used `URL`, which is unavailable in the Playwright callback sandbox | 1 | Derive the pathname from `route.request().url()` with bounded string operations; the corrected route exposed the real canvas. |
| Initial combined Phase 30 test/findings patch assumed a generic `# Findings` heading | 1 | Re-read the file header and apply the regression test and findings as separate patches against the exact heading. |
| Exact-DWG performance fixture served the raw converter intermediate and Chromium rejected anonymous `</>` tags | 1 | Use the real browser upload path so `normalizeCadSvg` repairs and sanitizes the final SVG before measuring paint/interaction cost. |
| Playwright file-input locator matched both canvas upload and Agent Chat upload controls | 1 | Target the first canvas file input explicitly for the real DWG upload probe. |
| Playwright request context bypassed the page's mocked asset route and could not resolve `asset.local` | 1 | Fetch the captured normalized SVG inside the page context so the route handler supplies the bytes. |
| Combined performance findings patch matched entries in a different order than the current file | 1 | Re-read the exact section and apply the package/result additions against their real positions. |
| Direct CDN import used LeaferJS's package ESM build, whose bare `@leafer/core` specifier is not browser-resolvable | 1 | Load the official prebundled browser distribution for the throwaway benchmark. |