|
1 | 1 | # AgentOps Dashboard Framework v0.1 |
2 | 2 |
|
3 | | -A reusable dashboard framework for: |
4 | | -- Ticket workflow visibility |
5 | | -- Agent run/artifact tracking |
6 | | -- Approval gate + audit logs |
7 | | -- RBAC (Admin/Member) |
| 3 | +A reusable full-stack dashboard framework for ticket workflow management, run tracking, audit logging, and role-based access control. |
| 4 | + |
| 5 | +## What is included |
| 6 | + |
| 7 | +- **Dashboard API**: FastAPI + SQLAlchemy + Alembic. |
| 8 | +- **Dashboard Web**: Next.js app router frontend. |
| 9 | +- **Local infrastructure**: PostgreSQL via Docker Compose. |
| 10 | +- **Developer scripts**: bootstrap, seed, and one-command local startup. |
8 | 11 |
|
9 | 12 | ## Repository structure |
10 | | -- `apps/dashboard_api/`: FastAPI + SQLAlchemy + Alembic |
11 | | -- `apps/dashboard_web/`: Next.js dashboard UI |
12 | | -- `infra/docker-compose.yml`: Postgres for local development |
13 | 13 |
|
14 | | -## Business Logic Overview |
| 14 | +- `apps/dashboard_api/` — backend service. |
| 15 | +- `apps/dashboard_web/` — frontend service. |
| 16 | +- `infra/docker-compose.yml` — local PostgreSQL. |
| 17 | +- `scripts/` — development utilities. |
| 18 | +- `docs/` — install and RBAC notes. |
| 19 | + |
| 20 | +## Core business flow |
15 | 21 |
|
16 | 22 | ### Tickets |
17 | | -- Tickets are created with metadata (`type`, `priority`, `assigned_agent`) and enter `PENDING_APPROVAL` by default. |
18 | | -- Members and Admins can list tickets; Admins can operate full lifecycle transitions (`approve/reject/queue`). |
19 | | -- Editing rules are permission-aware (`PUT /tickets/{id}` and `POST /tickets/{id}/update`) and validated by the backend. |
| 23 | + |
| 24 | +- Tickets are created with metadata like `type`, `priority`, and `assigned_agent`. |
| 25 | +- New tickets default to `PENDING_APPROVAL`. |
| 26 | +- Admin users can approve/reject/queue tickets. |
| 27 | +- `PUT /tickets/{id}` and `POST /tickets/{id}/update` support editing with permission checks. |
20 | 28 |
|
21 | 29 | ### Runs |
22 | | -- Runs are admin-driven execution records. |
23 | | -- Admin can start next run (`POST /runs/next`) and finish a run (`POST /runs/{id}/finish`). |
24 | | -- Status transitions are constrained to valid lifecycle paths; invalid transitions return `409`. |
| 30 | + |
| 31 | +- Admin can start execution from queued tickets via `POST /runs/next`. |
| 32 | +- Admin can finish runs via `POST /runs/{id}/finish` with status `DONE` or `FAILED`. |
| 33 | +- Ticket status transitions follow lifecycle constraints (`QUEUED -> RUNNING -> DONE/FAILED`). |
25 | 34 |
|
26 | 35 | ### Agents |
27 | | -- Agents are managed as available executors for ticket assignment. |
28 | | -- Agent CRUD (`/agents`) is admin-only at API layer. |
29 | | -- Web UI mirrors this by showing management actions only for admin role, while backend still enforces final authorization. |
30 | | - |
31 | | -### Auth, Permissions, and Token flow (Dashboard Web + API) |
32 | | -1. **Backend authorization is the source of truth** |
33 | | - - API only trusts `Authorization: Bearer <token>`. |
34 | | - - `ADMIN_TOKEN` maps to Admin; `MEMBER_TOKEN` maps to Member. |
35 | | - - Frontend permission UI is only UX gating. Final enforcement comes from backend `401/403`. |
36 | | - |
37 | | -2. **Frontend login and local state** |
38 | | - - Built-in dev credentials: `admin/admin` and `member/member`. |
39 | | - - On login, frontend stores: |
40 | | - - `localStorage.dashboard_token` |
41 | | - - `localStorage.dashboard_username` |
42 | | - - UI role checks prefer username first, then fallback to token comparison. |
43 | | - |
44 | | -3. **`NEXT_PUBLIC_MEMBER_TOKEN` alignment matters** |
45 | | - - `NEXT_PUBLIC_*` variables are exposed to browser and should only hold dev/demo tokens. |
46 | | - - If backend `MEMBER_TOKEN` changes, frontend `NEXT_PUBLIC_MEMBER_TOKEN` must be updated too. |
47 | | - - Otherwise member login may receive `401 Invalid token`. |
48 | | - |
49 | | -4. **Local verification examples** |
50 | | -```bash |
51 | | -curl -H "Authorization: Bearer ${ADMIN_TOKEN:-admin-dev-token}" http://localhost:8000/tickets |
52 | | -curl -H "Authorization: Bearer ${MEMBER_TOKEN:-member-dev-token}" http://localhost:8000/tickets |
53 | | -``` |
| 36 | + |
| 37 | +- Agents are assignable executors for tickets. |
| 38 | +- Agent CRUD endpoints are admin-only (`/agents`). |
| 39 | +- Deletion is blocked if an agent is already referenced by tickets. |
| 40 | + |
| 41 | +### Audit logs |
| 42 | + |
| 43 | +- Key actions (ticket/agent/run operations) are written to audit logs. |
| 44 | +- Audit listing endpoint (`GET /audit-logs`) is admin-only. |
| 45 | + |
| 46 | +## Auth and permission model |
| 47 | + |
| 48 | +- Backend authorization is the source of truth. |
| 49 | +- API expects `Authorization: Bearer <token>`. |
| 50 | +- `ADMIN_TOKEN` maps to Admin, `MEMBER_TOKEN` maps to Member. |
| 51 | +- Frontend role-based UI is for UX only; backend still enforces `401/403`. |
| 52 | + |
| 53 | +### Dev login in web UI |
| 54 | + |
| 55 | +- Built-in credentials: |
| 56 | + - `admin / admin` |
| 57 | + - `member / member` |
| 58 | +- Frontend stores: |
| 59 | + - `localStorage.dashboard_token` |
| 60 | + - `localStorage.dashboard_username` |
| 61 | + |
| 62 | +### Token alignment note |
| 63 | + |
| 64 | +If you change backend token values in `.env`, ensure frontend `NEXT_PUBLIC_*` token variables are aligned as well. |
54 | 65 |
|
55 | 66 | ## Quickstart |
56 | 67 |
|
57 | | -### Option 1: Use start script (recommended) |
| 68 | +### Option 1 (recommended): one command |
| 69 | + |
58 | 70 | ```bash |
59 | | -# One command starts DB bootstrap + API + Web |
60 | 71 | ./scripts/start_dev.sh |
61 | 72 | ``` |
62 | 73 |
|
63 | | -Services: |
64 | | -- API: http://localhost:8000 |
65 | | -- Web: http://localhost:3000 |
| 74 | +By default, this script: |
| 75 | + |
| 76 | +1. Runs DB bootstrap (wait + migration + seed). |
| 77 | +2. Ensures frontend dependencies are installed. |
| 78 | +3. Starts API on `http://localhost:8000`. |
| 79 | +4. Starts Web on `http://localhost:3000`. |
| 80 | + |
| 81 | +### Option 2: manual startup |
66 | 82 |
|
67 | | -### Option 2: Manual start |
| 83 | +1. Start PostgreSQL: |
68 | 84 |
|
69 | | -1. Start database |
70 | 85 | ```bash |
71 | 86 | docker compose -f infra/docker-compose.yml up -d |
72 | 87 | ``` |
73 | 88 |
|
74 | | -2. Install API dependencies and setup env |
| 89 | +2. Prepare Python env: |
| 90 | + |
75 | 91 | ```bash |
76 | 92 | python -m venv .venv |
77 | 93 | source .venv/bin/activate |
78 | 94 | pip install -r requirements.txt |
79 | 95 | cp .env.example .env |
80 | 96 | ``` |
81 | 97 |
|
82 | | -3. Run bootstrap (DB wait + migrations + seed) |
| 98 | +3. Bootstrap DB + migrations + seed: |
| 99 | + |
83 | 100 | ```bash |
84 | 101 | ./scripts/dev_bootstrap.sh |
85 | 102 | ``` |
86 | 103 |
|
87 | | -4. Start API |
| 104 | +4. Start API: |
| 105 | + |
88 | 106 | ```bash |
89 | 107 | cd apps/dashboard_api |
90 | 108 | PYTHONPATH=. uvicorn src.main:app --reload --port 8000 |
91 | 109 | ``` |
92 | 110 |
|
93 | | -5. Start Web |
| 111 | +5. Start Web: |
| 112 | + |
94 | 113 | ```bash |
95 | 114 | cd apps/dashboard_web |
96 | 115 | npm install |
97 | 116 | npm run dev |
98 | 117 | ``` |
99 | 118 |
|
| 119 | +## Environment variables |
100 | 120 |
|
101 | | -## CI (GitHub Actions) |
102 | | - |
103 | | -A concise CI pipeline is provided at `.github/workflows/ci.yml`: |
104 | | -- **api-tests**: installs Python dependencies and runs API smoke tests (`pytest`). |
105 | | -- **web-build**: installs Node dependencies and runs `next build` to verify web service health. |
106 | | - |
107 | | -Trigger strategy: |
108 | | -- `pull_request`: run checks before merge. |
109 | | -- `push` to `main`: run checks after each merge. |
110 | | -- `workflow_dispatch`: allow manual reruns when needed. |
| 121 | +From `.env.example`: |
111 | 122 |
|
112 | | -Reliability tweaks: |
113 | | -- **concurrency cancellation**: automatically cancels outdated runs on the same ref. |
114 | | -- **timeout guards**: each job has a 10-minute timeout. |
| 123 | +- `DATABASE_URL` |
| 124 | +- `ADMIN_TOKEN` |
| 125 | +- `MEMBER_TOKEN` |
| 126 | +- `NEXT_PUBLIC_API_URL` |
| 127 | +- `NEXT_PUBLIC_ADMIN_TOKEN` |
115 | 128 |
|
116 | | -Run API tests locally: |
117 | | -```bash |
118 | | -PYTHONPATH=apps/dashboard_api pytest -q apps/dashboard_api/tests |
119 | | -``` |
| 129 | +Frontend also supports `NEXT_PUBLIC_MEMBER_TOKEN` (defaults to `member-dev-token` when unset). |
120 | 130 |
|
121 | | -## Chinese README |
122 | | -- 中文说明请查看:`README.zh-CN.md` |
| 131 | +## API smoke checks |
123 | 132 |
|
124 | | -## INSTALL / RBAC docs |
125 | | -- Detailed install: `docs/INSTALL.md` |
126 | | -- RBAC details: `docs/RBAC.md` |
127 | | - |
128 | | -## API checks |
129 | 133 | ```bash |
130 | 134 | curl http://localhost:8000/health |
131 | 135 | curl -H "Authorization: Bearer member-dev-token" http://localhost:8000/tickets |
| 136 | +curl -H "Authorization: Bearer admin-dev-token" http://localhost:8000/runs |
132 | 137 | curl -X POST -H "Authorization: Bearer admin-dev-token" http://localhost:8000/tickets/1/approve |
133 | 138 | ``` |
134 | 139 |
|
135 | | -<img width="1274" height="827" alt="image" src="https://github.com/user-attachments/assets/b4dba5dd-99df-4064-86fb-cc665564eb4a" /> |
| 140 | +## Tests |
136 | 141 |
|
137 | | -## 权限与 Token 业务逻辑(Dashboard Web + API) |
| 142 | +Run API tests locally: |
138 | 143 |
|
139 | | -### 1) 后端鉴权是唯一权限来源 |
140 | | -- API 只认 `Authorization: Bearer <token>`。 |
141 | | -- `ADMIN_TOKEN` 映射为 Admin,`MEMBER_TOKEN` 映射为 Member。 |
142 | | -- 前端页面上的「是否可操作」仅用于 UX 提示;真正权限由后端 `401/403` 决定。 |
| 144 | +```bash |
| 145 | +PYTHONPATH=apps/dashboard_api pytest -q apps/dashboard_api/tests |
| 146 | +``` |
143 | 147 |
|
144 | | -### 2) 前端登录与本地状态 |
145 | | -- 登录页内置两组开发账号:`admin/admin` 与 `member/member`。 |
146 | | -- 登录成功后,前端会把 token 和 username 写入 `localStorage`: |
147 | | - - `dashboard_token` |
148 | | - - `dashboard_username` |
149 | | -- 页面判断是否 Admin 时,优先使用 `dashboard_username`(避免仅靠 token 字符串比较带来的误判);如果 username 缺失,再回退到 token 对比。 |
| 148 | +## CI |
150 | 149 |
|
151 | | -### 3) `NEXT_PUBLIC_MEMBER_TOKEN` 的配置要点 |
152 | | -- `NEXT_PUBLIC_*` 变量会暴露到浏览器,只应放开发/演示 token。 |
153 | | -- 若后端改了 `MEMBER_TOKEN`,前端也必须同步 `NEXT_PUBLIC_MEMBER_TOKEN`,否则 member 登录会拿到错误 token 并返回 `401 Invalid token`。 |
154 | | -- 默认开发值: |
155 | | - - Admin: `admin-dev-token` |
156 | | - - Member: `member-dev-token` |
| 150 | +CI workflow: `.github/workflows/ci.yml` |
157 | 151 |
|
158 | | -### 4) 推荐的本地联调检查 |
159 | | -```bash |
160 | | -curl -H "Authorization: Bearer ${ADMIN_TOKEN:-admin-dev-token}" http://localhost:8000/tickets |
161 | | -curl -H "Authorization: Bearer ${MEMBER_TOKEN:-member-dev-token}" http://localhost:8000/tickets |
162 | | -``` |
| 152 | +- `api-tests`: runs backend tests. |
| 153 | +- `web-build`: runs frontend build check. |
| 154 | + |
| 155 | +Triggers: |
163 | 156 |
|
164 | | -## INSTALL / RBAC docs |
165 | | -- 详细安装:`docs/INSTALL.md` |
166 | | -- 权限说明:`docs/RBAC.md` |
| 157 | +- Pull requests |
| 158 | +- Push to `main` |
| 159 | +- Manual dispatch |
167 | 160 |
|
168 | 161 | ## Troubleshooting |
169 | 162 |
|
170 | | -### Restart services |
171 | | -The script handles DB bootstrap and starts API/Web in one command. Use it to restart local dev stack: |
| 163 | +### Restart with script |
| 164 | + |
172 | 165 | ```bash |
173 | 166 | ./scripts/start_dev.sh |
174 | 167 | ``` |
175 | 168 |
|
176 | | -### Restart services manually |
177 | | -```bash |
178 | | -# Stop existing processes |
179 | | -pkill -f "uvicorn src.main:app" && pkill -f "next dev" |
180 | | - |
181 | | -# Start services |
182 | | -cd apps/dashboard_api && python3 -m uvicorn src.main:app --host 0.0.0.0 --port 8000 --reload & |
183 | | -cd apps/dashboard_web && npm run dev & |
184 | | -``` |
| 169 | +### Detach mode |
185 | 170 |
|
186 | | -### View API logs |
187 | 171 | ```bash |
188 | | -# Check log file |
189 | | -tail -f /tmp/agentops_api.log |
190 | | - |
191 | | -# Or use the process tool |
192 | | -process action=list |
193 | | -process action=log sessionId=<session-id> |
| 172 | +./scripts/start_dev.sh --detach |
194 | 173 | ``` |
195 | 174 |
|
196 | | -### View Web logs |
| 175 | +### Logs |
| 176 | + |
197 | 177 | ```bash |
| 178 | +tail -f /tmp/agentops_api.log |
198 | 179 | tail -f /tmp/agentops_web.log |
199 | 180 | ``` |
200 | 181 |
|
201 | 182 | ### Common issues |
202 | | -- **404 Not Found**: Check whether API has restarted and whether new routes are loaded (run `./scripts/start_dev.sh` to restart). |
203 | | -- **401 Unauthorized**: Check whether the token is correct (default: `admin-dev-token` / `member-dev-token`). |
204 | | -- **Database connection failed**: Confirm PostgreSQL container is running with `docker ps`. |
| 183 | + |
| 184 | +- **401 Unauthorized**: verify token values and frontend/backend token alignment. |
| 185 | +- **409 Conflict**: check whether status transition is valid. |
| 186 | +- **DB connection failure**: verify PostgreSQL container is running (`docker ps`). |
| 187 | + |
| 188 | +## Additional docs |
| 189 | + |
| 190 | +- Chinese README: `README.zh-CN.md` |
| 191 | +- Install guide: `docs/INSTALL.md` |
| 192 | +- RBAC details: `docs/RBAC.md` |
0 commit comments