Skip to content

Commit a647f4f

Browse files
committed
docs: update spatial parity checklist and plan with refactoring progress
1 parent 27fad31 commit a647f4f

11 files changed

Lines changed: 801 additions & 435 deletions

File tree

docs/SPATIAL_PARITY_CHECKLIST.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
| 2.1 | Container enabled toggle | `note-collab.ts` `container.enabled` | `note-model.ts:container.enabled` | **Done** | `note-model.test.ts` |
5656
| 2.2 | Spatial container (free child positioning) | `DisplayNote/Container/Spatial.vue` | `DisplayNote.vue:container children` | **Done** ||
5757
| 2.3 | Horizontal container (children in a row) | `note-collab.ts` `container.horizontal` | `DisplayNote.vue:flex-row` | **Done** ||
58-
| 2.4 | Drag child out to detach | `DisplayNote/Container/Detach.ts` | `useSpatialPage.ts:moveNoteOutOfContainer` | **Done** ||
59-
| 2.5 | Drag note into container to attach | `DisplayNote/Container/Attach.ts` | `SpatialPageView.vue:overlap heuristic` | **Done** ||
58+
| 2.4 | Drag child out to detach | `DisplayNote/Container/Detach.ts` | `useNoteDrag.ts:onNoteDragEnd` + `useSpatialPage.ts:moveNoteOutOfContainer` | **Done** ||
59+
| 2.5 | Drag note into container to attach | `DisplayNote/Container/Attach.ts` | `useNoteDrag.ts:overlap heuristic` | **Done** ||
6060
| 2.6 | Container wrap children toggle | `note-collab.ts` `container.wrapChildren` | `note-model.ts:container.wrapChildren` | **Done** | `note-model.test.ts` |
6161
| 2.7 | Container stretch children toggle | `note-collab.ts` `container.stretchChildren` | `note-model.ts:container.stretchChildren` | **Done** | `note-model.test.ts` |
6262
| 2.8 | Container force color inheritance toggle | `note-collab.ts` `container.forceColorInheritance` | `note-model.ts:container.forceColorInheritance` | **Done** | `note-model.test.ts` |
@@ -66,8 +66,8 @@
6666

6767
| # | Feature | Legacy reference | New file(s) | Status | Test file |
6868
|---|---------|------------------|-------------|--------|-----------|
69-
| 3.1 | Create arrow (drag from note handle to target) | `DisplayArrow/CreateArrow.ts` | `SpatialPageView.vue:onArrowDragStart/End` | **Done** ||
70-
| 3.2 | Delete arrow (Delete key) | `DisplayArrow/DeleteArrow.ts` | `SpatialPageView.vue:onKeyDown` | **Done** ||
69+
| 3.1 | Create arrow (drag from note handle to target) | `DisplayArrow/CreateArrow.ts` | `useArrowDrag.ts` | **Done** ||
70+
| 3.2 | Delete arrow (Delete key) | `DisplayArrow/DeleteArrow.ts` | `useSpatialKeyboard.ts:onKeyDown` | **Done** ||
7171
| 3.3 | Curve body (quadratic bezier) | `DisplayArrow/CurveArrow.vue` | `DisplayArrow.vue:pathD` | **Done** ||
7272
| 3.4 | Line body (straight line) | `DisplayArrow/LineArrow.vue` | `DisplayArrow.vue:pathD` + `arrow-geometry.ts` | **Done** | `arrow-geometry.test.ts` |
7373
| 3.5 | Arrow heads (open chevron SVG markers) | `DisplayArrow/OpenHead.vue` | `DisplayArrow.vue:marker` | **Done** ||
@@ -76,7 +76,7 @@
7676
| 3.8 | Body style toggle (`solid`/etc.) | `arrow.ts` `bodyStyle` | `arrow-model.ts:bodyStyle` | **Done** | `arrow-model.test.ts` |
7777
| 3.9 | Arrow label (Tiptap on `Y.XmlFragment`) | `DisplayArrow/ArrowLabel.vue` | `DisplayArrow.vue:NoteTiptapEditor` | **Done** ||
7878
| 3.10 | Hitbox (thick invisible stroke) | `DisplayArrow/ArrowHitbox.vue` | `DisplayArrow.vue:transparent stroke` | **Done** ||
79-
| 3.11 | Drag-to-reconnect | `DisplayArrow/Reconnect.ts` | `SpatialPageView.vue:onReconnectPointerMove/Up` | **Done** ||
79+
| 3.11 | Drag-to-reconnect | `DisplayArrow/Reconnect.ts` | `useArrowReconnect.ts` | **Done** ||
8080
| 3.12 | Arrow color matching note logic | `DisplayArrow/ArrowColor.ts` | `DisplayArrow.vue:arrowColor` | **Partial** ||
8181
| 3.13 | Arrow read-only state | `arrow.ts` `readOnly` | `arrow-model.ts:readOnly` | **Done** | `arrow-model.test.ts` |
8282
| 3.14 | Arrow timestamps (`createdAt`, `editedAt`) | `arrow.ts` | `arrow-model.ts:createdAt, editedAt` | **Done** | `arrow-model.test.ts` |
@@ -106,7 +106,7 @@
106106
|---|---------|------------------|-------------|--------|-----------|
107107
| 5.1 | Click to select note | `selection/select.ts` | `DisplayNote.vue:onPointerDown` | **Done** ||
108108
| 5.2 | Ctrl+click to toggle selection | `selection/select.ts` | `DisplayNote.vue:onPointerDown` | **Done** ||
109-
| 5.3 | Box selection (drag on empty canvas) | `selection/boxSelect.ts` | `SpatialPageView.vue:box selection` | **Done** | |
109+
| 5.3 | Box selection (drag on empty canvas) | `selection/boxSelect.ts` | `useBoxSelection.ts` | **Done** | `useBoxSelection.test.ts` |
110110
| 5.4 | Select all (`Ctrl+A`) | `selection/selectAll.ts` | `SpatialPageView.vue:onKeyDown` | **Done** ||
111111
| 5.5 | Active element tracking | `selection/active.ts` | `useSpatialSelection.ts:activeId` | **Partial** | `selection.test.ts` |
112112
| 5.6 | Active region tracking | `selection/activeRegion.ts` | `useSpatialSelection.ts:activeRegionId` | **Partial** ||
@@ -276,7 +276,7 @@ Every field from legacy `INoteCollab` and `IArrowCollab` is present in the new Y
276276

