mirror of
https://github.com/Pandipipas/scoreko-electron-dev.git
synced 2026-06-06 05:32:06 +00:00
feat: add comprehensive architecture documentation and migration plan for refactor sessions
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
# Migration Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Refactor the Electron main-process architecture without changing product behavior. The plan is sequential and should be followed in order so future sessions can make progress without reinterpreting the architecture.
|
||||
|
||||
## Migration Principles
|
||||
|
||||
- Preserve behavior before moving structure.
|
||||
- Add tests around risky lifecycle behavior before refactoring it.
|
||||
- Keep the NodeCG runtime model intact.
|
||||
- Keep Electron minimal.
|
||||
- Avoid introducing IPC, preload, or renderer code unless required by a concrete feature.
|
||||
- Prefer small pure functions for paths, URLs, update metadata, asset selection, and navigation policy.
|
||||
- Rewrite only the degraded areas: updater, lifecycle orchestration, and platform process shutdown.
|
||||
|
||||
## Phase 1: Freeze Existing Behavior
|
||||
|
||||
Purpose:
|
||||
|
||||
Protect current startup, shutdown, provisioning, navigation, and update behavior before extracting modules.
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add tests for first-run runtime provisioning and relaunch behavior.
|
||||
- Add tests for loading window and main window ordering.
|
||||
- Add tests for update scheduling behavior.
|
||||
- Add tests for shutdown when NodeCG is running.
|
||||
- Add tests for shutdown when NodeCG is already stopped.
|
||||
- Add tests for double quit or repeated shutdown calls.
|
||||
- Add tests for macOS-style activation after windows are closed.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Existing tests continue to pass.
|
||||
- New tests describe current behavior, not the desired future behavior.
|
||||
- No folder reorganization occurs in this phase.
|
||||
|
||||
## Phase 2: Extract Pure Path And URL Logic
|
||||
|
||||
Purpose:
|
||||
|
||||
Remove deterministic calculations from `main.ts` while keeping Electron side effects in the entrypoint.
|
||||
|
||||
Target files:
|
||||
|
||||
```text
|
||||
src/main/app/paths.ts
|
||||
src/main/config/runtime-config.ts
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Extract `userData` path calculation.
|
||||
- Extract managed runtime path calculation.
|
||||
- Extract NodeCG dashboard URL construction.
|
||||
- Extract runtime configuration parsing.
|
||||
- Keep Electron `app.setPath`, `app.setName`, and lock handling in bootstrap code.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Extracted functions are pure.
|
||||
- Tests cover path and URL edge cases.
|
||||
- No Electron app object is required to test the extracted logic.
|
||||
|
||||
## Phase 3: Introduce ApplicationController
|
||||
|
||||
Purpose:
|
||||
|
||||
Make lifecycle explicit without redesigning the app.
|
||||
|
||||
Target file:
|
||||
|
||||
```text
|
||||
src/main/app/application-controller.ts
|
||||
```
|
||||
|
||||
Required states:
|
||||
|
||||
```text
|
||||
idle
|
||||
preparing
|
||||
starting
|
||||
ready
|
||||
stopping
|
||||
stopped
|
||||
failed
|
||||
```
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- Prepare runtime.
|
||||
- Start NodeCG.
|
||||
- Wait for readiness.
|
||||
- Create or reuse windows through a window service.
|
||||
- Load dashboards only after NodeCG readiness.
|
||||
- Schedule update checks.
|
||||
- Handle activation safely.
|
||||
- Handle shutdown idempotently.
|
||||
|
||||
Non-responsibilities:
|
||||
|
||||
- Direct process-kill command construction.
|
||||
- Direct update metadata parsing.
|
||||
- Direct Electron `BrowserWindow` option construction.
|
||||
- Business logic inside preload or renderer code.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- `main.ts` becomes a thin bootstrap.
|
||||
- Activation uses readiness-aware startup behavior.
|
||||
- Shutdown is idempotent.
|
||||
- Tests cover state transitions and failure paths.
|
||||
|
||||
## Phase 4: Extract Shutdown Service
|
||||
|
||||
Purpose:
|
||||
|
||||
Make shutdown behavior predictable and easy to test.
|
||||
|
||||
Target files:
|
||||
|
||||
```text
|
||||
src/main/app/shutdown-service.ts
|
||||
src/main/nodecg/nodecg-process-service.ts
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Centralize app shutdown sequencing.
|
||||
- Ensure NodeCG is stopped before app exit completes.
|
||||
- Handle repeated shutdown requests.
|
||||
- Handle process already exited.
|
||||
- Preserve current quit behavior.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Repeated quit calls do not duplicate process termination.
|
||||
- Tests cover `before-quit`, process exit before shutdown, and shutdown failure logging.
|
||||
|
||||
## Phase 5: Rewrite Updater In Small Modules
|
||||
|
||||
Purpose:
|
||||
|
||||
Replace the fragile updater internals while preserving user-visible behavior.
|
||||
|
||||
Target files:
|
||||
|
||||
```text
|
||||
src/main/updates/update-service.ts
|
||||
src/main/updates/update-config.ts
|
||||
src/main/updates/update-download.ts
|
||||
src/main/updates/update-schema.ts
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Define a runtime schema for update metadata.
|
||||
- Validate remote JSON before using it.
|
||||
- Validate update asset URLs.
|
||||
- Restrict protocols to `https:` unless an explicit local development mode exists.
|
||||
- Select platform assets through pure functions.
|
||||
- Download to a safe temporary path.
|
||||
- Finalize downloads atomically.
|
||||
- Keep dialog behavior outside fetch and download helpers.
|
||||
- Correct Spanish encoding issues.
|
||||
- Add tests for malformed JSON, missing assets, invalid URLs, failed downloads, and cancelled dialogs.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Invalid update metadata fails closed.
|
||||
- Downloaded files cannot escape the intended temporary directory.
|
||||
- User-facing strings render correctly.
|
||||
- Existing update behavior is preserved where valid metadata is provided.
|
||||
|
||||
## Phase 6: Isolate Platform Process Termination
|
||||
|
||||
Purpose:
|
||||
|
||||
Keep OS-specific process-kill details outside NodeCG lifecycle logic.
|
||||
|
||||
Target file:
|
||||
|
||||
```text
|
||||
src/main/nodecg/platform-process-killer.ts
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Implement a small interface for terminating process trees.
|
||||
- Provide Windows and POSIX implementations.
|
||||
- Validate that Windows PIDs are numeric before command construction.
|
||||
- Avoid spreading platform conditionals through the process manager.
|
||||
- Test command selection and error handling.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- `taskkill` construction is isolated.
|
||||
- POSIX process termination is isolated.
|
||||
- Process manager tests no longer need to know platform command details.
|
||||
|
||||
## Phase 7: Harden Electron Window Policy
|
||||
|
||||
Purpose:
|
||||
|
||||
Make Electron browser security explicit and testable.
|
||||
|
||||
Target files:
|
||||
|
||||
```text
|
||||
src/main/windows/window-service.ts
|
||||
src/main/windows/navigation-policy.ts
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Explicitly set `webSecurity: true`.
|
||||
- Keep `nodeIntegration: false`.
|
||||
- Keep `contextIsolation: true`.
|
||||
- Keep `sandbox: true`.
|
||||
- Add a permission request handler that denies by default.
|
||||
- Define devtools policy by environment.
|
||||
- Keep navigation allowlist limited to approved local NodeCG origins.
|
||||
- Prevent unexpected new-window behavior.
|
||||
- Review CSP options for NodeCG-hosted content where feasible.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- BrowserWindow options are covered by tests.
|
||||
- Permission requests are denied unless explicitly allowed.
|
||||
- Navigation policy has tests for allowed and blocked origins.
|
||||
|
||||
## Phase 8: Normalize Scripts And Shared Constants
|
||||
|
||||
Purpose:
|
||||
|
||||
Reduce packaging fragility without changing the build system.
|
||||
|
||||
Targets:
|
||||
|
||||
```text
|
||||
scripts/
|
||||
src/main/config/
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Make repository layout assumptions explicit.
|
||||
- Validate required paths before build work starts.
|
||||
- Share package/runtime constants where reasonable.
|
||||
- Improve error messages for missing parent project or missing NodeCG runtime.
|
||||
- Keep scripts simple `.mjs` utilities.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- CI failures explain missing external dependencies clearly.
|
||||
- Local build behavior remains unchanged.
|
||||
- No new framework is introduced.
|
||||
|
||||
## Phase 9: Reorganize Folders Last
|
||||
|
||||
Purpose:
|
||||
|
||||
Move files only after behavior is protected and new ownership is clear.
|
||||
|
||||
Target structure:
|
||||
|
||||
```text
|
||||
src/main/
|
||||
app/
|
||||
config/
|
||||
windows/
|
||||
nodecg/
|
||||
updates/
|
||||
logging/
|
||||
src/shared/
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
- Move files into target folders after tests pass.
|
||||
- Update imports mechanically.
|
||||
- Avoid changing logic during moves.
|
||||
- Run typecheck, tests, and lint after each group of moves.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- File moves are behavior-neutral.
|
||||
- Test output remains unchanged.
|
||||
- Imports reflect the target architecture.
|
||||
|
||||
## Required Verification Per Phase
|
||||
|
||||
Run the relevant subset while iterating, then run all checks before closing a phase:
|
||||
|
||||
```text
|
||||
npm run typecheck
|
||||
npm test
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## Stop Conditions
|
||||
|
||||
Stop and reassess if:
|
||||
|
||||
- A change requires adding IPC without a product need.
|
||||
- A refactor changes the NodeCG runtime model.
|
||||
- Update validation requires a product or release-server decision.
|
||||
- CSP changes break NodeCG dashboards.
|
||||
- CI requires external repository layout decisions outside this package.
|
||||
Reference in New Issue
Block a user