feat(housekeeping): dispatch canonical domain routes
This commit is contained in:
1 parent
2970dff563
commit
e5c230ba35
13 files changed
+680
-82
No files matched your search
@@ -0,0 +1,140 @@
|
||||
# Task 9 report — canonical route dispatch
|
||||
|
||||
## Status
|
||||
|
||||
- DONE: matcher, registry collision guard, empty handler aggregate, preview root routing, and catch-all dispatch are implemented.
|
||||
- Base verified before edits: `2970dff56378cf5259fd125794bf0d89bec25b25` on `codex/housekeeping-complete`.
|
||||
- Commit message: `feat(housekeeping): dispatch canonical domain routes`.
|
||||
- `.remember/` remained untouched and untracked.
|
||||
- No pull, push, PR/MR update, deployment, database operation, Task 10 work, or worktree was performed.
|
||||
|
||||
## TDD evidence
|
||||
|
||||
### RED — tests written before production
|
||||
|
||||
Exact command:
|
||||
|
||||
```text
|
||||
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
|
||||
```
|
||||
|
||||
Observed exit 1:
|
||||
|
||||
```text
|
||||
Test Files 4 failed (4)
|
||||
Tests 1 failed | 14 passed (15)
|
||||
|
||||
Cannot find module './match-route'
|
||||
Cannot find module './route-handlers'
|
||||
Cannot find package '@/app/ase-next/[domain]/[[...segments]]/page'
|
||||
|
||||
registry > rejects duplicate dynamic route shapes regardless of parameter name
|
||||
AssertionError: expected [Function] to throw an error
|
||||
```
|
||||
|
||||
This proved the three missing production boundaries and the existing registry's acceptance of equivalent `:id` / `:username` route shapes.
|
||||
|
||||
### First targeted GREEN
|
||||
|
||||
The same exact command after the minimum implementation exited 0:
|
||||
|
||||
```text
|
||||
Test Files 4 passed (4)
|
||||
Tests 94 passed (94)
|
||||
```
|
||||
|
||||
An intermediate run had 92/94 passing because two import-boundary fixtures still used the old route file's relative depth. The fixture imports were moved one directory higher for the new catch-all location; the forbidden-module assertions were unchanged.
|
||||
|
||||
### Full-suite contract correction
|
||||
|
||||
The first full housekeeping run correctly exposed one obsolete Task 1 expectation:
|
||||
|
||||
```text
|
||||
Test Files 1 failed | 37 passed (38)
|
||||
Tests 1 failed | 348 passed (349)
|
||||
Expected NEXT_REDIRECT:/ase-next/operations
|
||||
Received NEXT_NOT_FOUND
|
||||
```
|
||||
|
||||
`server-capability-context.test.ts` was updated to the Task 9 ruling: with the real registered route set still empty, `/ase-next` calls `notFound()` and must not redirect to an empty Operations placeholder. Its request-scoped context isolation assertions remain intact.
|
||||
|
||||
## Implemented behavior
|
||||
|
||||
- `matchHousekeepingRoute` compares decoded path segments without constructing a regular expression from route text.
|
||||
- Static routes win over same-depth dynamic routes; dynamic and nested parameters are returned in a frozen readonly record.
|
||||
- Unknown, cross-domain, malformed, repeated-separator, trailing-separator, query/fragment, invalid-percent, encoded-separator, dot-segment, and backslash paths fail closed.
|
||||
- Registry construction rejects duplicate dynamic shapes even when parameter names differ.
|
||||
- `HousekeepingPageInput` is exactly the readonly `{ context, match }` pair.
|
||||
- The global route-handler aggregate is empty and its test proves one-to-one equality with the currently empty manifest route set; no placeholder handlers were added.
|
||||
- `/ase-next` searches registered routes in manifest order, requires both domain and route capability, redirects to the first permitted route, and calls `notFound()` when none exists.
|
||||
- `/ase-next/<domain>/<segments>` derives the domain's canonical `/ase` path, matches it, finds the exact handler, reacquires the cached request-scoped context, rechecks domain and route capability, and invokes the handler with that same context and match.
|
||||
- Unknown routes fail before context loading; inaccessible matched routes load one context and never invoke a handler.
|
||||
|
||||
## Verification evidence
|
||||
|
||||
Targeted routing/registry/handler/preview tests:
|
||||
|
||||
```text
|
||||
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/routing/match-route.test.ts src/features/housekeeping/foundation/registry.test.ts src/features/housekeeping/route-handlers.test.ts src/features/housekeeping/foundation/preview-route-contract.test.ts
|
||||
Test Files 4 passed (4)
|
||||
Tests 94 passed (94)
|
||||
```
|
||||
|
||||
Directly affected context contract:
|
||||
|
||||
```text
|
||||
pnpm exec vitest run --coverage.enabled=false src/features/housekeeping/foundation/server-capability-context.test.ts
|
||||
Test Files 1 passed (1)
|
||||
Tests 2 passed (2)
|
||||
```
|
||||
|
||||
Full housekeeping suite:
|
||||
|
||||
```text
|
||||
pnpm test:housekeeping
|
||||
Test Files 38 passed (38)
|
||||
Tests 349 passed (349)
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```text
|
||||
pnpm typecheck
|
||||
$ tsc --noEmit
|
||||
exit 0
|
||||
```
|
||||
|
||||
The only output note was the existing engine warning: local Node `26.7.0` is below the package request `>=26.8.1 <27`.
|
||||
|
||||
Targeted Biome with formatting disabled:
|
||||
|
||||
```text
|
||||
pnpm exec biome check --formatter-enabled=false <11 changed Task 9 source/test files>
|
||||
Checked 11 files in 47ms. No fixes applied.
|
||||
```
|
||||
|
||||
`git diff --check` exited 0 before staging. Cached-diff and committed-tree checks are run as the final staging/commit gates.
|
||||
|
||||
## Exact Task 9 files
|
||||
|
||||
```text
|
||||
src/app/ase-next/[domain]/[[...segments]]/page.tsx
|
||||
src/app/ase-next/[domain]/layout.tsx
|
||||
src/app/ase-next/[domain]/page.tsx (deleted)
|
||||
src/app/ase-next/page.tsx
|
||||
src/features/housekeeping/foundation/preview-route-contract.test.ts
|
||||
src/features/housekeeping/foundation/registry.test.ts
|
||||
src/features/housekeeping/foundation/registry.ts
|
||||
src/features/housekeeping/foundation/routing/match-route.test.ts
|
||||
src/features/housekeeping/foundation/routing/match-route.ts
|
||||
src/features/housekeeping/foundation/server-capability-context.test.ts
|
||||
src/features/housekeeping/route-handlers.test.ts
|
||||
src/features/housekeeping/route-handlers.ts
|
||||
.superpowers/sdd/2026-08-26-housekeeping-completion/task-9-report.md
|
||||
```
|
||||
|
||||
## Self-review and tooling
|
||||
|
||||
- Mutation check: dynamic-name normalization removal, regex-style static matching, static-priority removal, decoded-separator acceptance, domain mismatch acceptance, skipped route ACL, context reload inside the handler, missing handler lookup, placeholder handler addition, and empty-domain redirect each break a focused test.
|
||||
- The catch-all route imports only housekeeping foundation/manifests/handlers and retains the existing forbidden database/auth/permissions/actions/legacy-page boundary audit.
|
||||
- `apply_patch` created all new files, but the Windows sandbox helper repeatedly failed to read existing files with `apply deny-read ACLs`. Existing-file edits therefore used controller-approved exact-anchor/full-file fallbacks only after resolving absolute paths and validating every target under `E:\Users\simol\Desktop\EpicNext-cms`.
|
||||
Reference in new issue
Block a user