docs(housekeeping): track functional parity gaps and execution
This commit is contained in:
1 parent
d0190bc11f
commit
9b91880e33
2 files changed
+152
No files matched your search
@@ -0,0 +1,57 @@
|
|||||||
|
# Housekeeping functional parity audit
|
||||||
|
|
||||||
|
Baseline: 8e54cdbc. CI aggregate success verified remotely. This is an open-work inventory, not a completion report.
|
||||||
|
|
||||||
|
## Hotel / Studio / Operations
|
||||||
|
|
||||||
|
| Priority | Confirmed gap | Evidence | Execution |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| P1 | Legacy radio editor can write unrelated site setting keys | src/actions/admin-radio-extra.ts saveRadioSetting | Functional parity Task 2 |
|
||||||
|
| P1 | Legacy room items allow arbitrary fields and wrong-room update/delete | src/actions/rooms.ts | Task 1 |
|
||||||
|
| P1 | Studio final persistence/readback failure reclassifies successful runner as failed | hotel/commands/studio-commands.ts createStudioOperationService | Task 3 |
|
||||||
|
| P1 | Hotel radio writes omit runtime cache invalidation | hotel/services/mutations-production.ts | Task 2 |
|
||||||
|
| P1 | Studio furniture import omits selected source and finalization | studio-commands.ts furni branch vs src/app/api/admin/import/furni/route.ts | Open orchestration task |
|
||||||
|
| P2 | Studio command reason is discarded | studio-commands.ts / hotel/queries/studio.ts | Task 3 |
|
||||||
|
| P2 | Production Studio get/list only reads process memory | hotel/queries/studio.ts | Open durable repository task |
|
||||||
|
| P2 | Clone ignores false catalog/items refresh delivery | studio-commands.ts consolidate | Task 3 |
|
||||||
|
| P2 | Repair ignores nested Nitro failure and error events | studio-commands.ts repair-icons branch | Task 3 |
|
||||||
|
| P2 | Hotel HAVING filters only final UNION branch | hotel/queries/hotel-production.ts | Open query task |
|
||||||
|
|
||||||
|
Also requiring explicit parity review: one-time radio API-key delivery; catalog audit/repair bridge versus a history-only screen; radio CRUD legacy convergence.
|
||||||
|
|
||||||
|
Controller confirmed shared site-settings freshness defect: an expired memory cache is returned before attempting a database refresh whenever Redis has no value. Cache invalidation also resets inFlight without protecting against stale in-flight work repopulating the cache. Include regression coverage in the settings task.
|
||||||
|
|
||||||
|
Operations replacing legacy dashboard metrics is intentional in migration/operations.ts, not itself missing parity.
|
||||||
|
|
||||||
|
Audit coverage: Hotel mutations, Studio service/runner/repository, Hotel query/search/inbox/widgets, legacy room/radio actions, furniture import API; Operations composition and migration contract. Auditors performed read-only code comparison, not service-backed acceptance.
|
||||||
|
|
||||||
|
## Other domains
|
||||||
|
|
||||||
|
| Domain | Gap | Execution |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| People | Ban/moderation/CFH bypass target hierarchy or existence; CFH accepts unrelated user | Task 4 |
|
||||||
|
| People | Alert/trade-lock bypass established target guard | Task 4 |
|
||||||
|
| People | Commands lose audit reason | Task 5 |
|
||||||
|
| People | Missing IP/word-filter delete reports success | Task 5 |
|
||||||
|
| People | Missing canonical user creation and individual badge grant/removal | Task 7 |
|
||||||
|
| People | User detail omits legacy account/relations/investigation fields | Task 12 |
|
||||||
|
| System | Privileged configuration/external operations lack canonical audit | Task 6 |
|
||||||
|
| System | Multi-key settings/maintenance writes are non-atomic | Task 6 |
|
||||||
|
| System | Unknown permission slugs silently revoke grants; audit outside transaction | Task 6 |
|
||||||
|
| System | Rank update accepts missing target and empty/unknown fields | Task 6 |
|
||||||
|
| System | Logs fixed to flattened latest 50, no investigation filters/details | Task 12 |
|
||||||
|
| Content | Theme Builder operations absent despite verified migration row | Task 9 |
|
||||||
|
| Content | CRUD synthetic snapshots/false success for absent records | Task 8 |
|
||||||
|
| Content | Prefix settings silently skip invalid keys | Task 8 |
|
||||||
|
| Content | Edit query payloads incomplete across banners/prefixes/help/writeables/email | Task 8 |
|
||||||
|
| Economy | Missing file-upload soundtrack responsibility | Task 11 |
|
||||||
|
| Economy | Catalog bulk-create catches row failures and audits success | Task 10 |
|
||||||
|
| Economy | Badge grant race and inconsistent code bounds | Task 7 |
|
||||||
|
| Economy | Voucher update omits editable code | Task 10 |
|
||||||
|
| Economy | Marketplace/transactions filtering and user identity projections incomplete | Task 12 |
|
||||||
|
| Economy | Expired active subscriptions included | Task 12 |
|
||||||
|
| Economy | Calendar/rare-values editable/grouped projections incomplete | Task 12 |
|
||||||
|
|
||||||
|
Read-only audit coverage included all declared commands and production query routing for Content/Economy, and People/System commands, services, query models and affected legacy entrypoints. Findings are mapped to implementation work; each needs focused regression evidence. Proposed badge slot uniqueness is NOT accepted without model verification: slot semantics may allow multiple unequipped badges.
|
||||||
|
|
||||||
|
No domain is declared complete by this document. UI-only omissions remain separately open even when their backend operation already exists.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# Housekeeping functional parity execution
|
||||||
|
|
||||||
|
Spec: `docs/superpowers/specs/2026-08-30-housekeeping-stepwise-rebuild-design.md`, with current conversation authorizing continuous execution and backend-first completion.
|
||||||
|
|
||||||
|
## Global constraints
|
||||||
|
|
||||||
|
- Canonical checkout and existing `codex/housekeeping-rebuild-stepwise`; no worktrees.
|
||||||
|
- Preserve `/admin`, preview isolation, unrelated local files and existing useful workflows.
|
||||||
|
- Keep PR 53 draft, update English and Dutch after verified pushes. No deployment or merge.
|
||||||
|
- Backend completion requires operation-level evidence, not migration registration. UI and live acceptance remain separate gates.
|
||||||
|
- No new dependency or distributed-delivery guarantee without evidence and user discussion.
|
||||||
|
|
||||||
|
## Task 1: Converge legacy room mutations on the Hotel service
|
||||||
|
|
||||||
|
Files: `src/actions/rooms.ts`, focused legacy-action regression tests; Hotel runtime/service helpers only where necessary to preserve the existing forms.
|
||||||
|
|
||||||
|
Replace direct room and furniture writes with the existing authenticated Hotel mutation service/production adapter, preserving exported action signatures and revalidation routes. Cover update, delete, bulk delete, room update/delete, and runtime actions. Preserve existing webhook notifications, but do not let notification failure reclassify a committed mutation as failed. Use correlation IDs and legacy context; do not manufacture an operator reason. Return actionable failure through the existing server-action convention. Check the caller hook before choosing the result adapter.
|
||||||
|
|
||||||
|
The effective contract must reject unknown fields, invalid IDs, invalid runtime actions and mutations targeting an item outside the supplied room. Bulk selection must be bounded, deduplicated and atomic: absent/wrong-room requested items must not silently count as deleted. Database changes and audit share the existing transaction. No success audit/revalidation on failed database work. Do not claim emulator reload after a database-only edit; correct misleading success copy in the affected edit dialog if necessary.
|
||||||
|
|
||||||
|
Use TDD against real action/service/runtime behavior with transport mocks, not an entirely mocked service: demonstrate the legacy bypass failing first, then test valid floor/wall edits, forbidden owner/type fields, wrong-room single/bulk targets, denied permission, audit failure rollback, and runtime false delivery. Run focused tests, typecheck, scoped Biome and full suite once before commit. Commit exact files, no push (controller reviews first). Report RED/GREEN commands and results.
|
||||||
|
|
||||||
|
## Task 2: Scope and refresh radio settings consistently
|
||||||
|
|
||||||
|
Files: legacy radio setting actions, Hotel production adapter, site-settings service, focused tests.
|
||||||
|
|
||||||
|
Route legacy single/bulk radio setting updates through scoped validated Hotel operations. Only radio_/auto_dj_ keys, bounded batches and values; preserve forms and useful metadata. Reject invalid settings before writes. Invalidate siteSettings only after successful committed radio.settings.save-one, radio.settings.save-many and radio.points.save, never after rollback. Handle post-commit invalidation failure as partial completion, not a retryable failed write. TDD covers forged unrelated keys, invalid bulk entries, valid settings, transactional audit and commit/invalidation order. Preserve other radio CRUD for its own parity pass.
|
||||||
|
|
||||||
|
Repair shared cache freshness: expired memory must attempt database refresh when Redis misses; retain stale data only on actual dependency failure. An in-flight read started before reload must not repopulate the current cache or overwrite Redis with stale settings. Preserve single-flight behavior and build-time stable reads. Test expiration without Redis, database failure fallback, reload during an in-flight read and Redis invalidation failures. Do not install a cache dependency.
|
||||||
|
|
||||||
|
## Task 3: Preserve Studio reasons and truthful completion
|
||||||
|
|
||||||
|
Files: Hotel Studio commands, repository contracts and focused tests.
|
||||||
|
|
||||||
|
Propagate normalized optional reason from command to invocation, intent and every audit event. Separate runner failure from final event persistence/readback failure: completed external work must return its known output with partial audit availability, never trigger a false failure event. Preserve genuine runner/cancellation failures and durable intent before side effects. False catalog/items refresh returns must produce warning/partial. Aggregate icon/Nitro repair child failures and setup error events. TDD each failure mode and passing case. Durable repository and full import orchestration are subsequent tasks, not solved by this task.
|
||||||
|
|
||||||
|
## Task 4: Unify moderation target authority
|
||||||
|
|
||||||
|
Files: People moderation/user mutation services and tests; shared target-authority helper if needed.
|
||||||
|
|
||||||
|
Apply the existing peer/higher-rank protection and superadmin exception consistently to ban.create, user.alert, user.trade-lock, user-targeted moderation actions and CFH sanctions. A missing target returns NOT_FOUND before mutation or RCON. CFH loads/locks the ticket, binds the sanction to its reported user (reject caller mismatch), validates actionable state and applies the same target guard. Database target checks belong in the transaction; external actions must be guarded immediately before dispatch. Respect existing rank lock ordering and do not invent a new bypass permission.
|
||||||
|
|
||||||
|
Ban IP/machine/super types must use the actual target identifiers rather than empty strings; validate required identifiers using existing canonical ban semantics. Preserve account bans and existing result/legacy signatures. Test lower/peer/higher/superadmin, absent target, forged CFH user, closed ticket, missing ban identifiers, denied calls with no write/transport, and successful audited calls. Existing rank coordinator is already delivered and must not regress.
|
||||||
|
|
||||||
|
Include active quick user-targeted actions in src/actions/moderation.ts and legacy user alert/trade-lock entrypoints: converge them on the guarded service so they cannot bypass the fix. Preserve action response and permission contracts. Enforce the CFH sanction action allowlist in the service itself, not only the command schema; CFH cannot smuggle broadcast/room-kick input through a direct invocation. Existing ticket assign/state/close operations are a separate transactional parity follow-up.
|
||||||
|
|
||||||
|
## Task 5: Preserve People reasons and honest record existence
|
||||||
|
|
||||||
|
Propagate normalized reason across all People command/invocation/context paths into intent/success/failure/partial canonical audit entries, including delegated moderation/ticket executors. Do not synthesize a reason for legacy calls. Lock/read actual rows for IP/word-filter deletes; absent rows yield NOT_FOUND without reload or success audit. Test reason transport through real services and each outcome, plus absent and repeated deletes.
|
||||||
|
|
||||||
|
## Task 6: Make System configuration and access mutations auditable and atomic
|
||||||
|
|
||||||
|
System settings, emulator configuration, alerts, maintenance and command-center execution must carry actor/reason/correlation and use intent/outcome audits appropriate to DB versus external work. DB changes and audit share a transaction; multi-key writes are all-or-nothing. Cache/RCON failures after commit are partial, not false failed writes. Validate required reason at sensitive command boundaries while preserving working legacy forms via adapters.
|
||||||
|
|
||||||
|
Permission-set updates must resolve every normalized/deduplicated slug before replacement; unknown slugs reject atomically, empty list remains explicit revoke-all only under its existing confirmation contract. Rank updates accept only known editable fields, reject empty/unknown input and missing ranks, lock real rows, preserve rank coordinator behavior, and audit changes transactionally. TDD invalid slug/no writes, nth-write rollback, missing rank, empty/unknown fields, real before/after, audit failures and external partial outcomes.
|
||||||
|
|
||||||
|
## Task 7: Restore missing People account and badge operations
|
||||||
|
|
||||||
|
Add canonical typed create-user, individual badge grant and removal operations required by migration/people.ts. Reuse reliable legacy user creation/password validation/defaults and badge services; avoid parallel implementations. Create user/settings/currency rows transactionally with audit, honor authority and unique identity constraints. Serialize badge grants on a stable user row and preserve emulator slot semantics (do not assume all badge slots must be unique). Restore compatible badge-code bounds after checking database/emulator contract; reject overlength instead of truncating. Test missing/duplicate users, authorization, rollback, duplicate badge, grant/remove external failures, code boundaries and legacy delegation.
|
||||||
|
|
||||||
|
## Task 8: Repair Content CRUD state and complete editable projections
|
||||||
|
|
||||||
|
Tags, prefixes, help, writeables and email mutations must read/lock actual records, return NOT_FOUND for absent update/delete and capture real before/after audit snapshots. Prefix settings reject unknown keys and empty batches atomically. Expose typed editable query payloads for writeables, banners, prefixes/settings/blacklist, help and email; preserve untouched fields in round trips. Test nonexistent/concurrent stale targets, audit rollback, mixed-invalid settings and full field projection.
|
||||||
|
|
||||||
|
## Task 9: Restore Theme Builder backend parity
|
||||||
|
|
||||||
|
Compare migration/content.ts Theme Builder responsibilities with active legacy source. Implement all retained scope/value create/update/delete, duplicate and reset operations plus typed scope/tree/value queries. Reuse existing Theme Builder persistence and validation; transactionally audit real snapshots. Test complete lifecycle, inheritance/duplicate/reset semantics, invalid scope/value, permission denial and rollback. This task does not declare the Theme Builder UI complete.
|
||||||
|
|
||||||
|
## Task 10: Complete Economy commerce and bulk outcomes
|
||||||
|
|
||||||
|
Restore editable voucher code with duplicate conflict handling and preserved locked use counters; correct migration responsibilities for voucher and rare category/value updates. Catalog bulk-create must validate nonempty bounded input and report per-row committed/failed outcomes honestly, with partial canonical audit whenever only part succeeds. Preserve successful IDs and actionable failure indexes; do not blind-retry successful rows. Fully failed input must not claim success. Test mixed/all failed/all passed batches, refresh failure, audit failure and voucher code conflicts.
|
||||||
|
|
||||||
|
## Task 11: Restore soundtrack upload workflow
|
||||||
|
|
||||||
|
Add canonical soundtrack upload service/command using the reliable legacy MP3 validation, size limits and storage path rules. Share orchestration with the existing upload API; preserve authorization and response compatibility. Persist intent before filesystem work, compensate newly created file on DB failure, never delete a pre-existing file. Audit success/failure/partial truthfully. Test invalid content, oversize, successful upload, collision, DB failure cleanup and cleanup failure.
|
||||||
|
|
||||||
|
## Task 12: Complete investigative and commerce read models
|
||||||
|
|
||||||
|
Extend People user detail with bounded/batched legacy relations and capability-based sensitive-field redaction. Extend System logs with route-specific pagination/filter/search, stable ordering/totals and relevant investigation fields. Extend Economy marketplace/transactions with state/status, username joins/search and sorting; exclude expired active subscriptions; add full calendar campaign/reward and grouped rare category/value fields. Fix Hotel UNION filtering by applying filters to a derived table of the complete selection while preserving ordering aliases and fallback behavior. Tests must exercise real SQL/projections, parameter binding, totals and field round trips, not only manifest entries.
|
||||||
|
|
||||||
|
## Task 13: Make Studio history durable
|
||||||
|
|
||||||
|
Replace production process-memory-only reads with a bounded shared database-backed operation state/history repository. Retain existing repository contract and test-only in-memory adapter. Reuse current persistence if it can provide atomic identity/state validation; otherwise add a backward-compatible table/migration using repository conventions. Validate terminal transitions and monotonic progress atomically across instances. Keep secrets out of persisted output; do not pretend interrupted jobs are safely resumable. Test fresh-instance reads, list search/pagination, duplicate intent, competing/terminal events, and repository unavailability.
|
||||||
|
|
||||||
|
## Task 14: Complete Studio import orchestration
|
||||||
|
|
||||||
|
Extract shared furniture import orchestration from the active legacy API and use it from Studio. Preserve selected source, translation options, final reconciliation, asset ownership, gamedata sync and catalog/items refresh. Preserve API streaming and cancellation contracts. Return explicit per-stage partial outcomes without replaying completed stages. Compare every Studio operation with its legacy responsibility, including catalog audit/repair. Test source/options forwarding and finalization failures using service transport adapters; no real external writes.
|
||||||
|
|
||||||
|
## Remaining inventory (not completion claims)
|
||||||
|
|
||||||
|
- Hotel union query filtering; durable Studio history; furniture import orchestration parity; radio API-key delivery and full radio CRUD review.
|
||||||
|
- Content/Economy and People/System audit reports: validate and append concrete tasks before implementation.
|
||||||
|
- Shared input, foreign-reference and operation-level audit policy review.
|
||||||
|
- Complete workflow-specific UI/read models and visual acceptance across six domains.
|
||||||
|
- Full branch review, builds, CI and service-backed acceptance; production cutover requires separate approval.
|
||||||
Reference in new issue
Block a user