feat: add comprehensive architecture documentation and migration plan for refactor sessions

This commit is contained in:
2026-05-24 15:38:15 +02:00
parent 67f3e60953
commit c168c3b84a
5 changed files with 1334 additions and 0 deletions
+203
View File
@@ -0,0 +1,203 @@
# Architecture Rules
## Purpose
These rules define the constraints for future refactor sessions. They are intentionally practical: every rule should either protect behavior, reduce Electron risk, or keep the codebase easier to test.
## Core Rules
### Preserve The Product Model
- The app remains an Electron main-process wrapper around a local NodeCG runtime.
- NodeCG continues to be launched locally.
- Dashboards continue to load from approved local HTTP origins.
- The managed runtime continues to live under Electron `userData`.
- Runtime provisioning must preserve `cfg`, `db`, and `logs`.
### Avoid Unnecessary Architecture
- Do not add a renderer architecture unless a user-facing feature requires it.
- Do not add a preload script unless desktop APIs must be exposed to web content.
- Do not add IPC for organizational neatness.
- Do not introduce broad frameworks for lifecycle, dependency injection, logging, or configuration.
- Add an abstraction only when it removes real complexity or isolates a risky boundary.
### Keep Behavior Stable
- Preserve current behavior before reorganizing files.
- Write tests around existing behavior before extracting lifecycle code.
- Move files separately from behavior changes.
- Run typecheck, tests, and lint after meaningful refactor steps.
## TypeScript Rules
- Do not use `any`.
- Prefer explicit domain types at module boundaries.
- Validate unknown external input before narrowing.
- Keep pure functions pure.
- Prefer narrow interfaces over large service objects.
- Avoid global mutable state outside bootstrap or explicit controllers.
## Electron Rules
### BrowserWindow Defaults
Every application window must use secure defaults:
```text
nodeIntegration: false
contextIsolation: true
sandbox: true
webSecurity: true
```
Additional rules:
- Devtools availability must be controlled by environment or explicit config.
- Permission requests must be denied by default.
- New-window behavior must be blocked unless explicitly allowed.
- Navigation must be allowlisted.
- Remote content must not gain Node.js access.
### Preload Rules
Current decision:
- No preload script is required.
If a preload becomes necessary:
- Keep it minimal.
- Expose APIs only through `contextBridge`.
- Do not expose raw `ipcRenderer`.
- Do not include business logic in preload.
- Validate all payloads crossing the boundary.
- Treat preload as part of the security boundary, not as a convenience layer.
### Renderer Rules
Current decision:
- There is no custom renderer.
If a renderer is added later:
- It must not assume Node.js access.
- It must communicate through typed, validated IPC only.
- It must not own NodeCG process lifecycle.
- It must not bypass navigation or permission policies.
## IPC Rules
Current decision:
- No IPC layer is needed.
If IPC becomes necessary:
- Define all channel names in one module.
- Use explicit request and response types.
- Validate every payload at runtime.
- Use allowlisted handlers only.
- Never expose filesystem, process, shell, or update primitives directly.
- Never expose raw Electron APIs to web content.
- Keep handlers small and delegate to tested services.
- Return structured errors instead of throwing raw implementation details across IPC.
Example target shape:
```text
src/main/ipc/
channels.ts
register-handlers.ts
validators.ts
src/shared/ipc/
types.ts
```
Do not create this structure until IPC is genuinely needed.
## NodeCG Runtime Rules
- Keep NodeCG process ownership in the main process.
- Launch NodeCG with `ELECTRON_RUN_AS_NODE`.
- Validate the runtime installation before launching it.
- Wait for HTTP readiness before loading dashboards.
- Treat process stdout and stderr as diagnostic information only.
- Stop the full process tree on app shutdown.
- Keep platform process termination behind an adapter.
## Filesystem Rules
- Filesystem behavior must live behind domain modules.
- Runtime provisioning must never delete user-owned `cfg`, `db`, or `logs`.
- Downloads must stay inside safe temporary directories.
- Paths from config, remote metadata, or user-controlled sources must be validated before use.
- Avoid scattering path construction across unrelated modules.
## Update Rules
- Treat remote update metadata as untrusted.
- Validate update JSON with a runtime schema.
- Validate asset URLs before download.
- Prefer `https:` URLs for production updates.
- Fail closed when metadata is malformed.
- Download to a safe temporary file.
- Finalize downloads atomically.
- Keep fetch, validation, download, dialog, and install steps separate.
- Fix user-facing encoding issues when touching updater text.
- Do not execute downloaded installers unless validation has succeeded.
## Navigation Rules
- Allow only expected NodeCG dashboard origins.
- Prefer explicit URL parsing over string prefix checks.
- Block external navigation by default.
- Block unexpected new-window attempts.
- Keep navigation policy testable as pure logic where possible.
## Configuration Rules
- Parse configuration once.
- Keep configuration access centralized.
- Avoid reading environment variables throughout the codebase.
- Keep runtime defaults explicit.
- Ensure build scripts and app runtime agree on shared constants where appropriate.
## Process Rules
- Child process management must sit behind a small interface.
- Platform-specific kill behavior must be isolated.
- Windows process termination must validate numeric PIDs before command construction.
- Shutdown must be idempotent.
- Repeated quit events must not trigger duplicate process cleanup.
## Testing Rules
- Test pure path and URL functions directly.
- Test lifecycle states without launching real Electron where possible.
- Test updater validation with malformed metadata.
- Test navigation allow and block cases.
- Test process shutdown edge cases.
- Add integration-style coverage only where unit tests cannot represent the Electron behavior.
## Refactor Rules
- Do not refactor unrelated modules in the same change.
- Do not change formatting across the repository unless requested.
- Do not move folders and change behavior in the same step.
- Prefer small commits or small reviewable patches.
- Leave existing passing tests intact unless the product behavior intentionally changes.
## Security Baseline
The secure baseline is:
- No Node.js in web content.
- No preload unless needed.
- No IPC unless needed.
- Local navigation only.
- Deny permissions by default.
- Validate remote update data.
- Validate downloaded update assets.
- Keep process and filesystem access in main-process services only.