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,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.
|
||||
Reference in New Issue
Block a user