Add Groups management and split Admin navigation
- New backend: Group + GroupMembership models, schemas, CRUD router at /api/admin/groups (list, create, get detail, update, delete, add/remove members) - New Alembic migration: groups and group_memberships tables - Frontend: Admin sidebar item is now an expandable accordion with Users and Groups sub-items; AdminPage redirects to /admin/users; new AdminUsersPage and AdminGroupsPage with inline member management panel - API client: 7 new group functions + TypeScript types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -40,6 +40,18 @@ JWT signing uses a 4096-bit RSA key pair (`RS256`). Keys are generated by `scrip
|
||||
| `GET` | `/api/admin/users` | List all users (admin only) |
|
||||
| `PATCH` | `/api/admin/users/{id}` | Update user (role, active flag) |
|
||||
|
||||
### Groups (`/api/admin/groups`)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| `GET` | `/api/admin/groups` | List all groups with member count |
|
||||
| `POST` | `/api/admin/groups` | Create a new group |
|
||||
| `GET` | `/api/admin/groups/{id}` | Get group detail with member list |
|
||||
| `PATCH` | `/api/admin/groups/{id}` | Update group name / description |
|
||||
| `DELETE` | `/api/admin/groups/{id}` | Delete group (cascades memberships) |
|
||||
| `POST` | `/api/admin/groups/{id}/members/{user_id}` | Add user to group |
|
||||
| `DELETE` | `/api/admin/groups/{id}/members/{user_id}` | Remove user from group |
|
||||
|
||||
### Services (`/api/services`)
|
||||
|
||||
| Method | Path | Description |
|
||||
@@ -74,6 +86,8 @@ All `/api/documents/*` and `/api/documents/categories/*` requests are transparen
|
||||
|-------|-------|-------|
|
||||
| `User` | `users` | email, hashed_password, role (`user`\|`admin`), is_active |
|
||||
| `Profile` | `profiles` | one-to-one with User; full_name, phone, etc. |
|
||||
| `Group` | `groups` | name (unique), description, created_at |
|
||||
| `GroupMembership` | `group_memberships` | group_id + user_id (unique pair); joined_at |
|
||||
|
||||
Alembic migrations in `backend/alembic/versions/` — version table: `alembic_version`.
|
||||
|
||||
@@ -112,7 +126,7 @@ Browser (port 5173 dev / 80 prod)
|
||||
- **No refresh tokens** — 8h hard expiry; adding refresh requires `httpOnly` cookie + rotation
|
||||
- **No `httpOnly` cookie** — JWT in `localStorage` is XSS-exposed
|
||||
- **App permissions** — no per-user, per-app access control. Currently all authenticated users can use all apps. Planned: `user_app_permissions` table, admin UI to grant/revoke
|
||||
- **Groups / sharing** — no group model yet; blocks document sharing in doc-service
|
||||
- **Groups / sharing** — groups + memberships exist; app permission hooks not yet wired up
|
||||
- **Email verification** — accounts are active immediately after registration
|
||||
- **Password reset** — no flow implemented
|
||||
|
||||
@@ -120,7 +134,9 @@ Browser (port 5173 dev / 80 prod)
|
||||
|
||||
## Future work
|
||||
|
||||
- [ ] Groups + permissions system: `groups`, `group_memberships`, `group_app_permissions` tables; admin CRUD; doc sharing via group membership
|
||||
- [x] Groups system: `groups`, `group_memberships` tables; admin CRUD; add/remove members
|
||||
- [ ] App permissions registry: `group_app_permissions` table; AppsPage filtered by group grants
|
||||
- [ ] Doc sharing via group membership
|
||||
- [ ] App permissions registry: `user_app_permissions (user_id, app_key)`; AppsPage filtered by grants
|
||||
- [ ] `httpOnly` cookie migration for JWT
|
||||
- [ ] Refresh token flow (paired with cookie migration)
|
||||
|
||||
Reference in New Issue
Block a user