13 KiB
EpicNext CMS Admin Feature Recovery Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Restore all admin functionality removed by 4d515bc and make the complete EpicNext CMS application pass tests, typecheck, and production build.
Architecture: Revert the destructive revert, inventory unresolved imports, then port the smallest compatible shared and domain layers from E:\Users\simol\Desktop\habbo-next. EpicNext CMS remains authoritative for routing, authentication, Prisma models, and error handling.
Tech Stack: Next.js 16, React 19, TypeScript, Prisma 7/MariaDB, NextAuth 5, Vitest, Tailwind CSS 4, Radix UI/shadcn-style primitives.
Global Constraints
- Never delete a feature merely to make compilation succeed.
- Treat
E:\Users\simol\Desktop\habbo-nextas read-only reference material. - Preserve all security, PayPal, pagination, and public contrast changes from
4a1e111. - Adapt every database operation to EpicNext CMS's local Prisma schema.
- Every server mutation must use the existing staff authorization path and validated input.
- Do not push until
pnpm test,pnpm typecheck, andpnpm buildall exit zero.
Task 1: Restore the Removed Feature Set and Capture the Failure Inventory
Files:
- Restore: files deleted or rewound by commit
4d515bc - Create:
scripts/check-local-imports.mjs - Test:
src/lib/local-imports.test.ts
Interfaces:
-
Produces:
findMissingLocalImports(root: string): Promise<Array<{ importer: string; specifier: string }>> -
Produces: a deterministic unresolved-import report used by every later task.
-
Step 1: Write a failing local-import test
Create a fixture containing import { Button } from "@/components/ui/button" and assert that findMissingLocalImports() reports it when no matching file exists.
- Step 2: Verify RED
Run: pnpm vitest run src/lib/local-imports.test.ts
Expected: failure because the scanner does not exist.
- Step 3: Implement the scanner
Scan .ts and .tsx files, resolve @/ against src, and test .ts, .tsx, .js, .jsx, and /index candidates. Return sorted importer/specifier pairs and expose the same function through scripts/check-local-imports.mjs for CI output.
- Step 4: Verify GREEN
Run: pnpm vitest run src/lib/local-imports.test.ts
Expected: fixture test passes.
- Step 5: Restore functionality
Run: git revert 4d515bc
Resolve overlaps by preserving current security/contrast implementations while restoring every admin consumer and action from 41be683.
- Step 6: Capture the build and import failures
Run:
node scripts/check-local-imports.mjs
$env:DATABASE_URL='mysql://user:[email protected]:3306/atomcms'
pnpm prisma:generate
pnpm build
Expected: build fails for unresolved modules, and the scanner lists the complete local dependency inventory.
- Step 7: Commit
git add scripts/check-local-imports.mjs src/lib/local-imports.test.ts src
git commit -m "fix: restore incomplete admin feature set"
Task 2: Restore Shared UI, Hooks, Utilities, Types, and Packages
Files:
- Create/modify:
src/components/ui/*.tsx - Create:
src/hooks/use-server-action.ts - Create/modify:
src/lib/utils.ts - Create/modify:
src/types/index.ts - Modify:
package.json - Modify:
pnpm-lock.yaml - Test:
src/hooks/use-server-action.test.tsx - Test:
src/lib/utils.test.ts
Interfaces:
-
Produces:
cn(...inputs: ClassValue[]): string -
Produces:
useServerAction<TArgs, TResult>(action, options)with pending, result, and error state. -
Produces: shadcn-compatible exports consumed by restored admin pages, including Button, Badge, Card, Dialog, Input, Label, Select, Table, Tabs, Textarea, Checkbox, Command, Popover, Switch, Tooltip, Skeleton, and AlertDialog.
-
Step 1: Add failing utility and hook tests
Assert that cn("a", false && "b", "c") returns "a c", conflicting Tailwind classes merge correctly, successful actions expose results, and thrown actions expose a safe error while clearing pending state.
- Step 2: Verify RED
Run: pnpm vitest run src/lib/utils.test.ts src/hooks/use-server-action.test.tsx
Expected: missing-module failures.
- Step 3: Port the minimal shared layer
Use the corresponding Habbo Next files as reference. Remove locale routing and unrelated providers. Add only packages directly imported by restored consumers, including Radix primitives, class-variance-authority, clsx, tailwind-merge, cmdk, sonner, and the three @dnd-kit packages.
- Step 4: Verify GREEN and rescan
Run:
pnpm vitest run src/lib/utils.test.ts src/hooks/use-server-action.test.tsx
node scripts/check-local-imports.mjs
pnpm typecheck
Expected: shared-layer tests pass; remaining missing imports are domain-specific.
- Step 5: Commit
git add package.json pnpm-lock.yaml src/components/ui src/hooks src/lib/utils.ts src/lib/utils.test.ts src/types
git commit -m "fix: restore admin shared component layer"
Task 3: Restore Catalog and Furni Import Domains
Files:
- Create/modify:
src/components/admin/catalog/** - Create/modify:
src/components/admin/catalog-manager/** - Create/modify:
src/lib/furni/** - Create/modify:
src/lib/client-cache/** - Create/modify:
src/lib/catalog-layouts.ts - Create/modify:
src/lib/move-suggestions.ts - Modify:
src/actions/catalog.ts - Modify:
src/actions/catalog-bc.ts - Modify:
src/actions/catalog-items.ts - Modify:
src/actions/import-badges.ts - Modify:
src/actions/import-furni.ts - Test: focused tests under
src/lib/furni/*.test.tsandsrc/actions/catalog-items.test.ts
Interfaces:
-
Produces: catalog page/item CRUD actions returning
{ ok: true; data } | { ok: false; error }. -
Produces: safe furni classname/path helpers and import validation.
-
Step 1: Add failing tests
Cover invalid catalog identifiers, unauthorized mutation, safe furni classnames, duplicate imported items, and transactional bulk updates.
- Step 2: Verify RED
Run: pnpm vitest run src/lib/furni src/actions/catalog-items.test.ts
- Step 3: Port and adapt implementations
Use Habbo Next catalog/import helpers as reference. Replace [locale] paths with EpicNext routes, use requireStaffRateLimited(), and map every Prisma field against prisma/schema.prisma before writing queries.
- Step 4: Verify GREEN and checkpoint build
Run:
pnpm vitest run src/lib/furni src/actions/catalog-items.test.ts
node scripts/check-local-imports.mjs
pnpm typecheck
- Step 5: Commit
git add src/components/admin/catalog src/components/admin/catalog-manager src/lib/furni src/lib/client-cache src/lib/catalog-layouts.ts src/lib/move-suggestions.ts src/actions/catalog*.ts src/actions/import-*.ts
git commit -m "fix: restore catalog and furni administration"
Task 4: Restore Permissions, Users, and Rooms
Files:
- Create/modify:
src/lib/permissions.ts - Create/modify:
src/lib/admin-list.ts - Create/modify:
src/lib/imager.ts - Create/modify:
src/lib/services/watch.ts - Modify:
src/actions/permissions.ts - Modify:
src/actions/bulk-users.ts - Modify:
src/actions/rooms.ts - Modify:
src/actions/multi-account-detect.ts - Test:
src/lib/permissions.test.ts,src/actions/permissions.test.ts,src/actions/rooms.test.ts
Interfaces:
-
Produces: permission reads and mutations based on EpicNext rank tables.
-
Produces: room and bulk-user actions with staff checks and validated numeric IDs.
-
Step 1: Add failing authorization and schema tests
Test denial without a staff session, denial without the named permission, preservation of immutable permission fields, positive integer IDs, and atomic room updates.
- Step 2: Verify RED
Run: pnpm vitest run src/lib/permissions.test.ts src/actions/permissions.test.ts src/actions/rooms.test.ts
- Step 3: Implement against the EpicNext schema
Use Habbo Next only for workflow structure. Preserve EpicNext's resolveStaffUser path and adapt permission/rank queries to actual local Prisma models.
- Step 4: Verify GREEN and typecheck
Run:
pnpm vitest run src/lib/permissions.test.ts src/actions/permissions.test.ts src/actions/rooms.test.ts
node scripts/check-local-imports.mjs
pnpm typecheck
- Step 5: Commit
git add src/lib/permissions.ts src/lib/admin-list.ts src/lib/imager.ts src/lib/services/watch.ts src/actions/permissions.ts src/actions/bulk-users.ts src/actions/rooms.ts src/actions/multi-account-detect.ts src/app/admin/permissions src/app/admin/users src/app/admin/rooms
git commit -m "fix: restore permissions users and room administration"
Task 5: Restore Tickets, Translations, and Sounds
Files:
- Create/modify:
src/actions/tickets.ts - Create/modify:
src/actions/ticket-templates.ts - Create/modify:
src/actions/translations.ts - Create/modify:
src/lib/services/ticket-replies.ts - Create/modify: sound and translation helpers identified by the import scanner.
- Test:
src/actions/tickets.test.ts,src/actions/translations.test.ts, existingsrc/lib/services/ticket-replies.test.ts
Interfaces:
-
Produces: ticket assignment/status/priority/reply actions.
-
Produces: template CRUD actions.
-
Produces: validated CMS/client translation writes.
-
Produces: sound metadata operations required by admin pages.
-
Step 1: Add failing domain tests
Cover cross-ticket reply rejection, invalid status transitions, template ownership/permission, translation key validation, path traversal rejection, and unsupported sound metadata.
- Step 2: Verify RED
Run: pnpm vitest run src/actions/tickets.test.ts src/actions/translations.test.ts src/lib/services/ticket-replies.test.ts
- Step 3: Port compatible implementations
Use Habbo Next actions as behavioral reference, route errors through logServerError, validate all identifiers and paths, and retain EpicNext's existing ticket-reply service protections.
- Step 4: Verify GREEN and clear imports
Run:
pnpm vitest run src/actions/tickets.test.ts src/actions/translations.test.ts src/lib/services/ticket-replies.test.ts
node scripts/check-local-imports.mjs
pnpm typecheck
Expected: zero unresolved local imports.
- Step 5: Commit
git add src/actions/tickets.ts src/actions/ticket-templates.ts src/actions/translations.ts src/lib/services src/app/admin/tickets src/app/admin/translations src/app/admin/sounds
git commit -m "fix: restore ticket translation and sound administration"
Task 6: Integration Hardening and Navigation
Files:
- Modify: restored admin navigation and messages.
- Modify: action files with inconsistent result or authorization contracts.
- Test:
src/lib/admin-action-contract.test.ts
Interfaces:
-
Produces: consistent admin action contract and reachable navigation for every restored page.
-
Step 1: Add failing contract checks
Assert every restored action module begins with "use server", imports an approved staff guard for mutations, and every restored route has a navigation label in all supported message files.
- Step 2: Verify RED
Run: pnpm vitest run src/lib/admin-action-contract.test.ts
- Step 3: Correct integration gaps
Add missing guards, stable result shapes, narrow revalidatePath() calls, navigation entries, and translations without changing unrelated public behavior.
- Step 4: Verify GREEN
Run: pnpm vitest run src/lib/admin-action-contract.test.ts
- Step 5: Commit
git add src/actions src/components/admin src/app/admin src/messages src/lib/admin-action-contract.test.ts
git commit -m "fix: harden restored admin integrations"
Task 7: Full Verification and Publication
Files:
- Modify only files required by fresh verification failures.
Interfaces:
-
Produces: a complete, buildable
mainwith restored admin functionality. -
Step 1: Clean generated state and generate Prisma
Remove-Item -Recurse -Force .next -ErrorAction SilentlyContinue
$env:DATABASE_URL='mysql://user:[email protected]:3306/atomcms'
pnpm prisma:generate
- Step 2: Run complete gates
node scripts/check-local-imports.mjs
pnpm test
pnpm typecheck
pnpm build
git diff --check nextjs/main..HEAD
Expected: zero missing imports, zero failed tests, typecheck exit 0, build exit 0, and clean diff check.
- Step 3: Audit retained fixes
Confirm PayPal capture ownership/idempotency, staff session normalization, safe pagination, and readable theme variables remain present and covered by their existing tests.
- Step 4: Fetch and publish only by fast-forward
git fetch nextjs main
git rev-list --left-right --count nextjs/main...HEAD
git push nextjs HEAD:main
git ls-remote nextjs refs/heads/main
Expected before push: 0 N. Expected after push: remote SHA equals local HEAD.