feat(revamp): Block F — admin program management (closes #46 #47)#57
Draft
sacha-l wants to merge 2 commits intorevamp/block-d-program-applicationsfrom
Draft
feat(revamp): Block F — admin program management (closes #46 #47)#57sacha-l wants to merge 2 commits intorevamp/block-d-program-applicationsfrom
sacha-l wants to merge 2 commits intorevamp/block-d-program-applicationsfrom
Conversation
Admins can create and edit programs from /admin. POST and PATCH on /api/programs, both gated by requireAdmin; SIWS-signed with new "Create program on Stadium" / "Update program on Stadium" statements. Phase 1 revamp Block F, issue #46. See docs/stadium-revamp-phase-1-spec.md §5 Issue 11. Server: - server/api/utils/validation.js — validateProgram with partial/full modes. Enforces kebab-case slug, enum program_type and status, date validity, cross-field application-window and event-window ordering, length bounds on description / location / name, positive max_applicants. - server/api/repositories/program.repository.js — create + updateBySlug + a toSnakeCase helper that only writes provided keys (partial updates don't null-out untouched columns). - server/api/services/program.service.js — thin wrappers. - server/api/controllers/program.controller.js — createProgram (UUID id + owner='webzero' enforced; 409 on slug pre-check + DB unique violation race) and updateProgram (404 on missing, 409 on slug change collision, 422 on invalid partial). - server/api/routes/program.routes.js — POST '/' + PATCH '/:slug', both requireAdmin. - server/api/middleware/auth.middleware.js — adds base SIWS statements: "Create program on Stadium", "Update program on Stadium", "Review application on Stadium" (last one staged for #47). - server/api/controllers/__tests__/program-admin.test.js — 11 new unit tests covering validation errors, slug-conflict 409 (both pre-check and DB race), happy-path create with id + owner, update 404/422/409/200. Client: - client/src/lib/api.ts — api.createProgram + api.updateProgram with mock-mode fallbacks that enforce slug uniqueness. - client/src/lib/siwsUtils.ts — three new actions: 'create-program', 'update-program', 'review-application' (last staged for #47). - client/src/components/admin/ProgramFormModal.tsx (new) — single modal for both create and edit. Auto-generates slug from name until the user edits it; inline validation mirrors server (kebab-case slug, date ordering, positive integer max). Uses datetime-local inputs that convert to ISO on submit. Slug is read-only in edit mode so we don't churn FKs in this phase. - client/src/components/admin/ProgramsTable.tsx — "Create program" button (visible only when connectedAddress is set), clickable rows navigate to /admin/programs/:slug (Phase 1 revamp #47 route, landing in the next commit), per-row Edit button. - client/src/pages/AdminPage.tsx — passes connectedAddress to the ProgramsTable from walletState.selectedAccount. Verification: - server/npm test: 43/43 passing (11 new + 32 existing). - client/npm run build: clean. Out of scope (#47, next commit in this PR): - /admin/programs/:slug page and application review handlers.
Closes Block F. Admin reviews applications on a per-program page, accepts or rejects with status transitions stamped with reviewer + timestamp. Phase 1 revamp Block F, issue #47. See docs/stadium-revamp-phase-1-spec.md §5 Issue 12. Server: - server/api/controllers/program.controller.js — new updateApplicationStatus handler: status enum check, optional reviewNotes length bound (≤ 2000), 404 on unknown program, 404 mapping on PostgREST PGRST116 no-rows error, 200 on success. - server/api/routes/program.routes.js — PATCH /api/programs/:slug/applications/:applicationId (requireAdmin). - server/api/controllers/__tests__/program-application.test.js — 5 new tests covering: invalid status 422, too-long reviewNotes 422, unknown program 404, happy-path with reviewNotes trim, and PGRST116 → 404 mapping. Client: - client/src/lib/api.ts — api.updateApplicationStatus with mock-mode fallback. - client/src/components/admin/ApplicationCard.tsx (new) — shows project link (to /m2-program/:id), submitter, submitted date, status badge, Dogfooding feedback_focus, review notes (when present), and Accept/Reject buttons that appear only when status === 'submitted'. Each action triggers SIWS with the 'review-application' statement. - client/src/pages/AdminProgramPage.tsx (new) — /admin/programs/:slug admin-gated page. Restores admin_session_account from sessionStorage (same pattern as AdminPage); on-demand SIWS-signed Load/refresh fetches applications; filter chips (submitted / accepted / rejected / withdrawn / all); renders ApplicationCard per row. - client/src/App.tsx — new /admin/programs/:slug route. Design notes: - Filter default is "submitted" so admins land on the work queue. - Applications are loaded on explicit button click rather than on mount, because listing applications is SIWS-gated — the fetch has to happen after the admin signs. Alternative: auto-load once after a successful wallet connect. Chose explicit for transparency in Phase 1. - Status transitions are final in this phase (no comment-back flow yet, no email/Telegram notification — those are explicitly Phase 2+ per context-doc §64). Verification: - server/npm test: 48/48 passing (5 new + 43 existing). - client/npm run build: clean. End of Block F. Admin side of the Phase 1 program flow is complete.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Block F of the Phase 1 revamp — admin side of the program flow. Closes #46 and #47.
Stacked on #55 (Block D). Target base is
revamp/block-d-program-applicationswhile that PR is open. Once #55 merges, I'll rebase this ontodevelopand retarget.Block F journey slice (per spec §12)
"Admin can set up Dogfooding and process applications." Admin opens
/admin→ ProgramsTable → clicks "Create program" → fills form → saves → row appears. Clicks the row →/admin/programs/:slug→ clicks Load/refresh → sees applications → Accept one → status flips without reload.Commits
<sha>— #46: admin create / edit programsvalidatePrograminserver/api/utils/validation.js— kebab-case slug, enumprogramType/status, date validity, cross-field window ordering (apps open < close, event starts ≤ ends), bounds on name/description/location, positivemax_applicants. Works in partial mode for PATCH.create,updateBySlug,toSnakeCasehelper (writes only provided keys — partial PATCH doesn't null-out untouched columns).createProgram(UUID id + owner='webzero' enforced; 409 on slug pre-check + DB-race),updateProgram(404 / 422 / 409 / 200).POST /api/programs+PATCH /api/programs/:slug, bothrequireAdmin.Create program on Stadium+Update program on Stadium.api.createProgram+api.updateProgram+ newProgramFormModal(auto-slug from name until user edits; datetime-local inputs → ISO on submit; slug read-only in edit mode so we don't churn FKs).ProgramsTableextended with Create button + per-row Edit + clickable rows navigating to/admin/programs/:slug.<sha>— #47: admin applications queueupdateApplicationStatus(status enum check, optionalreviewNotes ≤ 2000chars, 404 on unknown program, PGRST116 → 404 mapping, 200 on success).PATCH /api/programs/:slug/applications/:applicationId(requireAdmin).Review application on Stadium.api.updateApplicationStatus, newApplicationCardcomponent (shows project link, submitter, submitted date, status badge, Dogfoodingfeedback_focus, review notes, Accept/Reject — visible only when status=submitted), new/admin/programs/:slugAdminProgramPagewith filter chips (submitted / accepted / rejected / withdrawn / all) and explicit SIWS-signed Load/refresh (listing applications is admin-gated on the server, so the fetch has to happen after sign).Test plan
Automated:
cd server && npm test→ 48/48 passing (16 new + 32 existing).cd client && npm run build→ clean.Playwright:
/adminwithout admin wallet, Create / Edit / row-click behaviours don't trigger write flows (admin session guards remain intact)./admin/programs/dogfooding-2026-berlinwithout admin wallet, "Admin wallet required" prompt renders.SIWS-gated (manual QA with an admin wallet):
/admin→ Create program → fill form → save → new row appears; clicking the row navigates to/admin/programs/<new-slug>./admin/programs/<slug>→ connect admin wallet → Load/refresh → applications appear; Accept one → card re-renders with 'accepted' status; filter chips correctly narrow the list.Design notes
program_applications.program_idFKs. Out of scope for Phase 1.reviewNotesstring). Notifications/email/Telegram are explicitly Phase 2+ per context-doc §64.Out of scope (deferred)
feedback_focus.