docs: add stage 1.6 enterprise governance design

This commit is contained in:
hailin
2026-07-01 13:59:25 +08:00
parent 5f558832f1
commit e0019de362
2 changed files with 481 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ The product contains multiple independent subsystems. Do not implement the entir
| 0 | Foundation and design system | Create the repo skeleton, local runtime, auth/RBAC baseline, audit baseline, frontend theme and component standards. | None | `docs/superpowers/plans/2026-06-30-stage-0-foundation-design-system.md` |
| 1 | Ticket workflow and reusable solutions | Implement ticket lifecycle, comments, attachments, events, export, solution library, and solution links. | Stage 0 | Create after Stage 0 passes. |
| 1.5 | shadcn enterprise UI foundation | Formalize shadcn/ui initialization, add a project-owned App component layer, redesign current ticket and solution pages, and enforce Chinese frontend text. | Stage 1 | `docs/superpowers/specs/2026-07-01-stage-1-5-shadcn-ui-foundation-design.md` |
| 1.6 | Enterprise governance and login | Add login/logout/current-user APIs, user/user-group/role/menu management, API permission enforcement, permission-driven frontend menus, and deployment bootstrap. | Stage 1.5 | `docs/superpowers/specs/2026-07-01-stage-1-6-enterprise-governance-design.md` |
| 2 | Knowledge base and vector retrieval | Implement knowledge bases, documents, parsing jobs, chunks, embeddings, and retrieval. | Stage 0, partial Stage 1 | Create after Stage 1 model contracts stabilize. |
| 3 | Model gateway and Agent/Skill runtime | Implement provider configs, model configs, model testing, Skill configs, built-in Agents, runs, steps, AI artifacts. | Stage 0, Stage 1, Stage 2 retrieval interfaces | Create after Stage 2 retrieval contracts exist. |
| 4 | MCP tools and trust boundary | Implement MCP server registration, tool sync, risk levels, Agent tool binding, tool calls, confirmation, audit. | Stage 3 | Create after Agent runtime exists. |

View File

