name: fantasia-two-level-architecture description: >- Migrates Fantasia Archive features to two-level functions + managers layout: pure scripts/functions/, *_manager.ts wiring (underscore suffix, e.g. dialogFoo_manager.ts), thin Vue SFCs. Use when refactoring features, fixing fa-two-level ESLint violations, or adding new UI.
Two-level functions + managers
Migrate one feature
- Add
scripts/functions/— pure logic;import typefromapp/types/**only; inject deps from manager - Add
scripts/<feature>_manager.ts— wiring only;create…factories; no top-level functions/classes (fa-two-level/manager-wiring-only) - Thin
.vue: props, child imports, oneuse…from manager - Delete legacy
scripts/*.tsbesidefunctions/ - Update
_tests; addfunctions/_tests yarn lint:eslinton feature, thenyarn testbatch:verify
Fix common ESLint messages
| Message | Fix |
|---|---|
| functions/ value imports | Move to *_manager.ts, pass as arg |
| Legacy script beside functions/ | Merge into functions/ + manager or delete |
| Vue script import allowlist | Expose via manager return |
| Import functions/ only from manager | Manager (tests excepted) |
| Re-export shim | Delete; import real manager/functions |
| manager-wiring-only | Bodies in functions/ or *Wiring.ts |
| manager-wiring-only (class) | Class in non-manager sibling |
| manager-wiring-only (arrow const) | Factory arg object or *Wiring.ts |
| functions-only-type-imports | Keep orchestration in scripts/ sibling — not functions/ |
Vue imports functions/ |
Use domain barrel (faDragDrop_manager, dom_manager) when present |
*Wiring.ts vs *_manager.ts
*_manager.ts— factory +export constonly.*Wiring.ts—export function+document/window/fs; examples:faInterfaceTextDirectionApplyWiring.ts,faDragDropDocumentDragCursorWiring.ts,faProjectFilePathHardeningWiring.ts.MainLayout:attachWindowKeydownListener/detachWindowKeydownListenerinjected frommainLayout_manager.tsintocreateMainLayout.
Domain barrels (src/scripts/<domain>/)
faDragDrop_manager.ts, dom_manager.ts — public API for Vue; re-export functions/ + wiring.
Pinia stores
src/stores/S_*.ts = manager. Pure logic in src/stores/functions/. Bridge scripts may import stores/functions/.
- Return
readonly(ref)for external session state; mutate in actions only. S_FaActiveProject:openGenerationmutex; stale open →'superseded'(T_faActiveProjectOpenFlowOutcome).
Audit checklist (all *_manager.ts)
- Grep — no
export function, modulefunction,class, top-levelconst x = () => yarn lint:eslint—fa-two-level/manager-wiring-only- Factory arg property arrows OK
- Classes +
sessionDepsin*Session.ts,*Wiring.ts,*Bound.ts - Electron Node
fsbind: factory infunctions/,export constin*Wiring.ts(e.g.faProjectFilePathHardeningWiring.ts)
Shared types (types/)
Level-1 functions/**: import type from app/types/** only. Managers export values; types from app/types/.... See types-folder.mdc.
Electron
Same under src-electron/mainScripts/<area>/: functions/, <area>_manager.ts, *Wiring.ts, IPC registrars import domain *_manager.ts. Keep contentBridgeAPIs/ thin.