mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-15 19:32:21 +02:00
refactor(frontend): establish source ownership and architecture gates (#6701)
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
# Notes reference decomposition roadmap
|
||||
|
||||
Status: planning only. F1 changes no Notes implementation. Begin after the
|
||||
foundation has been reviewed and integrated into official `upstream/dev`.
|
||||
The reference program ends after Notes integration and the completed H handoff.
|
||||
F1 remains an entirely separate foundation-only PR. The complete Notes
|
||||
decomposition, regression tests, compatibility validation and final reference
|
||||
case study belong to one comprehensive draft PR targeting official `dev`.
|
||||
|
||||
## Verified current responsibility and compatibility map
|
||||
|
||||
Baseline: `8feb50e89468235cd3e0986da80edbd3acaf2c40`.
|
||||
The module is `static/js/notes.js`, about 5,470 lines, with browser identity
|
||||
`/static/js/notes.js?v=20260911notesselectioncancel1`. Preserve that identity across
|
||||
the app import, HTML, SW and lazy consumers until a separately reviewed migration
|
||||
changes the contract everywhere.
|
||||
|
||||
| Responsibility | Current evidence | Intended owner after its reviewed slice |
|
||||
| --- | --- | --- |
|
||||
| State and CRUD | `_notes`, selection/filter/editing/loading variables, `_undoStack`, `_fetchNotes`, `_saveNote`, `_patchNote`, `_archiveNoteById` | One application state owner and workflow operations; no second reminder/UI copy |
|
||||
| Dates and recurrence | `_normalizeRepeat`, `_advanceRecurring`, `_nthWeekdayOfMonth`, `_lastWeekdayOfMonth`, `_toLocalDatetimeStr`, repeat formatting helpers | Pure domain calculations with explicit clock inputs |
|
||||
| Network and persistence | Notes CRUD/reorder, upload, reminder firing, draft and reminder localStorage keys | Infrastructure adapters preserving request payloads, credentials and error contracts |
|
||||
| Reminders | `_checkReminders`, `_startReminderLoop`, `_initReminders`, notification permission/display and due/fired badge calculations | Application reminder workflow plus injected clock/storage/notification/API ports |
|
||||
| Draft autosave | `_draftKey`, `_collectFormDraft`, `_wireDraftAutosave`, `_applyDraftToNote`, `_commitOpenInPlaceEditor` | Draft workflow with editor view/persistence ports and serialized saves |
|
||||
| UI | `openPanel`, `closePanel`, `_renderNotes`, forms/cards/checklists, masonry, color/photo/drawing, mobile swipe/reorder | Scoped UI modules with explicit mount/dispose and application operations |
|
||||
| Agent context | `#notes-send-agent` handler, selected IDs, `odysseus:notes-context-selected` | Preserve event payload and synchronous acknowledgement; Chat owns attachment/session state |
|
||||
| Agent solve action | `_agentSolveNote`: default-chat lookup, session creation and chat stream | Separate existing workflow; do not conflate with selected-note attachment |
|
||||
| Compatibility coordinator | Default controller, named aliases, `window.notesModule`, delayed reminder startup | Stable legacy facade/composition bridge until consumers safely migrate |
|
||||
|
||||
The default API currently includes `openPanel`, `closePanel`, `togglePanel`,
|
||||
`isPanelOpen`, `openNote`, `newNote`, `openNotes`, `closeNotes`, `isNotesOpen` and
|
||||
`refreshDueBadge`. Named exports also include `dismissFiredReminderDot` and the
|
||||
panel/open aliases. Characterization must pin the complete actual namespace and
|
||||
default object separately, including identity of aliases and the window bridge.
|
||||
|
||||
Consumers include `static/app.js` sidebar/routes/badge polling,
|
||||
`chatStream.js` note tool updates, `chatRenderer.js` note links and
|
||||
`document.js` coordination. `static/index.html` and `static/sw.js` are entry/cache
|
||||
contracts. The shared UI, confetti, modal, color picker, drag, tiling, docking,
|
||||
z-order and Escape helpers are direct dependencies. Those legacy dependencies
|
||||
remain in the coordinator until their ownership is reviewed, rather than moving
|
||||
all UI coupling into domain modules.
|
||||
|
||||
Import-time behavior includes window origin/storage reads and
|
||||
`setTimeout(_initReminders, 3000)`. The successful bootstrap loads Notes and starts
|
||||
a 30-second reminder interval. App composition separately refreshes the badge
|
||||
every five minutes. Panel/editing listeners, draft timers, highlight animations,
|
||||
ResizeObserver and drawing/touch handlers have shorter scopes. Record them before
|
||||
extraction; do not stop background reminders merely because a panel closes.
|
||||
Listener cleanup concerns require characterization, not an unrelated fix hidden
|
||||
inside an extraction.
|
||||
|
||||
Persistence includes `odysseus-notes-view`, label collapse and hint preferences,
|
||||
fired/glowed/pending/active reminder markers, dismissed timestamp, and
|
||||
`odysseus-note-draft-<id>` including `__new__`. Current direct APIs include Notes
|
||||
CRUD/reorder/fire-reminder and upload, plus default-chat/session/chat-stream for
|
||||
the existing solve action. Backend owner isolation and permission handling stay
|
||||
authoritative and are outside this frontend decomposition's implementation scope.
|
||||
|
||||
## PR #6495 contract that every relevant slice preserves
|
||||
|
||||
Notes sends `odysseus:notes-context-selected` with `{ noteIds, accepted: false }`.
|
||||
Chat's synchronous listener accepts only a valid active or pending chat, updates
|
||||
session/pending selection, sets `accepted`, and updates the context indicator.
|
||||
Notes clears select mode only after acceptance. Session lifecycle events
|
||||
`odysseus:session-changed` carry session/materialization information. Chat appends
|
||||
selected IDs as `selected_note_ids` when sending; server parsing validates IDs,
|
||||
filters by owner and treats the resulting prompt context as untrusted.
|
||||
|
||||
Keep selection transfer to a materialized chat, reset on a new chat, rejection
|
||||
when no chat/model can accept it, aliases and indicator behavior. Do not broaden
|
||||
frontend selections into permissions or bypass the backend. See
|
||||
`tests/selectedNotesContext.test.mjs`, `tests/test_selected_notes_context.py`,
|
||||
`static/js/chat.js` selected-context listeners and send payload, and
|
||||
`static/js/sessions.js` lifecycle event producers.
|
||||
|
||||
## One Notes branch, worktree and draft PR
|
||||
|
||||
After F1 integration and authorization to begin Notes, create one worktree and
|
||||
branch, suggested name `refactor/notes-reference-decomposition`, from the latest
|
||||
official `upstream/dev`. N0 through N6 are sequential internal engineering
|
||||
checkpoints on that same branch. No independent GitHub PR is required for a
|
||||
checkpoint or a UI substage. Maintain one draft PR targeting official `dev`, with
|
||||
checkpoint evidence linked from its description. Keep it a draft until the
|
||||
complete decomposition passes all acceptance gates below.
|
||||
|
||||
| Checkpoint | Responsibility | Deliverable and exit evidence |
|
||||
| --- | --- | --- |
|
||||
| N0 | Characterization | Public API/consumer, responsibility, state, lifecycle and network map; deterministic behavior tests; PR-overlap refresh; no extraction |
|
||||
| N1 | Recurrence domain | Only pure date/recurrence rules to `features/notes/domain/recurrence.js`; preserve old wrapper call contracts, time-read position and returned strings; new offline dependency registered |
|
||||
| N2 | Infrastructure | HTTP and storage adapters with exact request/error/key contracts; retain state ownership and backend authorization |
|
||||
| N3 | Application | Single state owner and CRUD/optimistic/undo workflows; UI/reminders call operations; no competing arrays or stores |
|
||||
| N4 | Reminders | Timer/notification/reminder orchestration through explicit ports; characterize startup, catch-up, deduplication, badge and background behavior |
|
||||
| N5 | UI substages | Bounded card/panel, editor/draft, checklist, drawing and mobile reviews within the same PR; explicit listener/observer disposal and the same application operations |
|
||||
| N6 | Compatibility and reference case study | Reduce coordinator; full API/consumer/lifecycle/offline comparison; retain legacy facade unless removal is proven safe; complete the final reference case study in the same PR |
|
||||
|
||||
Do not create the Notes worktree, branch or PR during F1. N5 remains several
|
||||
bounded internal reviews rather than a second monolith move. Every checkpoint
|
||||
and UI substage must have its own focused tests, review evidence, lessons,
|
||||
exceptions and a rollback plan. Record the validated revision or reproducible
|
||||
patch/snapshot, prior known-good checkpoint, exact test commands/results and
|
||||
how to restore its matching source/output/facade/precache set while preserving
|
||||
unrelated work. Checkpoint commits require the applicable maintainer authority;
|
||||
no checkpoint or commit is created by this planning document.
|
||||
|
||||
Advance only after the current checkpoint's required checks and review findings
|
||||
are resolved. A failed checkpoint returns to its prior validated state or receives
|
||||
a bounded correction on the same branch; it does not require a separate PR.
|
||||
If upstream changes require updating the baseline, update the same Notes branch,
|
||||
record that revision and rerun affected checkpoint and compatibility gates.
|
||||
|
||||
## Complete Notes PR acceptance gates
|
||||
|
||||
Before marking the single draft PR ready for review:
|
||||
|
||||
- Complete N0 through N6, including all N5 substages, with their tests, review
|
||||
receipts and reproducible checkpoint/rollback evidence.
|
||||
- Pass the required full Notes regression and compatibility checks on the final
|
||||
combined revision, including PR #6495 selection/context behavior, public APIs,
|
||||
module identities, single state ownership, storage formats, timers and teardown.
|
||||
- Pass source/output parity, LF attribute, architecture, import graph and exact
|
||||
offline manifest gates; verify current bootstrap/lazy behavior and relevant
|
||||
native/packaging contracts. Record platform limits and distinguish preserved
|
||||
offline module behavior from separately certified root offline reload.
|
||||
- Resolve required gate failures and review findings; document unrelated existing
|
||||
failures or coverage gaps explicitly rather than bypassing required checks.
|
||||
- Include the final reference case study in this PR: actual before/after APIs,
|
||||
dependency/state/lifecycle maps, stage decisions and lessons, validation recipes,
|
||||
temporary exceptions, known debt and tested rollback/compatibility procedures.
|
||||
|
||||
These are readiness gates for the complete PR, not separate stage merges.
|
||||
The receiving maintainer may choose smaller independent PRs for future frontend
|
||||
features; this one-PR delivery decision applies to the Notes reference program.
|
||||
|
||||
## N0 and N1 characterization requirements
|
||||
|
||||
Pin recurrence normalization for legacy bare repeat values and explicit values;
|
||||
none/unknown/malformed input; daily/weekly/monthly/yearly advancement; month ends,
|
||||
leap years, nth/last weekdays including absent fifth occurrences; overdue catch-up
|
||||
and the 5,000-step guard; future anchors; local serialization and preserved hours;
|
||||
DST gaps/overlaps under explicit time zones. `_advanceRecurring` currently reads
|
||||
`Date.now()` after its first step. Inject a clock without changing that ordering.
|
||||
Record the existing behavior of invalid dates rather than inventing improvements.
|
||||
|
||||
Characterize request error handling, optimistic rollback/undo, archive/delete,
|
||||
selection/filter/reset, ordering, uploads and notification permission errors.
|
||||
For drafts, preserve synchronous local backup before the 500 ms persistence
|
||||
timer, intentional empty text, checklist type fallback, serialized writes,
|
||||
failure recovery and refusal to clear a newer draft when an older save finishes.
|
||||
|
||||
Use stub clocks/ports and temporary storage for unit behavior; browser tests for
|
||||
public namespace evaluation, DOM lifecycle, selected context and actual offline
|
||||
loading. Run real modules through their output paths. Do not rewrite source-range
|
||||
tests wholesale; migrate each only with its responsible slice and equivalent
|
||||
behavioral assertions. Existing source-sensitive Notes autosave tests currently
|
||||
read `notes.js`, so extraction has an explicit test-maintenance dependency.
|
||||
|
||||
Before a slice, refresh #6585/#6647/#6652 backend behavior and #6470/#6695 shared
|
||||
UI/platform overlaps from the [assessment](assessment.md). Existing fixes may
|
||||
change characterization inputs, but this program does not merge or silently
|
||||
reimplement those PRs. The independent root-SW fix #6227 is required before a
|
||||
claim of full SPA offline reload readiness.
|
||||
|
||||
## H completion and stopping rule
|
||||
|
||||
The final reference case study is completed inside the Notes PR before it becomes
|
||||
ready for review. After that PR is integrated, finalize H with the integrated
|
||||
revision and checkpoint-to-integration receipts, outstanding dependencies and
|
||||
the recipient's independent reproduction. Have the receiving maintainer
|
||||
reproduce setup and validation independently and record that receipt. Transfer
|
||||
future feature ownership explicitly. Do not automatically begin Calendar,
|
||||
Documents, Email, Chat, Skills or Settings; the initiating architect continues
|
||||
with separately approved non-frontend monolith work.
|
||||
Reference in New Issue
Block a user