@@ -0,0 +1,480 @@
# Stage 1.6 Enterprise Governance Design
## Background
Stage 0 established an RBAC seed baseline with Django's built-in `User`, `Group`, and `Permission` models. Stage 1 added ticket and solution workflows. Stage 1.5 formalized shadcn/ui and created the enterprise admin UI base.
The current governance capability is still incomplete for an enterprise product:
- No frontend login or logout flow.
- No current-user API for frontend permission and menu rendering.
- No user management page.
- No user group management page.
- No role and permission management page.
- No menu permission management page.
- No API-level permission enforcement policy across ticket, solution, audit, and system governance APIs.
- Docker deployment does not yet run a full governance bootstrap for default admin, roles, permissions, and menus.
Stage 1.6 fills this gap before Stage 2 knowledge base and later Agent/model/MCP modules. Those later modules must not be built on top of anonymous APIs and hard-coded menus.
## Decision
Create a dedicated Stage 1.6 after Stage 1.5:
```text
Stage 0 = project skeleton + RBAC seed baseline
Stage 1 = ticket workflow and solution library
Stage 1.5 = shadcn enterprise UI foundation
Stage 1.6 = login + users + user groups + roles + menus + permission enforcement
Stage 2 = knowledge base and vector retrieval
```
Stage 1.6 is a frontend and backend stage. It must use the current shadcn/ui component base for all frontend governance pages.
## Goals
1. Add login, logout, and current-user APIs.
2. Add frontend login experience and authenticated application shell.
3. Add backend CRUD APIs for users, user groups, roles, permissions, and menus.
4. Add frontend system governance pages using shadcn components.
5. Add menu permission data so frontend navigation is driven by backend permission results instead of hard-coded public menus.
6. Add API permission checks for ticket, solution, audit, and governance endpoints.
7. Add deployment bootstrap so a fresh Docker environment can create default admin, permissions, roles, user groups, and menus.
## Non-Goals
- No SSO, LDAP, SAML, OAuth, enterprise WeChat, or DingTalk login.
- No multi-tenant model.
- No organization tree or department hierarchy.
- No row-level data permission.
- No field-level permission.
- No approval workflow.
- No password complexity policy beyond Django's baseline validation.
- No MFA.
- No public self-registration.
- No Stage 2 knowledge base, model gateway, Agent, Skill, or MCP implementation.
## Terminology
| Product Term | Backend Representation | Notes |
|---|---|---|
| 用户 | Django `User` | Use Django's built-in user model for Stage 1.6. |
| 角色 | Django `Group` | Product UI calls it "角色"; backend reuses Django Group permissions. |
| 权限点 | Django `Permission` | Seeded by catalog. Canonical business code is like `ticket.view`. |
| 用户组 | New `UserGroup` model | Business grouping independent from permission roles. |
| 菜单权限 | New `MenuItem` model + permission code | Menus can require a permission code and are returned from `/me`. |
| 按钮/操作权限 | Permission codenames | Frontend hides actions; backend still enforces. |
## Backend Design
### Authentication
Use Django session authentication for Stage 1.6.
Required endpoints under `/api/accounts/auth`:
| Method | Path | Purpose |
|---|---|---|
| `GET` | `/csrf` | Set CSRF cookie for SPA login requests. |
| `POST` | `/login` | Validate username/password and create Django session. |
| `POST` | `/logout` | Clear current session. |
| `GET` | `/me` | Return current user, roles, groups, permissions, and authorized menu tree. |
Cross-origin local development must support session cookies:
- Backend enables `CORS_ALLOW_CREDENTIALS = True`.
- Backend configures `CSRF_TRUSTED_ORIGINS` from env.
- Frontend API client sends `credentials: "include"`.
- Login flow fetches CSRF before posting credentials.
### Data Models
Add models to `backend/apps/accounts/models.py`.
#### UserGroup
Business user group separate from role permissions:
| Field | Type | Notes |
|---|---|---|
| `name` | varchar unique | Chinese display name. |
| `code` | varchar unique | Stable code for integration and seeding. |
| `description` | text blank | Optional description. |
| `users` | many-to-many `User` | Group members. |
| `is_active` | boolean | Disabled groups are not shown in normal assignment. |
| `created_at` / `updated_at` | datetime | Audit-friendly timestamps. |
#### MenuItem
Backend-driven menu definition:
| Field | Type | Notes |
|---|---|---|
| `code` | varchar unique | Stable menu code. |
| `title` | varchar | Chinese title. |
| `path` | varchar blank | Frontend hash route, such as `#/tickets`. |
| `icon` | varchar blank | Frontend icon key understood by AppSidebar. |
| `parent` | FK self nullable | Supports menu tree. |
| `sort_order` | int | Ordering inside parent. |
| `permission_code` | varchar blank | Business permission code required to see the menu. |
| `is_visible` | boolean | Hidden menus can still exist for permissions. |
| `is_enabled` | boolean | Disabled menus are excluded. |
| `created_at` / `updated_at` | datetime | Audit-friendly timestamps. |
Roles continue to use Django `Group`. Permissions continue to use Django `Permission`.
### Permission Catalog
Extend the permission catalog with Chinese names and governance permissions.
Required governance permission codes:
```text
system.user.view
system.user.manage
system.user_group.view
system.user_group.manage
system.role.view
system.role.manage
system.menu.view
system.menu.manage
system.audit.view
system.setting.manage
```
Existing business permissions remain:
```text
ticket.view
ticket.create
ticket.edit
ticket.export
ticket.assign
ticket.close
solution.view
solution.manage
knowledge.view
knowledge.manage
agent.use
agent.manage
model.manage
tool.manage
```
When checking permissions through Django, use `system.<business_code>` because the seeded permission content type uses app label `system`.
Example:
```python
request.user.has_perm("system.ticket.view")
```
### Seed And Bootstrap
Stage 1.6 should add a single bootstrap command that is safe to run repeatedly:
```bash
python manage.py bootstrap_governance
```
The command must:
1. Seed permissions.
2. Seed default roles.
3. Seed default user groups.
4. Seed default menus.
5. Create or update a default admin user from env vars.
Recommended env vars:
```dotenv
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_PASSWORD=admin12345
DJANGO_SUPERUSER_EMAIL=admin@example.com
```
Default roles:
| Role | Meaning |
|---|---|
| 系统管理员 | All permissions. |
| 知识库管理员 | Knowledge and solution management. |
| 技术支持 | Ticket handling and Agent usage. |
| 普通建单人 | Create/view own relevant tickets first; broad row-level ownership is deferred. |
| 只读审计员 | View tickets, solutions, knowledge, and audit logs. |
Default menus:
```text
工作台
运营总览
业务处理
工单中心
创建工单
解决方案库
平台能力
知识库
Agent 配置
模型与工具
系统治理
用户管理
用户组管理
角色权限
菜单权限
操作审计
设计系统
```
Menus for future modules may be seeded but hidden or disabled until their stage is implemented.
### Governance APIs
Add APIs under `/api/accounts`.
#### Current User
`GET /api/accounts/auth/me` returns:
```json
{
"id": 1,
"username": "admin",
"display_name": "系统管理员",
"email": "admin@example.com",
"is_superuser": true,
"roles": [{"id": 1, "name": "系统管理员"}],
"user_groups": [{"id": 1, "name": "默认用户组", "code": "default"}],
"permissions": ["ticket.view", "system.user.manage"],
"menus": [
{
"code": "workbench",
"title": "工作台",
"path": "",
"icon": "home",
"children": []
}
]
}
```
#### User APIs
| Method | Path | Permission |
|---|---|---|
| `GET` | `/users` | `system.user.view` |
| `POST` | `/users` | `system.user.manage` |
| `GET` | `/users/{id}` | `system.user.view` |
| `PATCH` | `/users/{id}` | `system.user.manage` |
| `POST` | `/users/{id}/reset-password` | `system.user.manage` |
| `POST` | `/users/{id}/roles` | `system.user.manage` |
| `POST` | `/users/{id}/user-groups` | `system.user.manage` |
#### User Group APIs
| Method | Path | Permission |
|---|---|---|
| `GET` | `/user-groups` | `system.user_group.view` |
| `POST` | `/user-groups` | `system.user_group.manage` |
| `PATCH` | `/user-groups/{id}` | `system.user_group.manage` |
| `POST` | `/user-groups/{id}/members` | `system.user_group.manage` |
#### Role And Permission APIs
| Method | Path | Permission |
|---|---|---|
| `GET` | `/roles` | `system.role.view` |
| `POST` | `/roles` | `system.role.manage` |
| `PATCH` | `/roles/{id}` | `system.role.manage` |
| `POST` | `/roles/{id}/permissions` | `system.role.manage` |
| `GET` | `/permissions` | `system.role.view` |
#### Menu APIs
| Method | Path | Permission |
|---|---|---|
| `GET` | `/menus` | `system.menu.view` |
| `POST` | `/menus` | `system.menu.manage` |
| `PATCH` | `/menus/{id}` | `system.menu.manage` |
| `POST` | `/menus/reorder` | `system.menu.manage` |
### API Permission Enforcement
Add a small accounts permission helper:
```text
require_login(request)
require_permission(request, "ticket.view")
```
Enforcement rules:
- `/api/system/health` remains public.
- `/api/accounts/auth/csrf` and `/api/accounts/auth/login` remain public.
- `/api/accounts/auth/me` requires login.
- Audit log list requires `system.audit.view`.
- Ticket list/detail/export require `ticket.view`.
- Ticket create requires `ticket.create`.
- Ticket update/status/comment/attachment operations require the closest ticket operation permission.
- Solution list/detail require `solution.view`.
- Solution create/link requires `solution.manage`.
Frontend hiding is not security. Backend permission checks are mandatory for all protected operations.
## Frontend Design
### Auth Flow
Add frontend auth state:
```text
AuthProvider
├─ load /api/accounts/auth/me
├─ login(username, password)
├─ logout()
└─ exposes user, permissions, menus, loading, authenticated
```
Application flow:
```text
Unauthenticated → LoginPage
Authenticated → AppShell + Router
```
The login page must use shadcn components and Chinese text:
- `Card`
- `Input`
- `Button`
- `Alert`
- `Label` or shadcn `Field` if installed
### API Client
Update `frontend/src/lib/api.ts`:
- Send `credentials: "include"`.
- Include CSRF token for unsafe methods.
- Convert `401` into an auth state transition.
- Keep error messages Chinese where shown to users.
### Sidebar Menus
`AppSidebar` should no longer own the final hard-coded menu list. It should consume menu data from `AuthProvider`.
Rules:
- Backend returns only menus the user can see.
- Frontend still handles unknown future paths with disabled or placeholder behavior.
- Icon mapping is local and controlled, using lucide-react icons.
- All menu text is Chinese.
### Governance Pages
Add a new feature module:
```text
frontend/src/features/system/
```
Required pages:
| Route | Page | Purpose |
|---|---|---|
| `#/system/users` | 用户管理 | List, create, edit active state, assign roles and user groups, reset password. |
| `#/system/user-groups` | 用户组管理 | List/create/edit business user groups and members. |
| `#/system/roles` | 角色权限 | List/create/edit roles and assign permissions. |
| `#/system/menus` | 菜单权限 | View/edit menu tree, menu metadata, and required permission. |
| `#/audit` | 操作审计 | Reuse existing audit API with protected access. |
Required shadcn components:
- Existing Stage 1.5 components: `button`, `badge`, `card`, `input`, `textarea`, `select`, `label`, `separator`, `sidebar`, `breadcrumb`, `dropdown-menu`, `table`, `tabs`, `sheet`, `dialog`, `tooltip`, `skeleton`, `sonner`.
- Add if not installed: `checkbox`, `switch`, `alert`, `empty`, `pagination`.
Project App components should remain the page-level API:
- `AppDataTable`
- `AppFilterBar`
- `AppPageHeader`
- `AppSection`
- `AppEmptyState`
- system-specific wrappers if useful, such as `PermissionMatrix` and `RolePermissionEditor`.
### Page Experience
The governance UI should feel like an enterprise admin console, not a demo:
- Dense tables with Chinese column names.
- Dialog or Sheet for create/edit.
- Permission assignment grouped by module.
- Clear active/disabled status badges.
- Empty states in Chinese.
- Loading skeletons for initial data fetch.
- Toast feedback via `sonner`.
## Deployment Initialization
Docker/local startup should support a fresh database:
```text
backend startup:
python manage.py migrate
python manage.py bootstrap_governance
python manage.py runserver 0.0.0.0:8000
```
The exact startup implementation can be an entrypoint script or documented command. The important requirement is that a new developer can bring up Docker Compose and log in with the seeded admin account after migrations finish.
## Security Notes
- Default admin password is acceptable only for local/dev. Production deployments must override env vars.
- Backend permission checks are the source of truth.
- Superusers bypass permission assignment checks through Django's built-in behavior, but `/me` should still return all business permission codes.
- Passwords are never returned in API responses.
- User deletion should not be implemented in Stage 1.6; use deactivate instead.
## Testing Requirements
Backend tests:
- Login succeeds with seeded admin.
- `/me` returns user, roles, permissions, and filtered menus.
- Anonymous access to protected endpoints returns 401 or 403.
- Permissioned users can access allowed endpoints.
- Users without permissions are denied.
- User CRUD, role permission assignment, user group membership, and menu update APIs work.
- Bootstrap command is idempotent.
Frontend verification:
- `npm run typecheck`
- `npm run build`
- Browser smoke test:
- anonymous user sees login page
- seeded admin can log in
- system governance menus appear
- user/role/menu pages render Chinese UI
- logout returns to login
Full project verification:
```bash
cd backend
python -m pytest -v
python -m ruff check .
cd frontend
npm run typecheck
npm run build
```
## Acceptance Criteria
- Fresh deployment can create database schema, seed governance data, and log in with the configured admin account.
- Frontend is no longer usable as an anonymous public app except for the login page.
- Sidebar menus come from backend-authorized menu data.
- Users, user groups, roles, permissions, and menus are manageable from Chinese frontend pages.
- Backend enforces permissions for ticket, solution, audit, and governance APIs.
- Frontend uses shadcn/ui primitives and project App components for all new governance UI.
- No Stage 2 knowledge base or AI platform features are implemented in this stage.