diff --git a/docs/superpowers/plans/2026-07-11-admin-feature-recovery.md b/docs/superpowers/plans/2026-07-11-admin-feature-recovery.md new file mode 100644 index 00000000..491402d4 --- /dev/null +++ b/docs/superpowers/plans/2026-07-11-admin-feature-recovery.md @@ -0,0 +1,345 @@ +# 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-next` as 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`, and `pnpm build` all 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>` +- 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: + +```powershell +node scripts/check-local-imports.mjs +$env:DATABASE_URL='mysql://user:password@127.0.0.1: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** + +```powershell +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(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: + +```powershell +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** + +```powershell +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.ts` and `src/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: + +```powershell +pnpm vitest run src/lib/furni src/actions/catalog-items.test.ts +node scripts/check-local-imports.mjs +pnpm typecheck +``` + +- [ ] **Step 5: Commit** + +```powershell +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: + +```powershell +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** + +```powershell +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`, existing `src/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: + +```powershell +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** + +```powershell +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** + +```powershell +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 `main` with restored admin functionality. + +- [ ] **Step 1: Clean generated state and generate Prisma** + +```powershell +Remove-Item -Recurse -Force .next -ErrorAction SilentlyContinue +$env:DATABASE_URL='mysql://user:password@127.0.0.1:3306/atomcms' +pnpm prisma:generate +``` + +- [ ] **Step 2: Run complete gates** + +```powershell +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** + +```powershell +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`.