# Next.js Full-Stack CRUD, RBAC, and Audit Logs

## Goal

Turn the current static/local-storage Next.js app into a minimal real full-stack application for the first operational slice: account setup/login, built-in RBAC, elder profile CRUD, and auditable administrative actions.

The first release should remove mock/local-only behavior from the core flow and persist data through server-side APIs so the app can be exercised end-to-end without browser localStorage state.

## Confirmed Facts

- The repository is already a Next.js 15 App Router project with routes under `app/`.
- Protected app screens are currently guarded by `modules/auth/components/AuthGate.tsx`, which reads localStorage through `modules/auth/lib/local-auth.ts`.
- Login/register/setup UI exists in `modules/auth/components/AuthPanel.tsx`, but password input is not validated server-side and accounts are browser-local.
- The "老人档案" route at `app/(app)/app/elders/page.tsx` is currently a static `ModulePage`.
- The "权限设置" route at `app/(app)/app/settings/page.tsx` is currently a static `ModulePage`.
- The project has no installed database/auth dependencies such as Drizzle, PostgreSQL client, oRPC, Zod, or better-auth.
- Current `package.json` already supports `pnpm lint`, `pnpm type-check`, and `pnpm build`.

## MVP Scope

- Implement a real server-side persistence layer using JSON files under a server-owned data directory for this milestone. This is not mock data: API mutations must write durable data on disk during local/runtime execution.
- Use Next.js Route Handlers for the first API surface instead of adding oRPC/Drizzle/better-auth in this milestone.
- Replace localStorage authentication with server-side account/session APIs and HTTP-only cookie sessions.
- Provide built-in roles and permission groups without user-defined custom role creation in this milestone.
- Implement full CRUD for elder profiles as the first business entity.
- Implement a permissions/settings page that shows accounts, roles, permission coverage, and audit logs from server data.
- Record audit log entries for login, logout, account creation, elder create/update/delete, and permission-sensitive denied actions.

## Requirements

### Authentication

- Setup must create the first administrator account on the server.
- Login must validate account credentials on the server and set an HTTP-only session cookie.
- Logout must clear the session cookie and record an audit event when possible.
- App routes must no longer depend on localStorage for authentication.

### Roles and Permissions

- The system must include built-in roles:
  - `admin`: full access to accounts, permissions, audit logs, and elder CRUD.
  - `manager`: elder CRUD and audit log viewing, but no account/role administration.
  - `caregiver`: elder read/update access for care-facing fields, no delete or account administration.
  - `viewer`: read-only elder access.
- Permission checks must run on the server for all protected APIs.
- UI navigation or controls may hide unavailable actions, but hidden UI must not be the only enforcement.

### Elder CRUD

- Users with permission can list, create, update, and delete elder profiles.
- Elder records must include at minimum: name, gender, birth date or age, care level, room/bed, status, primary contact, phone, medical notes, created/updated timestamps.
- The elder page must show real server data and support create/edit/delete interactions.
- Invalid input must return structured API errors and show usable feedback in the UI.

### Audit Logs

- Audit logs must be persisted server-side and visible in the settings page.
- Each audit record must include timestamp, actor account ID/email when available, action, target type, target ID when available, result, and human-readable reason.
- Failed permission checks must be logged without exposing sensitive internals to the client.

### Data and API

- API responses must use a consistent `{ success, reason, ... }` shape.
- Server-side data helpers must avoid browser APIs.
- All file persistence operations must be centralized so future Drizzle/Postgres migration has a single boundary to replace.
- Do not use hard-coded UI counters for the implemented CRUD/settings/audit areas once server data exists.

### Quality

- Keep TypeScript strict without `any`, non-null assertions, or `@ts-ignore`/`@ts-expect-error`.
- Prefer Server Components for initial data loading and small Client Components only for forms/mutations.
- `pnpm lint`, `pnpm type-check`, and `pnpm build` should pass before marking implementation complete.

## Acceptance Criteria

- [ ] First-run setup creates a server-persisted admin account and redirects into the app.
- [ ] Login/logout uses server APIs and an HTTP-only cookie session, not localStorage.
- [ ] Visiting `/app/elders` while authenticated loads elder records from the server persistence layer.
- [ ] An authorized user can create, edit, and delete elder records from the UI, and changes survive page reloads.
- [ ] Unauthorized role attempts against protected elder/account/audit APIs return a forbidden response and create audit log entries.
- [ ] `/app/settings` displays built-in roles, account list, and recent audit log entries from server data.
- [ ] Audit logs are written for account creation, login, logout, elder create/update/delete, and denied permission checks.
- [ ] Existing static module pages outside the MVP continue to render.
- [ ] `pnpm lint` passes.
- [ ] `pnpm type-check` passes.
- [ ] `pnpm build` passes.

## Out of Scope

- PostgreSQL/Drizzle migration.
- oRPC adoption.
- better-auth adoption.
- Password reset, email verification, OAuth, multi-factor authentication, or account invitations.
- Custom role builder UI.
- CRUD implementation for every module in the sidebar.
- Production-grade password hashing beyond Node built-in cryptographic hashing suitable for this local MVP.

## Open Questions

- None blocking. The MVP assumes "basic CRUD" means the first core business entity, elder profiles, plus real account/session/audit support.

## Notes

- Next.js documentation confirms App Router Route Handlers support `GET`, `POST`, `PATCH`, and `DELETE`, `Response.json`, `request.json()`, and async `cookies()` from `next/headers` for cookie reads/writes in current versions.
