docs: add CLAUDE.md, expand AGENTS.md, correct stale README
The repo had no agent-facing project guidance: AGENTS.md contained only the generated TanStack Intent skill pointers, and README.md described a stack this app does not use. - CLAUDE.md (new): API client contract (envelope, ApiError, single-flight 401 refresh, the FormData Content-Type trap), the PERM catalog mirroring the backend permission classes, the route + NAV_GROUPS + PERM triad that must be edited together to add a page, and the useListPage/DataTable pattern. - AGENTS.md: gotchas above the generated block, which is left untouched — global query retry policy, can() vs useCan() reactivity, the gig-admin-auth persist key, and that jsdom is opted into per file via a `// @vitest-environment jsdom` pragma since there is no vitest config. - README.md: @tanstack/react-start is not a dependency (this is a plain Vite SPA, no SSR); cf:deploy no longer copies a shell to index.html; the feature list was a milestone-1 snapshot that omitted five shipped nav groups and still called moderation reports a future milestone. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_013MADG54Y51wZkU3ViRjeSi
This commit is contained in:
@@ -2,7 +2,13 @@
|
||||
|
||||
Standalone admin dashboard for the gig-platform backend (`/api/admin/v1/*`).
|
||||
|
||||
React 19 · TanStack Start (SPA mode) · TanStack Query/Table · shadcn/ui · Tailwind v4 · TypeScript.
|
||||
React 19 · TanStack Router · TanStack Query/Table · shadcn/ui · Tailwind v4 · TypeScript · Vite.
|
||||
|
||||
It is a plain client-rendered SPA (`index.html` → `src/main.tsx` → `RouterProvider`). There is no
|
||||
SSR and no server functions — `@tanstack/react-start` is not used.
|
||||
|
||||
> Working on this repo with an AI agent? `CLAUDE.md` has the architecture and conventions,
|
||||
> `AGENTS.md` the gotchas.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -21,6 +27,9 @@ ddev exec php artisan tinker storage/app/e2e-admin-seed.php
|
||||
# → [email protected] / Admin@12345
|
||||
```
|
||||
|
||||
An account that authenticates but holds no admin roles or permissions is treated as
|
||||
logged out — the app clears the session and returns you to the login screen.
|
||||
|
||||
## Scripts
|
||||
|
||||
| Command | Purpose |
|
||||
@@ -28,8 +37,14 @@ ddev exec php artisan tinker storage/app/e2e-admin-seed.php
|
||||
| `pnpm dev` | dev server on :3000 |
|
||||
| `pnpm build` / `pnpm preview` | production build / preview |
|
||||
| `pnpm typecheck` | `tsc --noEmit` |
|
||||
| `pnpm test` | vitest (API client envelope/refresh/error tests) |
|
||||
| `pnpm test` | vitest — API client (envelope / refresh / errors) and auth store |
|
||||
| `pnpm generate-routes` | `tsr generate` — rewrite `src/routeTree.gen.ts` (dev/build do this automatically) |
|
||||
| `pnpm gen:api` | regenerate `src/api/types.gen.ts` from the backend's private admin OpenAPI spec (`../gig-platform/storage/app/api-docs/admin/openapi.yaml`; run `ddev artisan api-docs:generate` there first) |
|
||||
| `pnpm cf:build` / `pnpm cf:deploy` | Cloudflare build / build + `wrangler deploy` |
|
||||
|
||||
There is no ESLint config and no lint script: `pnpm typecheck && pnpm test` is the gate, and it
|
||||
is what CI runs. `tsconfig.json` is `strict` with `noUnusedLocals`/`noUnusedParameters`, so an
|
||||
unused import fails the typecheck.
|
||||
|
||||
## Uploads
|
||||
|
||||
@@ -49,7 +64,7 @@ Cloudflare returns `dist/index.html` for every client route.
|
||||
`CLOUDFLARE_ACCOUNT_ID` in your env):
|
||||
|
||||
```bash
|
||||
pnpm cf:deploy # vite build → copy shell to index.html → wrangler deploy
|
||||
pnpm cf:deploy # vite build → wrangler deploy
|
||||
```
|
||||
|
||||
**CI/CD** — every push & PR runs typecheck + test + build; pushes to `main`
|
||||
@@ -73,26 +88,44 @@ Configure these on the repo before the first deploy:
|
||||
enabled and an `act_runner` registered with the `ubuntu-latest` label (use an
|
||||
image such as `catthehacker/ubuntu:act-22.04`).
|
||||
|
||||
`VITE_API_BASE_URL` is read at build time, so pointing a deployment at a different
|
||||
backend means rebuilding, not changing a runtime setting.
|
||||
|
||||
## Architecture notes
|
||||
|
||||
- **Auth**: Bearer tokens in localStorage (zustand persist). `src/api/client.ts`
|
||||
unwraps the `{success, data, message}` envelope, sends `X-Language-Locale`,
|
||||
and does a single-flight refresh-then-retry on 401
|
||||
- **Auth**: Bearer tokens in localStorage under `gig-admin-auth` (zustand persist).
|
||||
`src/api/client.ts` unwraps the `{success, data, message}` envelope, sends
|
||||
`X-Language-Locale`, and does a single-flight refresh-then-retry on 401
|
||||
(`POST /api/v1/auth/refresh-token`, `client_machine_name=admin-api-client`).
|
||||
- **Permissions**: `GET /auth/me` returns `meta.roles` / `meta.permissions`;
|
||||
nav items and routes gate on them (`super-admin` passes everything).
|
||||
nav items and routes gate on them (`super-admin` passes everything). The key
|
||||
catalog lives in `src/auth/permissions.ts` and mirrors the backend's
|
||||
`Modules/{Module}/app/Permissions/`.
|
||||
- **Lists**: `useListPage` + `<DataTable>` bind to the backend's
|
||||
`pagination {current_page, page_size, …}` shape (`page`/`page_size` params).
|
||||
- **Errors**: `handleApiError` (`src/lib/errors.ts`) is the single mutation error
|
||||
path — 422 field errors land on the form, everything else becomes a toast.
|
||||
- **Generated types** (`types.gen.ts`) are reference-only (`@ts-nocheck` —
|
||||
scribe emits duplicate operationIds); hand-written shapes live in
|
||||
`src/api/types.ts`.
|
||||
- **UI copy** is hardcoded 简体中文. `i18next` and `next-themes` are installed but
|
||||
unused; theming is a `dark` class set by an inline script in `index.html`.
|
||||
|
||||
## Features (milestone 1)
|
||||
## Features
|
||||
|
||||
- 分类管理:分类树 CRUD、待审核队列(通过/驳回/合并到已有分类)
|
||||
- 内容工作室:机器人作者(暂停/恢复)、系列、文章、子话题、分类简报、风格预设、
|
||||
Sidebar groups (each entry hidden unless the account holds its permission):
|
||||
|
||||
- **分类管理** — 分类树 CRUD、待审核队列(通过/驳回/合并到已有分类)
|
||||
- **内容工作室** — 机器人作者、文章系列、文章、子话题、分类简报、风格预设、
|
||||
Agent 接入令牌(签发一次性展示 / 吊销)
|
||||
- 用户与系统:SID 保留规则、幸运号码、查询/分配;语言设置;推送设备;机器人会话令牌
|
||||
- **专长交易** — 需求、派单、订单、服务商监控
|
||||
- **Dimzou 内容** — 文档监控、发布监控、翻译
|
||||
- **简历导入** — 批量导入任务
|
||||
- **内容审核** — 被举报评论、被举报事件
|
||||
- **用户与系统** — 用户列表、角色管理、用户角色、SID 管理(保留规则、幸运号码、
|
||||
查询/分配)、语言设置、推送设备、机器人会话令牌
|
||||
- **开发工具** — API 文档、数据库管理台
|
||||
|
||||
Next milestones: moderation reports (comment / file-x), dashboard stats
|
||||
(needs backend endpoints).
|
||||
`/` has no dashboard: it redirects to the first nav route the account can see, and
|
||||
renders a "未分配权限" card only when there is none. Dashboard stats are still pending
|
||||
backend endpoints.
|
||||
|
||||
Reference in New Issue
Block a user