Delete src/services and wall off the way back

The directory is empty after the airtrail fold, so it goes. The ESLint rule is
the part that matters: the directory disappearing is not what keeps it gone,
because the way it grew was one file at a time, each one reasonable on its own.
Any import of a services/ path is an error now, with the message pointing at
the recipe in the module guide.

Proved rather than assumed: a probe file importing the old airtrail path fails
the rule, and the whole package still lints with zero errors.

Not changed: the 91 provenance comments in shared/, client/ and server/ that
name a services/*.ts file. They are statements about where a schema or a
service came from, and they stay true as history. Rewriting them all would put
91 files of noise over the change worth reviewing, and the paths they cite are
already gone from the tree, which is the honest signal that they are history.
This commit is contained in:
Maurice
2026-08-10 14:06:25 +02:00
committed by Maurice
parent 19f999329e
commit 4965281644
2 changed files with 39 additions and 11 deletions
+24
View File
@@ -82,6 +82,30 @@ export default tseslint.config(
],
},
},
{
// src/services/ is gone. It was the legacy layer this migration existed to
// empty, and the last of it (airtrail) folded into src/nest/integrations/.
//
// The wall matters more than the deletion: the directory disappearing is not
// what stops it coming back, because the way it grew was one file at a time,
// each one reasonable on its own. A new domain goes to src/nest/<domain>/
// with a service, a controller and a module.
files: ['src/**/*.ts', 'tests/**/*.ts'],
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['**/services/*', '**/services/**/*'],
message:
'src/services/ is deleted. New backend code goes to src/nest/<domain>/ (service + controller + module, registered in app.module.ts). See src/nest/README.md.',
},
],
},
],
},
},
{
// The plugin RPC decorator kit is written to stay extractable into its own
// package, so its dependencies are pinned to Nest plus the two host modules it
+15 -11
View File
@@ -79,17 +79,21 @@ remains as the platform underneath `@nestjs/platform-express`.
whole anonymous surface of the server, in one reviewable place. Stale entries
fail too.
`src/services/` is down to the `airtrail/` directory, which waits on the credential
decision. Backup has moved in: `services/backupService.ts` is now
`nest/backup/backup.impl.ts`, imported only by its own domain. It stays a module of
free functions rather than becoming methods, because the restore path closes and
reinitializes the core DB handle and rewriting that shape in the same step as the move
would make a regression there impossible to bisect — the db-lifecycle question is the
LAST step of that fold, not part of it. Note that the trip-access and
`canEdit` methods on the domain services are **not** dead weight waiting for a
guard: their callers are overwhelmingly the `*.mcp.ts` tools, which never pass
through an HTTP guard. In the five domains piloted for `TripAccessGuard`, 40 of
the 46 callers are MCP; only 6 sit in controllers.
**`src/services/` is gone.** It was the legacy layer this whole migration existed
to empty, and the last of it — `airtrail/`, 1305 lines of plain functions over the
better-sqlite3 singleton — folded into `integrations/`. An ESLint
`no-restricted-imports` rule now refuses any import of a `services/` path, because
the directory disappearing is not what keeps it gone: it grew one reasonable file
at a time. Backup made the same trip earlier: `services/backupService.ts` is
`nest/backup/backup.impl.ts`, imported only by its own domain, and it stays a
module of free functions rather than becoming methods because the restore path
closes and reinitializes the core DB handle — rewriting that shape in the same
step as the move would make a regression there impossible to bisect.
Note that the trip-access and `canEdit` methods on the domain services are **not**
dead weight waiting for a guard: their callers are overwhelmingly the `*.mcp.ts`
tools, which never pass through an HTTP guard. In the five domains piloted for
`TripAccessGuard`, 40 of the 46 callers are MCP; only 6 sit in controllers.
## Cross-cutting Foundation pieces