Skip to content

Commit e6b1d2a

Browse files
committed
feat(vps): port admin to HttpApiBuilder.group (Step 6)
Ports GET /api/admin/overview, /api/admin/frontend-errors/:scenario, and GET /api/admin/newsletter-subscribers from the Hono/zod-openapi router onto the Effect router. All three are admin-gated via .middleware(AuthMiddleware) plus an in-handler role check (requireAdmin), matching the pattern already used for music-artists' write endpoints. effect@4.0.0-beta.93's HttpApiError has no built-in 429 -- the frontend error simulator (a QA tool exercising www's error boundary/Sentry-reporting threshold against every real status code) needs one, so SimulatedRateLimitError is declared in packages/api/src/admin.ts the same way Phase 2 of the migration doc ports any other domain error. The other simulated-error branches use the built-in HttpApiError classes directly (bodyless) rather than preserving the old handler's { error, scenario } response body -- confirmed via apps/www/src/lib/http-client.ts that the frontend only branches on res.status, not response body shape. getAdminOverview's ~30-query aggregation batch has no dedicated service layer (same as the old Hono handler); ported as one Effect.tryPromise wrapping the whole batch, matching the old handler's single try/catch around one Promise.all rather than converting each query individually. Deletes the superseded routes/admin/{admin.routes,admin.index,admin.handlers}.ts Hono trio and its app.ts mount. No apps/www changes -- fetcher() calls the same /api/admin/* paths unchanged, verified end-to-end against the real prod-connected dev server (admin overview dashboard + newsletter tab both render real data through the new handler, logged in via a local dev account).
1 parent d64ff2f commit e6b1d2a

10 files changed

Lines changed: 827 additions & 698 deletions

File tree

apps/vps/src/app.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Duration, Effect, Schedule } from 'effect'
22
import configureOpenAPI from '@/lib/configure-open-api'
33
import { createAppEffect } from '@/lib/create-app'
4-
import admin from '@/routes/admin/admin.index'
54
import content from '@/routes/content/content.index'
65
import email from '@/routes/email/email.index'
76
import favorites from '@/routes/favorites/favorites.index'
@@ -29,7 +28,6 @@ const setupRoutesEffect = Effect.gen(function* () {
2928

3029
configureOpenAPI(app)
3130

32-
app.route('/api/admin', admin)
3331
app.route('/api/favorites', favorites)
3432
app.route('/api/invite', invite)
3533
app.route('/api/resolve', resolve)

0 commit comments

Comments
 (0)