Initial Commit
This commit is contained in:
92
openspec/changes/enterprise-api-plugin-admin/tasks.md
Normal file
92
openspec/changes/enterprise-api-plugin-admin/tasks.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Tasks: enterprise-api-plugin-admin
|
||||
|
||||
**Change ID**: enterprise-api-plugin-admin
|
||||
**Package**: `@suaveplan/api-plugin-admin`
|
||||
**Target path**: `api/auth/api-plugin-admin`
|
||||
**Prerequisite packages on Verdaccio**: `@suaveplan/api`, `@suaveplan/api-shared`, `@suaveplan/api-plugin-auth`, `@suaveplan/api-plugin-database`, `@suaveplan/audit-logging`, `@suaveplan/events`, `@suaveplan/rate-limiter`, `@suaveplan/error`, `@suaveplan/logger`
|
||||
|
||||
---
|
||||
|
||||
## 0. Pre-flight (non-negotiable)
|
||||
|
||||
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
|
||||
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
|
||||
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [ ] Create `api/auth/api-plugin-admin/` with all subdirs.
|
||||
- [ ] `package.json` v0.0.0, `"sideEffects": ["src/events.ts"]`, subpath exports.
|
||||
- [ ] `tsconfig.json` + `vitest.config.ts`.
|
||||
- [ ] Scripts: `lint`, `typecheck`, `test`, `test:coverage`, `test:with-db`, `build`, `docs:check`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Types and errors
|
||||
|
||||
- [ ] `src/types/` — `AdminConfig`, `AdminConfigSchema` (Zod), `SiteMetadata`, `AdminStats`, `AuditQuery`, `AuditEntry`.
|
||||
- [ ] `src/errors/admin-errors.ts` — 4-code `AdminErrorCode` union, metadata, registration.
|
||||
- [ ] `admin-errors.test.ts` + `admin-errors.md`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Events
|
||||
|
||||
- [ ] `src/events.ts` — module augmentation declaring `AdminEventMap` (`admin:action:performed`) on global event bus. Export `AdminActionPerformedEvent` interface.
|
||||
- [ ] No `as any` casts, no `@ts-expect-error`.
|
||||
|
||||
---
|
||||
|
||||
## 4. SurrealQL migrations
|
||||
|
||||
- [ ] `surql/admin_action.surql`, `surql/admin_ban.surql` — DEFINE TABLE + DEFINE FIELD + tenantId indexes.
|
||||
|
||||
---
|
||||
|
||||
## 5. AdminService
|
||||
|
||||
- [ ] Implement all methods listed in proposal: suspendUser, banUser, promoteUser, demoteUser, approvePost, removePost, getSiteMetadata, getStats, queryAuditLog.
|
||||
- [ ] Each state-changing method: emit `admin:action:performed` via `ctx.eventBus.emit(...)` (typed, no cast); write audit entry via `@suaveplan/audit-logging`.
|
||||
- [ ] OTel span per method.
|
||||
- [ ] `admin.service.test.ts` (≤500 lines): each method happy path + not-found throws + forbidden throws.
|
||||
- [ ] `admin.service.md`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Routes (each with `.test.ts` + `.md`)
|
||||
|
||||
- [ ] `/admin/users` — list, get, suspend, ban, promote, demote (all behind `requireAuth()` + `requireRole("ADMIN")`).
|
||||
- [ ] `/admin/sites` — list, get, update site metadata.
|
||||
- [ ] `/admin/stats` — GET dashboard stats.
|
||||
- [ ] `/admin/posts` — list moderation queue, approve, remove.
|
||||
- [ ] `/admin/audit` — paginated audit log query.
|
||||
- [ ] Rate limiting on all destructive endpoints.
|
||||
- [ ] OpenAPI tags + descriptions on every route.
|
||||
- [ ] Import specific types from `@suaveplan/api-schemas`; no `export *` pass-through.
|
||||
|
||||
---
|
||||
|
||||
## 7. Plugin factory
|
||||
|
||||
- [ ] `createAdminPlugin(config?)`: `definePlugin` with `dependencies: ["database", "auth"]`, `migrationsPath: "./surql"`.
|
||||
- [ ] `onInit`: instantiate `AdminService`, register via `ctx.registerService("admin", adminService)`.
|
||||
- [ ] `onClose`: no-op (no listeners to detach for this plugin).
|
||||
- [ ] `onTenantCreate` / `onTenantDelete`: bootstrap/teardown admin namespace in SurrealDB.
|
||||
|
||||
---
|
||||
|
||||
## 8. Integration tests (`tests/integration.test.ts`)
|
||||
|
||||
- [ ] Suspend user → user cannot login → reinstate → login succeeds (against real SurrealDB via `test:with-db`).
|
||||
- [ ] Admin action emits event on bus.
|
||||
- [ ] Non-admin role → 403.
|
||||
|
||||
---
|
||||
|
||||
## 9. Verify and publish
|
||||
|
||||
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/api-plugin-admin` — green.
|
||||
- [ ] `bunx turbo test:coverage --filter=@suaveplan/api-plugin-admin` — 100%.
|
||||
- [ ] No `@ts-expect-error`, `export *` of external deps, method rebinding, or `.skip`.
|
||||
- [ ] `bun scripts/publish.ts --package @suaveplan/api-plugin-admin`.
|
||||
- [ ] Archive → `openspec/archive/2026-04-24-enterprise-api-plugin-admin/`.
|
||||
Reference in New Issue
Block a user