277277
- [x] Checklist contains ≥ 60 rows. (Current count: **82+ rows**)
278278
- [x] Schema diff table covers every legacy `INoteCollab` and `IArrowCollab` field.
279-
- [ ] Every "Done" item has a passing automated test. **VIOLATED.** ~35+ UI/interaction rows marked "Done" still have "—" in the Test file column. Progress since last evaluation: `arrow-geometry.test.ts` (5 tests), `useSpatialEditing.test.ts` (4 tests) added. Remaining gaps: `DisplayNote.vue` (basic render tests only), `DisplayArrow.vue` (no component tests), `SpatialPageView.vue` (no component/integration tests), drag/resize interaction, box selection, arrow creation/reconnection, sidebar/toolbar integration.
279+
- [ ] Every "Done" item has a passing automated test. **VIOLATED.** ~30+ UI/interaction rows marked "Done" still have "—" in the Test file column. Progress since last evaluation: `note-geometry.test.ts` (8 tests), `useBoxSelection.test.ts` (6 tests), `arrow-geometry.test.ts` (5 tests), `useSpatialEditing.test.ts` (4 tests) added. Remaining gaps: `DisplayNote.vue` (basic render tests only), `DisplayArrow.vue` (no component tests), `SpatialPageView.vue` (no component/integration tests), drag/resize interaction, arrow creation/reconnection, sidebar/toolbar integration.
280280
- [ ] Phase 6 is not declared done until ≥ 80% of rows are **Done**. **NOT MET.** Strict enforcement of the test rule would drop the true "Done" count well below 80%.
281281

282282
---

docs/restart-plan/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# DeepNotes Restart Plan — Index
22

3-
> **Last updated:** 2026-05-31 (Phase 6 in progress. `useSpatialEditing`, `bringToTop`, line-body arrow geometry, and `useSpatialKeyboard` extracted. See `phase-6-spatial-polish.md` and `SPATIAL_PARITY_CHECKLIST.md` for details. Phase 9 pending.)
3+
> **Last updated:** 2026-05-31 (Phase 6 in progress. `SpatialPageView.vue` god-component refactored — box selection, arrow drag, arrow reconnect, note drag extracted into dedicated composables. `note-geometry.ts` and `useBoxSelection.test.ts` added. See `phase-6-spatial-polish.md` and `SPATIAL_PARITY_CHECKLIST.md` for details. Phase 9 pending.)
44
> **This document replaces `docs/RESTART_PLAN.md`.** If a prior statement conflicts with this one, this version wins.
55
66
---
@@ -90,14 +90,14 @@ A criterion is **not met** until the verification command or check passes in CI.
9090
- **No `PageElem` abstraction.** Legacy notes and arrows inherit from `PageElem`, sharing selected/active/editing/visible/region state. New code treats them as completely separate types.
9191
- **`editing` state management implemented.** `useSpatialEditing.ts` tracks which note/arrow is being edited. Escape stops editing; canvas click stops editing; Delete/Backspace is suppressed while editing to avoid deleting selected elements.
9292
- **Container rendering lacks legacy depth.** `stretchChildren`, `wrapChildren`, `originOffset`, and overflow detection are in the model but not enforced in rendering. Spatial vs non-spatial container distinction is not fully implemented.
93-
- **`SpatialPageView.vue` partially refactored.** Keyboard shortcuts (~150 lines) extracted to `useSpatialKeyboard.ts`. Still a large component; further extraction needed for drag, resize, box-select, and arrow-reconnection logic.
93+
- **`SpatialPageView.vue` partially refactored.** Keyboard shortcuts extracted to `useSpatialKeyboard.ts`. Box selection, arrow drag, arrow reconnect, and note drag extracted to dedicated composables (`useBoxSelection.ts`, `useArrowDrag.ts`, `useArrowReconnect.ts`, `useNoteDrag.ts`). Note geometry utilities extracted to `note-geometry.ts`. Component reduced from ~740 lines to ~365 lines. Remaining inline logic: context menu handlers, canvas double-click, fit-to-screen.
9494
- **Selection partially improved.** `bringToTop` zIndex bump on selection is now implemented. Formatting integration across selected editors, active element/region keyboard navigation, and `selectAll` including descendant arrows remain missing.
9595
- **Missing floating UI:** back/forward nav, screenshot, user avatars on canvas.
9696

