docs: add stage 1.6 enterprise governance plan

This commit is contained in:
hailin
2026-07-01 14:02:26 +08:00
parent e0019de362
commit ee9aad6a02

View File

@@ -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.