diff --git a/.cursor/rules/with-lingui-add-resource.mdc b/.cursor/rules/with-lingui-add-resource.mdc deleted file mode 100644 index 7148017..0000000 --- a/.cursor/rules/with-lingui-add-resource.mdc +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: "Add a new CRUD resource / scaffold (with-lingui)." -globs: apps/with-lingui/src/api/**/*.ts,apps/with-lingui/src/mocks/**/*.ts,apps/with-lingui/src/routes/_auth/**/*.tsx,apps/with-lingui/e2e/**/*.spec.ts -alwaysApply: false ---- - -# with-lingui · Add resource (thin rule) - -**Single source of truth:** - -`apps/with-lingui/.github/instructions/add-resource.instructions.md` - -When adding a resource, follow that recipe (mirror the `users` example). On conflict, the `.instructions.md` file wins. - -`@apps/with-lingui/.github/instructions/add-resource.instructions.md` diff --git a/.cursor/rules/with-lingui-api.mdc b/.cursor/rules/with-lingui-api.mdc deleted file mode 100644 index 0df0532..0000000 --- a/.cursor/rules/with-lingui-api.mdc +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: "API clients, Zod schemas, HTTP, MSW handlers (with-lingui)." -globs: apps/with-lingui/src/api/**/*.ts,apps/with-lingui/src/utils/http.ts,apps/with-lingui/src/mocks/handlers/**/*.ts,apps/with-lingui/src/mocks/createHandler.ts -alwaysApply: false ---- - -# with-lingui · API(薄规则) - -**唯一细则来源**: - -`apps/with-lingui/.github/instructions/api.instructions.md` - -编辑符合 `globs` 的文件时,遵守该文件中的约定;冲突以 `.instructions.md` 为准。 - -`@apps/with-lingui/.github/instructions/api.instructions.md` diff --git a/.cursor/rules/with-lingui-frontend.mdc b/.cursor/rules/with-lingui-frontend.mdc deleted file mode 100644 index f848906..0000000 --- a/.cursor/rules/with-lingui-frontend.mdc +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: "React UI, routes, components, styles, layout, i18n, Ant Design (with-lingui)." -globs: apps/with-lingui/src/**/*.{ts,tsx,css} -alwaysApply: false ---- - -# with-lingui · Frontend(薄规则) - -**唯一细则来源**(勿在此文件重复维护长文): - -`apps/with-lingui/.github/instructions/frontend.instructions.md` - -编辑符合 `globs` 的文件时,遵守该文件中的 Do / Do Not / Validation;如有冲突,以 `.instructions.md` 为准。 - -需要全文进上下文时,在对话里引用:`@apps/with-lingui/.github/instructions/frontend.instructions.md`。 diff --git a/.cursor/rules/with-lingui-refactor.mdc b/.cursor/rules/with-lingui-refactor.mdc deleted file mode 100644 index 5963e5c..0000000 --- a/.cursor/rules/with-lingui-refactor.mdc +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: "Refactors without behavior change — dedupe, naming, structure (with-lingui)." -globs: apps/with-lingui/src/**/*.{ts,tsx} -alwaysApply: false ---- - -# with-lingui · Refactor(薄规则) - -**唯一细则来源**: - -`apps/with-lingui/.github/instructions/refactor.instructions.md` - -做行为保持式重构时遵守该文件;与 frontend 规则同时命中时,**重构意图**以本文件指向的 refactor 指令为准,其余 UI 细节仍以 `frontend.instructions.md` 为准。 - -`@apps/with-lingui/.github/instructions/refactor.instructions.md` diff --git a/.cursor/rules/with-lingui-testing.mdc b/.cursor/rules/with-lingui-testing.mdc deleted file mode 100644 index ea60c0a..0000000 --- a/.cursor/rules/with-lingui-testing.mdc +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: "Playwright e2e, MSW mocks, test config (with-lingui)." -globs: apps/with-lingui/e2e/**/*.ts,apps/with-lingui/e2e/**/*.tsx,apps/with-lingui/src/mocks/**/*.ts,apps/with-lingui/playwright.config.ts -alwaysApply: false ---- - -# with-lingui · Testing(薄规则) - -**唯一细则来源**: - -`apps/with-lingui/.github/instructions/testing.instructions.md` - -编辑符合 `globs` 的文件时,遵守该文件中的约定;冲突以 `.instructions.md` 为准。 - -`@apps/with-lingui/.github/instructions/testing.instructions.md` diff --git a/.githooks/README.md b/.githooks/README.md index 7425e1f..327b238 100644 --- a/.githooks/README.md +++ b/.githooks/README.md @@ -1,26 +1,30 @@ -# Git hooks(仓库根) +# Git hooks (repository root) -本目录为 **monorepo 根级** Git 钩子。提交时根据暂存文件路径,在对应子项目目录执行检查(例如 `apps/with-lingui` 下执行 `vp staged`,以便正确读取该目录的 `vite.config.ts`)。 +This directory holds **monorepo root-level** Git hooks. On commit, checks run in the matching subproject based on staged file paths (for example, `vp staged` under `apps/with-lingui` so that directory’s `vite.config.ts` is loaded correctly). -模板应用目录内的 `.vite-hooks/`(如 `apps/with-lingui/.vite-hooks/`)留给 **模板单独拷贝出去使用**;在本仓库开发时请使用根级钩子,避免在仓库根执行 `vp staged` 找不到 `vite.config.ts`。 +Per-app `.vite-hooks/` under template apps (e.g. `apps/with-lingui/.vite-hooks/`) are for **copying a template out on its own**. When developing in this repo, use the root hooks so `vp staged` at the repo root does not fail to find `vite.config.ts`. -## 启用方式(一次性) +## Monorepo and `vp config` -在仓库根目录执行: +The root `package.json` `preinstall` sets `core.hooksPath=.githooks` before dependencies install and writes `vp.hooks.disabled=true` in **this clone** so parallel `prepare` scripts (`vp config`) from multiple workspaces do not fight over `.git/config` and cause lock conflicts. Template apps still use `"prepare": "vp config"`; when copied out alone they do not get the root `preinstall`. + +## Enabling (one-time) + +From the repository root: ```bash git config core.hooksPath .githooks ``` -或使用: +Or: ```bash pnpm run setup:git-hooks ``` -验证: +Verify: ```bash git config core.hooksPath -# 应输出:.githooks +# Expected: .githooks ``` diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 1664da5..bae6b61 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -16,11 +16,11 @@ run_in_dir() { } if echo "$STAGED" | grep -q '^apps/with-lingui/'; then - run_in_dir apps/with-lingui vp staged + run_in_dir apps/with-lingui pnpm exec vp staged fi if echo "$STAGED" | grep -q '^apps/basic/'; then - run_in_dir apps/basic vp staged + run_in_dir apps/basic pnpm exec vp staged fi if echo "$STAGED" | grep -q '^packages/create/'; then diff --git a/.gitignore b/.gitignore index f63e72f..7c32fe6 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,7 @@ yarn-error.log* # Git worktrees .worktrees/ -# Cursor:仅共享项目规则;其余本机数据仍忽略(方案 A — 细则单源在 apps/with-lingui/.github/instructions) +# Cursor: share project rules only; ignore other local Cursor data (agent rules: each app’s AGENTS.md) .cursor/* !.cursor/rules/ !.cursor/rules/** diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..22d6f67 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,23 @@ +# antd-admin (monorepo) + +Enterprise admin templates and docs. **AI and coding rules live in each app’s `AGENTS.md`**, not here. + +## Layout + +| Path | Role | +| --- | --- | +| `apps/basic` | English Vite+ template — see `apps/basic/AGENTS.md` | +| `apps/with-lingui` | Lingui i18n template — see `apps/with-lingui/AGENTS.md` | +| `apps/docs` | Nextra docs site | +| `packages/create` | `init-antd-admin` CLI | + +## Commands (repo root) + +- `pnpm install` — sets `core.hooksPath=.githooks` via `preinstall` +- `pnpm dev` / `pnpm build` / `pnpm fmt` / `pnpm lint` — turbo across workspaces + +**Template app work:** `cd apps/basic` or `cd apps/with-lingui`, then use **`vp`** (`vp install`, `vp check`, …). Do not run app `vp staged` from root without that `cd`. + +## Git hooks + +`.githooks/pre-commit` runs checks by staged paths: `pnpm exec vp staged` in `apps/basic` / `apps/with-lingui`, typecheck for `packages/create`, lint for `apps/docs`. diff --git a/README.md b/README.md index 345d91d..1414b8f 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ Antd Admin provides production-style admin templates with modern frontend toolin Available templates: -- `basic`: English-only setup -- `with-lingui`: Bilingual setup (`en` + `zh`) with Lingui +- `basic`: Admin template with plain-string UI copy (default English; no bundled Lingui) +- `with-lingui`: Lingui i18n workflow (`en` + `zh`) with locale switching Scaffolding CLI: @@ -20,6 +20,7 @@ Scaffolding CLI: - URL-synced table state (pagination, sorting, search) - Dark mode theme switching - Mock-first local development (no backend required) +- Modular API layer (`defineApi` per domain, Zod schemas, shared `API_PREFIX`) - Typed API boundaries and reusable CRUD patterns - React 19 + Ant Design 6 + TanStack Router/Query + Zustand + Zod - Optional Lingui-based i18n workflow (`with-lingui`) @@ -48,19 +49,23 @@ pnpm dlx init-antd-admin@latest my-app --example with-lingui --skip-install ### Common options -| Option | Description | -| ---------------------------- | -------------------------------- | -| `[project-directory]` | Target folder | -| `-e, --example ` | -| `--example-path ` | Subpath inside remote repository | -| `-m, --package-manager ` | `npm` / `pnpm` / `yarn` / `bun` | -| `--skip-install` | Skip dependency install | -| `--skip-transforms` | Skip rewrite transforms | -| `--no-git` | Skip git initialization | +| Option | Description | +| ---------------------------- | ------------------------------------------ | +| `[project-directory]` | Target folder | +| `-e, --example ` | Template name (`basic`, `with-lingui`) or URL | +| `--example-path ` | Subpath inside remote repository | +| `-m, --package-manager ` | `npm` / `pnpm` / `yarn` / `bun` | +| `--skip-install` | Skip dependency install | +| `--skip-transforms` | Skip rewrite transforms | +| `--no-git` | Skip git initialization | For detailed CLI behavior, see `[packages/create/README.md](./packages/create/README.md)`. +### AI / agent guidance + +Each template app keeps **`AGENTS.md`** as the single source of truth (Cursor, Claude Code, Codex, etc.). Monorepo overview: [AGENTS.md](./AGENTS.md) at the repo root. + Production docs: [https://antd-admin-doc.zuiidea.top](https://antd-admin-doc.zuiidea.top) ## Links diff --git a/apps/basic/.agents/skills/add-resource/SKILL.md b/apps/basic/.agents/skills/add-resource/SKILL.md new file mode 100644 index 0000000..5816201 --- /dev/null +++ b/apps/basic/.agents/skills/add-resource/SKILL.md @@ -0,0 +1,71 @@ +--- +name: add-resource +description: Add a new CRUD resource in antd-admin-basic (mirror users). Use when scaffolding roles, tenants, or any list+form resource with MSW, routes, menu, and e2e. +--- + +# Add Resource Recipe + +Add a list CRUD flow that mirrors **Users** (TanStack Router + Query + MSW). **No codegen** — copy and adapt by hand. References: `src/routes/_auth/users/` and matching `e2e/*.spec.ts`. UI copy is **English plain strings** (no i18n). + +## 0. Verification commands (after your changes) + +Run from the **app root** (this project directory — where `package.json` and `vite.config.ts` live): + +```bash +pnpm run build # refresh TanStack routeTree when routes change +vp check --no-fmt +pnpm run test:e2e -- e2e/.spec.ts +``` + +## 1. Zod and types (`src/api//schemas.ts`) + +- Define `Schema`, `CreateRequestSchema`, `UpdateRequestSchema` (`Update` = `Create.partial()`). +- For list `output`, reuse `PaginatedDataSchema(Schema)` (unwrapped `data`; envelope stays in `request.ts`). +- Add list query schema (e.g. `ListQuerySchema`) when the table has filters/pagination. +- Export `type = z.infer`. + +## 2. Resource API module (`src/api//index.ts`) + +- Export path constants if useful for MSW/docs. +- Define APIs with `defineApi` from `@/api/request`: `list` / `create` / `update` / `delete` (and `queryKeys`). +- `method` defaults to `GET`; mutations set `POST` / `PUT` / `DELETE`. +- Use segmented `params` / `query` / `body` + `output`; do not call axios from routes. + +## 3. Mock data (`src/mocks/data.ts`) + +- Append a `MOCK_` array. For **admin** users, `permissions` must include `:view` (and create/edit/delete if you add writes), aligned with `GET /api/auth/permissions`. + +## 4. MSW (`src/mocks/handlers/.ts` + `handlers/index.ts`) + +- Follow `handlers/user.ts`: paginated `GET` + optional `keyword`, `POST` / `PUT` / `DELETE`; use `successWithSchema` / `paginatedWithSchema` / `successWithNullBody` for success and `errorResponse` for errors. +- Register `...Handlers` in `handlers/index.ts`. + +## 5. Route page (`src/routes/_auth//`) + +- `createFileRoute("/_auth//")`, wiring `useResourceCRUD` with resource functions (`listX`, `createX`, …) and `queryKeys` from `@/api/` (recommended: `optimistic: { update: true, delete: true }`), plus `useCrudToasts`, `useUrlSearchState`, `useTableFitHeight` (see `users/` for splitting `-Toolbar` / `-FormModal`). +- Use English string literals for labels, placeholders, and messages. + +## 6. Menu and permissions (`src/utils/appMenu.ts`) + +- Add a menu entry to `APP_MENU_TREE`: `path: "/"`, `permissions: [":view"]`, `icon` using a Sidebar-registered key (see existing `IconLucide*` entries in `Sidebar`). +- Keep behavior consistent with `canAccessPath` / 403. + +## 6b. Sidebar labels and icons (`src/components/Layout/Sidebar/index.tsx`) + +- In `MENU_LABELS`, add an English label for the menu item `name` (must match the `name` string from `appMenu`). +- In `MENU_ICON_MAP`, map the new `icon` key to a `lucide-react` icon and add the matching `import`. + +## 7. E2E (`e2e/.spec.ts`) + +- Copy structure from `users.spec.ts`: `loginAsAdmin` → `goto /`, assert headers / search placeholder, etc. + +## 8. Verification + +- `vp check --no-fmt` +- `pnpm run test:e2e` (focused spec) or full suite as needed +- `pnpm run build` and watch chunk sizes in the log + +## Notes + +- Before adding or renaming files, confirm nothing already exists at that path so you do not overwrite hand-written code. +- After manual schema edits, treat the diff as source of truth; there is no automatic merge. diff --git a/apps/basic/.github/instructions/README.md b/apps/basic/.github/instructions/README.md deleted file mode 100644 index 27850d7..0000000 --- a/apps/basic/.github/instructions/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# AI Instruction Files - -This directory contains scoped instruction files used by AI coding agents. - -## Files - -- `frontend.instructions.md`: UI/routes/components/style changes -- `testing.instructions.md`: Playwright/MSW/test changes -- `api.instructions.md`: API client/schema/handler changes -- `refactor.instructions.md`: behavior-preserving cleanup and deduplication - -## Authoring Rules - -- Keep each file focused on one domain. -- Put trigger phrases in `description` so agents can discover the file. -- Use narrow `applyTo` patterns to avoid unnecessary context load. -- Keep instructions executable: short Do/Do Not/Validation sections. diff --git a/apps/basic/.github/instructions/api.instructions.md b/apps/basic/.github/instructions/api.instructions.md deleted file mode 100644 index 24f0c26..0000000 --- a/apps/basic/.github/instructions/api.instructions.md +++ /dev/null @@ -1,30 +0,0 @@ ---- - -## applyTo: "src/api/**/\*.ts,src/utils/http.ts,src/mocks/handlers/**/\*.ts,src/mocks/createHandler.ts" - -description: "Use when editing API clients, schemas, HTTP behavior, response types, or MSW endpoint handlers. Keywords: api, http, schema, zod, handler, endpoint, auth, users." - -# API Instructions - -## Purpose - -Maintain strict API contracts and consistent server/client mock behavior. - -## Do - -- Keep request/response shapes schema-driven and type-safe. -- Reuse endpoint constants and shared response helpers. -- Keep handler response envelope consistent (`code`, `data`, `message`). -- Ensure mock handlers reflect real API behavior and error semantics. -- Keep naming stable for endpoint keys and mutation/query keys. - -## Do Not - -- Do not return ad-hoc response shapes for one-off convenience. -- Do not bypass schema parsing in new client mutations/queries. -- Do not mix unrelated domain endpoints in the same module. - -## Validation - -- Verify TypeScript and schema parsing paths compile cleanly. -- Run: `vp check --no-fmt` diff --git a/apps/basic/.github/instructions/frontend.instructions.md b/apps/basic/.github/instructions/frontend.instructions.md deleted file mode 100644 index 1f88597..0000000 --- a/apps/basic/.github/instructions/frontend.instructions.md +++ /dev/null @@ -1,32 +0,0 @@ ---- - -## applyTo: "src/\*_/_.{ts,tsx,css}" - -description: "Use when editing React UI, route pages, components, styles, layout, i18n text, or Ant Design behavior. Keywords: frontend, component, page, ui, layout, style, antd, i18n." - -# Frontend Instructions - -## Purpose - -Keep frontend changes predictable, minimal, and reusable for AI-assisted edits. - -## Do - -- Preserve existing route contracts and UI behavior unless explicitly asked. -- Prefer reusable components and hooks over copy-paste logic. -- Keep styles token-driven using existing theme/store patterns. -- For Ant Design styling, follow this priority: component native API (`variant`/`type`/`size`/`styles`/`classNames`) -> `theme.useToken()` with inline `style` -> `className` + external CSS. -- Keep translations compatible with Lingui macros and catalogs. -- Follow current folder conventions under src/components and src/routes. - -## Do Not - -- Do not introduce new UI libraries when Ant Design already covers the need. -- Do not bypass existing theme/store abstractions with hardcoded global state. -- Do not write CSS overrides first when props or semantic `styles` can express the same UI. -- Do not refactor unrelated files in the same change. - -## Validation - -- Run: `vp check --no-fmt` -- For UI flow changes, run focused e2e where possible. diff --git a/apps/basic/.github/instructions/refactor.instructions.md b/apps/basic/.github/instructions/refactor.instructions.md deleted file mode 100644 index 81e74f5..0000000 --- a/apps/basic/.github/instructions/refactor.instructions.md +++ /dev/null @@ -1,37 +0,0 @@ ---- - -## applyTo: "src/_/_.{ts,tsx}" - -description: "Use when refactoring existing code for deduplication, modularization, naming cleanup, or maintainability improvements without behavior changes. Keywords: refactor, cleanup, simplify, deduplicate, maintainability." - -# Refactor Instructions - -## Purpose - -Reduce duplication while preserving behavior and public contracts. - -## Do - -- Keep refactors incremental and scoped to one concern per change. -- Prefer extracting shared utilities/hooks/components over large rewrites. -- Preserve existing external behavior and route/store contracts. -- Keep diffs reviewable with minimal unrelated formatting churn. -- Add or update lightweight comments only when logic is non-obvious. - -## Do Not - -- Do not change runtime behavior unless explicitly requested. -- Do not rename broadly across the codebase without clear benefit. -- Do not delete tests that still cover unique critical scenarios. -- Do not introduce large dependencies for minor convenience; prefer composition or small utilities. - -## Considerations - -- Bundle: Main app chunk is ~135KB (gzip ~41KB). Ant Design (vendor-antd) and TanStack (vendor-tanstack) are in separate chunks for parallel loading. Avoid adding large UI libraries when Ant Design covers the need. -- Type safety: Keep validations at API boundaries (Zod schemas) rather than adding more runtime checks throughout the app. - -## Validation - -- Confirm no new diagnostics in touched files. -- Run: `vp check --no-fmt` -- For significant changes, verify bundle size impact: `vp build 2>&1 | grep "kB"` diff --git a/apps/basic/.github/instructions/testing.instructions.md b/apps/basic/.github/instructions/testing.instructions.md deleted file mode 100644 index b08d024..0000000 --- a/apps/basic/.github/instructions/testing.instructions.md +++ /dev/null @@ -1,30 +0,0 @@ ---- - -## applyTo: "tests/**/.ts,tests/**/_.tsx,src/mocks//_.ts,playwright.config.ts" - -description: "Use when adding or editing tests, Playwright cases, MSW handlers, mock data, or test configuration. Keywords: test, e2e, playwright, mock, msw, coverage." - -# Testing Instructions - -## Purpose - -Keep tests fast, deterministic, and aligned with core business flows. - -## Do - -- Prioritize core flows first (auth, users CRUD, permission gates). -- Keep assertions user-visible and behavior-focused. -- Reuse existing helper patterns in tests before adding new helpers. -- Keep mock handlers and mock data synchronized with API schemas. -- Prefer focused test runs over full-suite runs during iteration. - -## Do Not - -- Do not add brittle selectors tied to unstable DOM internals. -- Do not expand fixture data without a clear scenario need. -- Do not duplicate scenarios already covered by existing tests. - -## Validation - -- Run focused tests first, then broader checks if needed. -- Run: `vp check --no-fmt` diff --git a/apps/basic/AGENTS.md b/apps/basic/AGENTS.md index 49ea51f..159fe07 100644 --- a/apps/basic/AGENTS.md +++ b/apps/basic/AGENTS.md @@ -1,84 +1,76 @@ -# Using Vite+, the Unified Toolchain for the Web +# antd-admin-basic -This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`. +Vite+ template app (React 19, Ant Design 6, TanStack Router/Query, MSW). Default UI copy is English (no i18n). CLI details: [viteplus.dev](https://viteplus.dev). -## Vite+ Workflow +## Commands -`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp --help` for information about a specific command. +Run from **this app root** (directory with `package.json` / `vite.config.ts`): -### Start +| Task | Command | +| ------------------------- | ---------------------------------------------------- | +| Install deps | `vp install` (after every pull) | +| Dev / build / preview | `vp dev`, `vp build`, `vp preview` | +| Format / lint / typecheck | `vp check`, `vp check --no-fmt`, `vp lint`, `vp fmt` | +| Unit tests | `vp test run` | +| E2E | `pnpm run test:e2e` (or focused spec via Playwright) | +| Add/remove deps | `vp add`, `vp remove` — not raw `pnpm`/`npm`/`yarn` | -- create - Create a new project from a template -- migrate - Migrate an existing project to Vite+ -- config - Configure hooks and agent integration -- staged - Run linters on staged files -- install (`i`) - Install dependencies -- env - Manage Node.js versions +**Pitfalls:** Do not install Vitest/Oxlint/Oxfmt/tsdown directly; use `vp`. Do not run `vp vitest` — use `vp test`. If a `package.json` script name conflicts with a built-in `vp` command, use `vp run