9797
### Other gaps
9898

9999
- **Realtime notification toast** — only `/notifications` page exists, no badge/toast.
100-
- **Composable size**`useGroupMembersDetail.ts` (103 lines), `usePageCollabEditor.ts` (238 lines), and `useSpatialPage.ts` (195 lines) are all under the 300-line limit. Container logic extracted to `container-ops.ts`. **However, `SpatialPageView.vue` is a 1,070-line god component that violates the spirit of this criterion.**
100+
- **Composable size**`useGroupMembersDetail.ts` (103 lines), `usePageCollabEditor.ts` (238 lines), and `useSpatialPage.ts` (195 lines) are all under the 300-line limit. Container logic extracted to `container-ops.ts`. `SpatialPageView.vue` script section reduced from ~740 lines to ~365 lines after extracting `useSpatialKeyboard.ts`, `useBoxSelection.ts`, `useArrowDrag.ts`, `useArrowReconnect.ts`, `useNoteDrag.ts`, and `note-geometry.ts`.
101101
- **Auth: `rememberDevice` UI missing in login**`LoginView.vue` has no "Remember this device" checkbox for 2FA login; users are re-prompted every time. API schema already supports it.
102102
- **Auth: no distributed locking** — Legacy used Redlock (`user-lock:${userId}`) around password change, email change, and 2FA mutations. New code relies on DB transactions only.
103103

docs/restart-plan/phase-6-spatial-polish.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Phase 6: Spatial canvas polish
22

33
> **Prerequisites:** Phase 5 done.
4-
> **Status:** In progress (2026-05-31 — `useSpatialEditing`, `bringToTop`, line-body arrow geometry, and `useSpatialKeyboard` extracted since last evaluation. Multiple "Done" items were over-reported; see notes below.)
4+
> **Status:** In progress (2026-05-31 — `SpatialPageView.vue` refactored. Box selection, arrow drag, arrow reconnect, and note drag extracted into dedicated composables. `note-geometry.ts` and `useBoxSelection.test.ts` added. `useSpatialEditing`, `bringToTop`, line-body arrow geometry, and `useSpatialKeyboard` were extracted in prior work.)
55
66
---
77

@@ -17,7 +17,7 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
1717
| Item | Status | Notes |
1818
|------|--------|-------|
1919
| Multi-select (ctrl/cmd + click) | **Done** | `SpatialPageView.vue` handles toggle via Ctrl+click |
20-
| Box selection (drag on empty canvas) | **Done** | Threshold-based drag-to-box-select implemented |
20+
| Box selection (drag on empty canvas) | **Done** | Extracted to `useBoxSelection.ts`; threshold-based drag-to-box-select with world-space intersection. Tested in `useBoxSelection.test.ts`. |
2121
| Select all (`Ctrl+A`) | **Done** | `onKeyDown` in `SpatialPageView.vue` |
2222
| Active element / active region tracking | **Partial** | `useSpatialSelection` has `activeId` and `activeRegionId` ref but no real active-region UI or keyboard navigation |
2323
| `bringToTop` on selection | **Done** | `useSpatialSelection` bumps selected note `zIndex` above other selected notes |
@@ -29,8 +29,8 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
2929
| Note can contain child notes | **Done** | `container.enabled` and `container.children` wired in Yjs |
3030
| Spatial container (free child positioning) | **Done** | Children rendered with world offset inside parent |
3131
| Horizontal container (children in a row) | **Done** | `container.horizontal` flag + `flex-row` class in `DisplayNote.vue` |
32-
| Drag child out to detach | **Done** | `onNoteDragEnd` + `moveNoteOutOfContainer` |
33-
| Drag note into container to attach | **Done** | Overlap-area heuristic in `SpatialPageView.vue` |
32+
| Drag child out to detach | **Done** | `useNoteDrag.ts:onNoteDragEnd` + `moveNoteOutOfContainer` |
33+
| Drag note into container to attach | **Done** | Overlap-area heuristic in `useNoteDrag.ts` |
3434

