mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
docs: tick permissions and auditLog in migrate.md and refresh the migration graph
This commit is contained in:
@@ -28,7 +28,8 @@ mount to Nest and leaves the sibling trip routes (days, places, ...) on Express.
|
||||
- **Phase 2 (trip sub-domains):** vacay (addon), packing, todo.
|
||||
- **DI-native services (legacy `src/services/*` deleted):** tags, categories,
|
||||
todo, packing, day-notes, trip-invite, assignments, share, settings, files,
|
||||
collab, vacay, reservations, day — see the migration recipe below.
|
||||
collab, vacay, reservations, day, permissions, audit — see the migration
|
||||
recipe below.
|
||||
|
||||
## Cross-cutting Foundation pieces
|
||||
|
||||
@@ -155,11 +156,38 @@ service, `TripsService` + the assignments/reservations MCP controllers
|
||||
converted to injection, and a 6-export `days.bridge.ts` for the legacy
|
||||
`tripService` and the still-legacy transit + transports registrars; the DTO
|
||||
ratchet for its 4 day + 2 accommodation grandfathered body contracts landed
|
||||
as a sibling commit).
|
||||
as a sibling commit);
|
||||
permissions followed (the first Wave-2 **cross-cutting** migration and the
|
||||
first greenfield module in the series — no prior wrapper, controller, MCP
|
||||
surface or DTO of its own: a new `nest/permissions/` whose
|
||||
`PermissionsService` is injected by 16 domain services, the airtrail-import
|
||||
controller and `PluginHostDepsFactory` (its 16th constructor dep) in one move,
|
||||
plus a 5-function `permissions.bridge.ts` for `mcp/tools/_shared.ts` — one
|
||||
repoint covering every `hasTripPermission` call site — and the four legacy
|
||||
consumers adminService/authService/backupService/collectionsService; the
|
||||
permissions **cache stays module-scoped** in `permissions.service.ts` on
|
||||
purpose, so the bridge instance and the container singleton share one cache
|
||||
and backup-restore's bridge-side `invalidatePermissionsCache()` flushes what
|
||||
request handlers serve; the domain e2e suites swapped their path mocks for a
|
||||
`vi.spyOn(app.get(PermissionsService), 'checkPermission')` instance spy);
|
||||
auditLog followed (the other Wave-2 half, split into five files: the
|
||||
injectable `AuditService` (`writeAudit` over `DatabaseService`), the pure
|
||||
`client-ip.ts` (files.constants precedent — the four getClientIp-only
|
||||
controllers stay plain imports), the deliberately side-effectful plain
|
||||
`audit-log.logger.ts` — frozen-at-import `LOG_LEVEL` and the import-time
|
||||
`data/logs` mkdir are a documented parity exception to the no-side-effects
|
||||
rule because `index.ts` lazy-requires it pre-container and tests/setup.ts
|
||||
sets the level pre-import — plus `audit.module.ts` and a full-surface
|
||||
`audit.bridge.ts` for `mcp/index.ts`, `mcp/oauthProvider.ts` and the legacy
|
||||
airtrail/immich/oauth services, while log*-only consumers (index.ts's lazy
|
||||
require strings, scheduler, globalMiddleware, notifications) point at the
|
||||
logger directly; 8 controllers + `PluginRuntimeService` inject `AuditService`,
|
||||
and the domain e2e suites dropped the audit mock entirely — writeAudit runs
|
||||
for real against an `audit_log` table in their temp DBs).
|
||||
Repeat these steps per
|
||||
service (next up: permissions + auditLog — the Wave-2 cross-cutting pair the
|
||||
dependency-honest order in `migration-graph.md` promotes now that dayService
|
||||
is folded; then the exchangeRateService fold → budgetService). This is a
|
||||
service (next up: the exchangeRateService fold → budgetService per the
|
||||
dependency-honest order in `migration-graph.md`, now that the Wave-2
|
||||
permissions + auditLog pair is folded). This is a
|
||||
**pure relocation** — byte-identical
|
||||
SQL, statuses, bodies, and error strings. The plugin RPC host is **no longer a
|
||||
bridge consumer**: since Option A of `src/nest/plugins/DI-MIGRATION.md` it
|
||||
|
||||
@@ -19,7 +19,7 @@ The plugin runtime has three layers. Only the third is "un-Nest".
|
||||
|---|---|---|---|
|
||||
| Sandbox / transport | `supervisor/plugin-supervisor.ts`, `runtime/plugin-host-entry.ts`, `protocol/envelope.ts` | Forked child per plugin, IPC envelopes, permission tables, actor resolution, rate limiting, RSS policing | Intentionally not — this is the security boundary |
|
||||
| Enforcement | `host/rpc-host.ts` (~1330 lines) | `PluginRpcHost`: builds a per-plugin method map at spawn — a handler is registered **only if the plugin holds the unlocking permission** (registration = authorization). Depends only on the `HostDeps` interface | Neutral — decoupled by design |
|
||||
| **Wiring** | `host/plugin-host-deps.factory.ts` (was `create-rpc-host.ts`) | Fills the ~130-member `HostDeps` object. Since Option A: an `@Injectable() PluginHostDepsFactory` with the DI-native domain services (`BudgetService`, `ReservationsService`, `TagsService`, `CategoriesService`, `TodoService`, `PluginOAuthService`) constructor-injected, fourteen domains as of 2026-07; legacy `services/*` domains stay plain function imports until their own migration. Raw `db`/`broadcast` also stay until injectable equivalents exist | **Yes (Option A)** — drains further per §3 |
|
||||
| **Wiring** | `host/plugin-host-deps.factory.ts` (was `create-rpc-host.ts`) | Fills the ~130-member `HostDeps` object. Since Option A: an `@Injectable() PluginHostDepsFactory` with the DI-native domain services (`BudgetService`, `ReservationsService`, `TagsService`, `CategoriesService`, `TodoService`, `PluginOAuthService`) constructor-injected, fifteen domains as of 2026-07 (permissions joined with the Wave-2 pair); legacy `services/*` domains stay plain function imports until their own migration. Raw `db`/`broadcast` also stay until injectable equivalents exist | **Yes (Option A)** — drains further per §3 |
|
||||
| Host state | `host/plugin-host-state.ts` | Deliberately module-level (NOT a provider): the per-plugin data-DB map (`getPluginDataDb`/`closePluginDataDb`) and daily broker budgets (`budgetFor`/`pluginBudgetUsage`). Must be one shared instance across host recreations, and is read by `PluginsService`, which the factory imports from — folding it into the injectable would create a provider cycle | Intentionally not |
|
||||
|
||||
Key fact that made Option A cheap: the wiring is **called from inside a Nest
|
||||
@@ -111,8 +111,11 @@ collabService swapped in 2026-07 — its seven imported symbols became the
|
||||
injected `CollabService`, completing Wave 3; vacayService swapped in 2026-07 —
|
||||
its four imported symbols became the injected `VacayService`; dayService
|
||||
swapped in 2026-07 — its eleven imported symbols (the heaviest single import)
|
||||
became the injected `DaysService`; the remaining factory imports are all
|
||||
Wave-4+ domains: trips, places, journeys, atlas, collections).
|
||||
became the injected `DaysService`; permissions swapped in 2026-07 with the
|
||||
Wave-2 pair — its `checkPermission` import became the injected
|
||||
`PermissionsService` (the auditLog half never touched the factory: the plugin
|
||||
host's audit trail is the separate `plugin-audit.ts`); the remaining factory
|
||||
imports are all Wave-4+ domains: trips, places, journeys, atlas, collections).
|
||||
|
||||
### Test impact (as landed)
|
||||
|
||||
@@ -120,7 +123,7 @@ Wave-4+ domains: trips, places, journeys, atlas, collections).
|
||||
`PluginRpcHost` directly with hand-built `HostDeps`).
|
||||
- `tests/unit/plugins/plugin-host-deps.factory.test.ts` (was
|
||||
`create-rpc-host.test.ts`) — the six DI-domain path mocks became constructor
|
||||
stubs (fourteen stubs as of the 2026-07 day migration); the ~23
|
||||
stubs (fifteen stubs as of the 2026-07 permissions migration); the ~22
|
||||
legacy-service path mocks remain; a file-local shim keeps the
|
||||
historical `createRealRpcHost(id, granted)` call sites and supplies a default
|
||||
no-op router.
|
||||
|
||||
Reference in New Issue
Block a user