docs: add stage 1.6 enterprise governance plan
This commit is contained in:
@@ -0,0 +1,628 @@
|
||||
# Stage 1.6 Enterprise Governance 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:** Add a usable enterprise governance baseline with login, current user, users, user groups, roles, menus, API permission enforcement, permission-driven frontend navigation, and deployment bootstrap.
|
||||
|
||||
**Architecture:** Backend keeps Django's built-in `User`, `Group`, and `Permission` as the core auth model, adds `UserGroup` and `MenuItem` for product governance, exposes session-authenticated Django Ninja APIs, and enforces permissions in ticket/solution/audit/governance routers. Frontend wraps the Vite SPA in an auth provider, renders a shadcn-based Chinese login page for anonymous users, consumes backend menu data in `AppSidebar`, and adds shadcn-based system governance pages.
|
||||
|
||||
**Tech Stack:** Python 3.12, Django, Django Ninja, pytest, ruff, React, Vite, TypeScript, Tailwind CSS v3, shadcn/ui, Radix UI, npm.
|
||||
|
||||
---
|
||||
|
||||
## Source Spec
|
||||
|
||||
- `docs/superpowers/specs/2026-07-01-stage-1-6-enterprise-governance-design.md`
|
||||
|
||||
## File Structure
|
||||
|
||||
Backend:
|
||||
|
||||
- Modify: `backend/config/settings/base.py`
|
||||
- Modify: `backend/config/urls.py`
|
||||
- Modify: `backend/apps/accounts/models.py`
|
||||
- Modify: `backend/apps/accounts/permissions.py`
|
||||
- Modify: `backend/apps/accounts/schemas.py`
|
||||
- Modify: `backend/apps/accounts/api.py`
|
||||
- Create: `backend/apps/accounts/auth.py`
|
||||
- Create: `backend/apps/accounts/menus.py`
|
||||
- Create: `backend/apps/accounts/bootstrap.py`
|
||||
- Create: `backend/apps/accounts/management/commands/bootstrap_governance.py`
|
||||
- Create: `backend/apps/accounts/migrations/0001_initial.py`
|
||||
- Modify: `backend/apps/tickets/api.py`
|
||||
- Modify: `backend/apps/solutions/api.py`
|
||||
- Modify: `backend/apps/audit/api.py`
|
||||
- Create: `backend/apps/accounts/tests/test_auth_api.py`
|
||||
- Create: `backend/apps/accounts/tests/test_governance_api.py`
|
||||
- Create: `backend/apps/accounts/tests/test_permission_enforcement.py`
|
||||
- Create: `backend/apps/accounts/tests/test_bootstrap_governance.py`
|
||||
- Modify: existing ticket/solution/audit tests to authenticate where protected endpoints are exercised.
|
||||
|
||||
Frontend:
|
||||
|
||||
- Modify: `frontend/src/lib/api.ts`
|
||||
- Create: `frontend/src/features/auth/types.ts`
|
||||
- Create: `frontend/src/features/auth/api.ts`
|
||||
- Create: `frontend/src/features/auth/AuthProvider.tsx`
|
||||
- Create: `frontend/src/features/auth/LoginPage.tsx`
|
||||
- Modify: `frontend/src/app/App.tsx`
|
||||
- Modify: `frontend/src/app/router.tsx`
|
||||
- Modify: `frontend/src/app/layout/AppShell.tsx`
|
||||
- Modify: `frontend/src/components/app/AppSidebar.tsx`
|
||||
- Modify: `frontend/src/components/app/AppTopbar.tsx`
|
||||
- Create: `frontend/src/features/system/api.ts`
|
||||
- Create: `frontend/src/features/system/types.ts`
|
||||
- Create: `frontend/src/features/system/SystemUsersPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemUserGroupsPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemRolesPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemMenusPage.tsx`
|
||||
- Create: `frontend/src/features/audit/AuditLogPage.tsx`
|
||||
- Add shadcn components if missing: `checkbox`, `switch`, `alert`, `pagination`.
|
||||
|
||||
Deployment/docs:
|
||||
|
||||
- Modify: `.env.example`
|
||||
- Create: `infra/backend-entrypoint.sh`
|
||||
- Modify: `infra/backend.Dockerfile`
|
||||
- Modify: `infra/docker-compose.yml`
|
||||
- Modify: `docs/development/local-setup.md`
|
||||
|
||||
## Task 1: Backend Governance Models And Bootstrap
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/apps/accounts/models.py`
|
||||
- Modify: `backend/apps/accounts/permissions.py`
|
||||
- Create: `backend/apps/accounts/menus.py`
|
||||
- Create: `backend/apps/accounts/bootstrap.py`
|
||||
- Create: `backend/apps/accounts/management/commands/bootstrap_governance.py`
|
||||
- Create: `backend/apps/accounts/tests/test_bootstrap_governance.py`
|
||||
|
||||
- [ ] **Step 1: Write failing bootstrap test**
|
||||
|
||||
Create `backend/apps/accounts/tests/test_bootstrap_governance.py` with tests proving:
|
||||
|
||||
```python
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.core.management import call_command
|
||||
|
||||
from apps.accounts.models import MenuItem, UserGroup
|
||||
|
||||
|
||||
def test_bootstrap_governance_seeds_admin_roles_groups_permissions_and_menus(db, settings):
|
||||
settings.DJANGO_SUPERUSER_USERNAME = "admin"
|
||||
settings.DJANGO_SUPERUSER_PASSWORD = "admin12345"
|
||||
settings.DJANGO_SUPERUSER_EMAIL = "admin@example.com"
|
||||
|
||||
call_command("bootstrap_governance")
|
||||
call_command("bootstrap_governance")
|
||||
|
||||
user = get_user_model().objects.get(username="admin")
|
||||
assert user.is_superuser is True
|
||||
assert user.check_password("admin12345")
|
||||
assert Group.objects.filter(name="系统管理员").exists()
|
||||
assert Permission.objects.filter(codename="system.user.manage").exists()
|
||||
assert UserGroup.objects.filter(code="default").exists()
|
||||
assert MenuItem.objects.filter(code="system.users", title="用户管理").exists()
|
||||
assert MenuItem.objects.filter(code="system.roles", permission_code="system.role.view").exists()
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run the test to verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_bootstrap_governance.py -v
|
||||
```
|
||||
|
||||
Expected: fails because `MenuItem`, `UserGroup`, and `bootstrap_governance` do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement models, catalog, menus, bootstrap command**
|
||||
|
||||
Implement:
|
||||
|
||||
- `UserGroup` with `name`, `code`, `description`, `users`, `is_active`, timestamps.
|
||||
- `MenuItem` with `code`, `title`, `path`, `icon`, `parent`, `sort_order`, `permission_code`, `is_visible`, `is_enabled`, timestamps.
|
||||
- Chinese permission names and governance permission codes in `permissions.py`.
|
||||
- Default role names in Chinese.
|
||||
- Default menu catalog in `menus.py`.
|
||||
- `bootstrap_governance()` service function and `bootstrap_governance` management command.
|
||||
|
||||
- [ ] **Step 4: Make migrations and verify GREEN**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python manage.py makemigrations accounts
|
||||
python -m pytest apps/accounts/tests/test_bootstrap_governance.py -v
|
||||
```
|
||||
|
||||
Expected: test passes.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/apps/accounts
|
||||
git commit -m "feat: add governance bootstrap models"
|
||||
```
|
||||
|
||||
## Task 2: Backend Auth And Current User APIs
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/config/settings/base.py`
|
||||
- Modify: `backend/config/urls.py`
|
||||
- Create: `backend/apps/accounts/auth.py`
|
||||
- Modify: `backend/apps/accounts/schemas.py`
|
||||
- Modify: `backend/apps/accounts/api.py`
|
||||
- Create: `backend/apps/accounts/tests/test_auth_api.py`
|
||||
|
||||
- [ ] **Step 1: Write failing auth API tests**
|
||||
|
||||
Create `backend/apps/accounts/tests/test_auth_api.py` with tests for:
|
||||
|
||||
```python
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.management import call_command
|
||||
|
||||
|
||||
def test_login_me_and_logout_flow(client, db):
|
||||
call_command("bootstrap_governance")
|
||||
|
||||
login = client.post(
|
||||
"/api/accounts/auth/login",
|
||||
data={"username": "admin", "password": "admin12345"},
|
||||
content_type="application/json",
|
||||
)
|
||||
assert login.status_code == 200
|
||||
assert login.json()["username"] == "admin"
|
||||
|
||||
me = client.get("/api/accounts/auth/me")
|
||||
assert me.status_code == 200
|
||||
payload = me.json()
|
||||
assert payload["username"] == "admin"
|
||||
assert "system.user.manage" in payload["permissions"]
|
||||
assert any(menu["code"] == "system" for menu in payload["menus"])
|
||||
|
||||
logout = client.post("/api/accounts/auth/logout")
|
||||
assert logout.status_code == 200
|
||||
assert client.get("/api/accounts/auth/me").status_code == 401
|
||||
|
||||
|
||||
def test_login_rejects_invalid_password(client, db):
|
||||
get_user_model().objects.create_user(username="u", password="right")
|
||||
|
||||
response = client.post(
|
||||
"/api/accounts/auth/login",
|
||||
data={"username": "u", "password": "wrong"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run tests to verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_auth_api.py -v
|
||||
```
|
||||
|
||||
Expected: fails because auth endpoints do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement session auth endpoints**
|
||||
|
||||
Implement:
|
||||
|
||||
- `GET /api/accounts/auth/csrf`
|
||||
- `POST /api/accounts/auth/login`
|
||||
- `POST /api/accounts/auth/logout`
|
||||
- `GET /api/accounts/auth/me`
|
||||
- `CORS_ALLOW_CREDENTIALS = True`
|
||||
- `CSRF_TRUSTED_ORIGINS` env parsing
|
||||
|
||||
- [ ] **Step 4: Verify GREEN**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_auth_api.py -v
|
||||
```
|
||||
|
||||
Expected: tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/config backend/apps/accounts
|
||||
git commit -m "feat: add session auth api"
|
||||
```
|
||||
|
||||
## Task 3: Backend Governance CRUD APIs
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/apps/accounts/schemas.py`
|
||||
- Modify: `backend/apps/accounts/api.py`
|
||||
- Create: `backend/apps/accounts/tests/test_governance_api.py`
|
||||
|
||||
- [ ] **Step 1: Write failing governance API tests**
|
||||
|
||||
Tests must cover:
|
||||
|
||||
- Admin lists users.
|
||||
- Admin creates a user.
|
||||
- Admin creates a user group and assigns members.
|
||||
- Admin creates a role and assigns permissions.
|
||||
- Admin lists menus and updates one menu permission.
|
||||
- Anonymous calls to governance endpoints return 401.
|
||||
|
||||
- [ ] **Step 2: Run tests to verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_governance_api.py -v
|
||||
```
|
||||
|
||||
Expected: fails because CRUD endpoints do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement schemas and APIs**
|
||||
|
||||
Implement `/api/accounts` endpoints:
|
||||
|
||||
- `/users`
|
||||
- `/users/{id}`
|
||||
- `/users/{id}/reset-password`
|
||||
- `/users/{id}/roles`
|
||||
- `/users/{id}/user-groups`
|
||||
- `/user-groups`
|
||||
- `/user-groups/{id}`
|
||||
- `/user-groups/{id}/members`
|
||||
- `/roles`
|
||||
- `/roles/{id}`
|
||||
- `/roles/{id}/permissions`
|
||||
- `/permissions`
|
||||
- `/menus`
|
||||
- `/menus/{id}`
|
||||
- `/menus/reorder`
|
||||
|
||||
- [ ] **Step 4: Verify GREEN**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_governance_api.py -v
|
||||
```
|
||||
|
||||
Expected: tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/apps/accounts
|
||||
git commit -m "feat: add governance management api"
|
||||
```
|
||||
|
||||
## Task 4: Backend Permission Enforcement
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/apps/accounts/auth.py` if not already created.
|
||||
- Modify: `backend/apps/tickets/api.py`
|
||||
- Modify: `backend/apps/solutions/api.py`
|
||||
- Modify: `backend/apps/audit/api.py`
|
||||
- Modify: existing ticket/solution/audit tests.
|
||||
- Create: `backend/apps/accounts/tests/test_permission_enforcement.py`
|
||||
|
||||
- [ ] **Step 1: Write failing permission enforcement tests**
|
||||
|
||||
Tests must prove:
|
||||
|
||||
- Anonymous ticket list is denied.
|
||||
- User with `ticket.view` can list tickets.
|
||||
- User without `ticket.create` cannot create tickets.
|
||||
- User with `solution.view` can list solutions.
|
||||
- User without `system.audit.view` cannot list audit logs.
|
||||
|
||||
- [ ] **Step 2: Run tests to verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests/test_permission_enforcement.py -v
|
||||
```
|
||||
|
||||
Expected: fails because current APIs are public.
|
||||
|
||||
- [ ] **Step 3: Implement helpers and protect APIs**
|
||||
|
||||
Implement helpers:
|
||||
|
||||
```python
|
||||
require_login(request)
|
||||
require_permission(request, "ticket.view")
|
||||
```
|
||||
|
||||
Update routers:
|
||||
|
||||
- `/api/system/health` remains public.
|
||||
- tickets require ticket permissions.
|
||||
- solutions require solution permissions.
|
||||
- audit requires `system.audit.view`.
|
||||
- governance endpoints use governance permissions.
|
||||
|
||||
- [ ] **Step 4: Update existing tests to authenticate**
|
||||
|
||||
Existing ticket/solution/audit API tests should create a superuser or assign required permissions before calling protected endpoints.
|
||||
|
||||
- [ ] **Step 5: Verify backend API tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/accounts/tests apps/tickets/tests apps/solutions/tests apps/audit/tests -v
|
||||
```
|
||||
|
||||
Expected: tests pass.
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add backend/apps/accounts backend/apps/tickets backend/apps/solutions backend/apps/audit
|
||||
git commit -m "feat: enforce api permissions"
|
||||
```
|
||||
|
||||
## Task 5: Frontend Auth Shell And Permission Menus
|
||||
|
||||
**Files:**
|
||||
- Modify: `frontend/src/lib/api.ts`
|
||||
- Create: `frontend/src/features/auth/types.ts`
|
||||
- Create: `frontend/src/features/auth/api.ts`
|
||||
- Create: `frontend/src/features/auth/AuthProvider.tsx`
|
||||
- Create: `frontend/src/features/auth/LoginPage.tsx`
|
||||
- Modify: `frontend/src/app/App.tsx`
|
||||
- Modify: `frontend/src/app/layout/AppShell.tsx`
|
||||
- Modify: `frontend/src/components/app/AppSidebar.tsx`
|
||||
- Modify: `frontend/src/components/app/AppTopbar.tsx`
|
||||
|
||||
- [ ] **Step 1: Add missing shadcn components**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npx shadcn@latest add alert checkbox switch pagination --yes
|
||||
```
|
||||
|
||||
Then review generated files for Tailwind v3 compatibility.
|
||||
|
||||
- [ ] **Step 2: Implement auth API client and provider**
|
||||
|
||||
Implement:
|
||||
|
||||
- CSRF fetch.
|
||||
- login/logout/me calls.
|
||||
- `AuthProvider`.
|
||||
- `useAuth`.
|
||||
- `apiRequest` sends `credentials: "include"` and CSRF token on unsafe methods.
|
||||
|
||||
- [ ] **Step 3: Implement Chinese login page**
|
||||
|
||||
`LoginPage` uses shadcn `Card`, `Input`, `Label`, `Button`, and `Alert`.
|
||||
|
||||
Visible text must include:
|
||||
|
||||
```text
|
||||
AI 工单平台
|
||||
企业技术支持工作台
|
||||
账号
|
||||
密码
|
||||
登录
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Gate app by auth state**
|
||||
|
||||
Anonymous users see `LoginPage`. Authenticated users see `AppShell` and `Router`.
|
||||
|
||||
- [ ] **Step 5: Make sidebar backend-driven**
|
||||
|
||||
`AppSidebar` receives menu data from auth context. Keep local icon mapping with lucide icons.
|
||||
|
||||
- [ ] **Step 6: Run frontend verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run typecheck
|
||||
npm run build
|
||||
```
|
||||
|
||||
Expected: both pass.
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src frontend/components.json frontend/package.json frontend/package-lock.json
|
||||
git commit -m "feat: add frontend auth shell"
|
||||
```
|
||||
|
||||
## Task 6: Frontend System Governance Pages
|
||||
|
||||
**Files:**
|
||||
- Create: `frontend/src/features/system/types.ts`
|
||||
- Create: `frontend/src/features/system/api.ts`
|
||||
- Create: `frontend/src/features/system/SystemUsersPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemUserGroupsPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemRolesPage.tsx`
|
||||
- Create: `frontend/src/features/system/SystemMenusPage.tsx`
|
||||
- Create: `frontend/src/features/audit/AuditLogPage.tsx`
|
||||
- Modify: `frontend/src/app/router.tsx`
|
||||
|
||||
- [ ] **Step 1: Add system API client**
|
||||
|
||||
Create typed API functions for users, user groups, roles, permissions, menus, and audit logs.
|
||||
|
||||
- [ ] **Step 2: Add users page**
|
||||
|
||||
`#/system/users` shows table columns:
|
||||
|
||||
```text
|
||||
用户名
|
||||
显示名称
|
||||
邮箱
|
||||
状态
|
||||
角色
|
||||
用户组
|
||||
操作
|
||||
```
|
||||
|
||||
Use Dialog or Sheet for create/edit.
|
||||
|
||||
- [ ] **Step 3: Add user groups page**
|
||||
|
||||
`#/system/user-groups` shows Chinese table and create/edit dialog.
|
||||
|
||||
- [ ] **Step 4: Add roles page**
|
||||
|
||||
`#/system/roles` shows role list and permission matrix grouped by module.
|
||||
|
||||
- [ ] **Step 5: Add menus page**
|
||||
|
||||
`#/system/menus` shows menu rows, required permission, visibility/enabled status, and edit dialog.
|
||||
|
||||
- [ ] **Step 6: Add audit page**
|
||||
|
||||
`#/audit` shows existing operation logs in a Chinese table.
|
||||
|
||||
- [ ] **Step 7: Run frontend verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run typecheck
|
||||
npm run build
|
||||
```
|
||||
|
||||
Expected: both pass.
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add frontend/src/features/system frontend/src/features/audit frontend/src/app/router.tsx
|
||||
git commit -m "feat: add system governance pages"
|
||||
```
|
||||
|
||||
## Task 7: Deployment Bootstrap And Final Verification
|
||||
|
||||
**Files:**
|
||||
- Modify: `.env.example`
|
||||
- Create: `infra/backend-entrypoint.sh`
|
||||
- Modify: `infra/backend.Dockerfile`
|
||||
- Modify: `infra/docker-compose.yml`
|
||||
- Modify: `docs/development/local-setup.md`
|
||||
|
||||
- [ ] **Step 1: Add environment defaults**
|
||||
|
||||
Add admin bootstrap env vars to `.env.example`:
|
||||
|
||||
```dotenv
|
||||
DJANGO_SUPERUSER_USERNAME=admin
|
||||
DJANGO_SUPERUSER_PASSWORD=admin12345
|
||||
DJANGO_SUPERUSER_EMAIL=admin@example.com
|
||||
CSRF_TRUSTED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add backend entrypoint**
|
||||
|
||||
Create `infra/backend-entrypoint.sh`:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
python manage.py migrate
|
||||
python manage.py bootstrap_governance
|
||||
exec "$@"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Wire backend Dockerfile and compose**
|
||||
|
||||
Backend service uses the entrypoint before running `runserver`. Worker can still start Celery after migrations are handled by backend.
|
||||
|
||||
- [ ] **Step 4: Update setup docs**
|
||||
|
||||
Document:
|
||||
|
||||
- fresh Docker startup
|
||||
- default login account
|
||||
- production warning to override password
|
||||
|
||||
- [ ] **Step 5: Run full verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest -v
|
||||
python -m ruff check .
|
||||
|
||||
cd ../frontend
|
||||
npm run typecheck
|
||||
npm run build
|
||||
npx shadcn@latest info
|
||||
```
|
||||
|
||||
Expected: all commands pass.
|
||||
|
||||
- [ ] **Step 6: Verify compose config**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd infra
|
||||
docker compose --env-file ../.env.example config
|
||||
```
|
||||
|
||||
Expected: config prints without errors. On this Windows host, use Docker Desktop's full docker executable path if `docker` is unavailable in shell PATH.
|
||||
|
||||
- [ ] **Step 7: Browser smoke test**
|
||||
|
||||
Start backend and frontend locally if feasible, then verify:
|
||||
|
||||
- anonymous user sees login page
|
||||
- admin can log in
|
||||
- sidebar shows system governance menus
|
||||
- `#/system/users`, `#/system/roles`, `#/system/menus`, `#/audit` render Chinese UI
|
||||
- logout returns to login
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add .env.example infra docs/development
|
||||
git commit -m "feat: add governance deployment bootstrap"
|
||||
```
|
||||
|
||||
## Final Review Checklist
|
||||
|
||||
- [ ] `bootstrap_governance` is idempotent.
|
||||
- [ ] Login/logout/me APIs work.
|
||||
- [ ] Frontend anonymous state shows login only.
|
||||
- [ ] Sidebar menus are backend-driven.
|
||||
- [ ] User/user-group/role/menu pages use shadcn/App components.
|
||||
- [ ] Ticket/solution/audit/governance APIs enforce permissions.
|
||||
- [ ] Docker startup can migrate and seed governance.
|
||||
- [ ] Backend tests pass.
|
||||
- [ ] Backend ruff passes.
|
||||
- [ ] Frontend typecheck passes.
|
||||
- [ ] Frontend build passes.
|
||||
- [ ] shadcn info still reports Vite/Tailwind v3 and installed components.
|
||||
Reference in New Issue
Block a user