3535
### 3. Clipboard
3636
| Item | Status | Notes |
@@ -87,7 +87,7 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
8787
| Arrow heads (`OpenHead.vue`) | **Done** | SVG `<marker>` chevron heads; `sourceHead`/`targetHead` supported |
8888
| Arrow label (editable `Y.XmlFragment`) | **Done** | `NoteTiptapEditor` at midpoint. Proper collaborative rich-text editing on `Y.XmlFragment` |
8989
| Hitbox (thick invisible stroke) | **Done** | `stroke="transparent" stroke-width="20"` pointer-events-auto hitbox |
90-
| Drag-to-reconnect | **Done** | Connection zones + `onReconnectPointerMove/Up` in `SpatialPageView.vue` wired |
90+
| Drag-to-reconnect | **Done** | Extracted to `useArrowReconnect.ts`. Connection zones + world-space note detection on pointer move. |
9191
| Arrow source/target anchor positioning | **Done** | `DisplayArrow.vue` geometry uses `sourceAnchor`/`targetAnchor` when provided; line body falls back to rectangle-edge intersection |
9292
| Color matching note color logic | **Partial** | Same hardcoded 10-color map used, but `inherit` logic may not cascade correctly for arrows |
9393

@@ -110,7 +110,7 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
110110

111111
## Verification
112112

113-
- [ ] Each deliverable has a test (unit, component, or integration). **Partially improved.** New tests: `arrow-geometry.test.ts` (5 tests), `useSpatialEditing.test.ts` (4 tests). Major gaps remain: `DisplayNote.vue` (only basic render tests), `DisplayArrow.vue` (no component tests), `SpatialPageView.vue` (no component/integration tests), drag/resize interaction tests, box selection tests, arrow creation/reconnection tests, sidebar/toolbar integration tests.
113+
- [ ] Each deliverable has a test (unit, component, or integration). **Partially improved.** New tests: `note-geometry.test.ts` (8 tests), `useBoxSelection.test.ts` (6 tests), `arrow-geometry.test.ts` (5 tests), `useSpatialEditing.test.ts` (4 tests). Major gaps remain: `DisplayNote.vue` (only basic render tests), `DisplayArrow.vue` (no component tests), `SpatialPageView.vue` (no component/integration tests), drag/resize interaction tests, arrow creation/reconnection tests, sidebar/toolbar integration tests.
114114
- [ ] Phase 1 checklist is >80% marked done. **NOT MET.** Strict enforcement of the checklist's "Done = implemented + passing test" rule drops the true completion rate well below 80%.
115115

116116
---
@@ -127,7 +127,7 @@ Achieve parity with the legacy `/pages/:pageId` immersive spatial canvas experie
127127
- [x] `MainToolbar`, `LeftSidebar`, `RightSidebar`, and `TableContextMenu` are implemented as standalone shadcn components and visible on `/pages/:pageId`.
128128
- [x] Sidebar panels (`RecentPages`, `FavoritePages`) display real data from API.
129129
- [x] Arrow geometry reads actual note heights instead of hardcoding `80px`.
130-
- [ ] `SpatialPageView.vue` is refactored to avoid god-component anti-pattern. Keyboard shortcuts extracted to `useSpatialKeyboard.ts`; drag, resize, box-select, and arrow-reconnection logic still inline.
130+
- [ ] `SpatialPageView.vue` is refactored to avoid god-component anti-pattern. **Partial.** Keyboard shortcuts extracted to `useSpatialKeyboard.ts`; box selection extracted to `useBoxSelection.ts`; arrow drag extracted to `useArrowDrag.ts`; arrow reconnect extracted to `useArrowReconnect.ts`; note drag extracted to `useNoteDrag.ts`; note geometry extracted to `note-geometry.ts`. Component reduced from ~740 to ~365 lines. Remaining inline: context menu handlers, fit-to-screen, canvas double-click.
131131
- [x] Selection implements `bringToTop`. Formatting integration and active element/region navigation remain missing.
132132
- [ ] Container rendering enforces `stretchChildren`, `wrapChildren`, and spatial vs non-spatial layout modes.
133133
- [ ] Manual QA session with 3+ users finds no blocking usability issues.

0 commit comments

Comments
 (0)