feat(admin-access): single hardcoded admin with full RLS-backed access + audit log - #67
Merged
Conversation
Scaffold fofafu_vault/features/admin-access.md and draft Problem/Acceptance criteria/Out of scope/Open questions with the user: a single hardcoded admin account with full edit access (including DMs) across all user data. Design targets Supabase (is_admin() RLS bypass policies + a new admin Edge Function + admin_audit_log table) rather than the legacy Express/sqlite stack, since migrate-render-to-vercel-supabase is actively decommissioning Express. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
is_admin() will match kurarei+8@gmail.com, per user decision. Not yet verified as a registered Supabase Auth user in the live project. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Was kurarei+8@gmail.com; user had mixed up which test account was which. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…s + audit log is_admin() SECURITY DEFINER fn (kurarei+5@gmail.com) + FOR ALL RLS policies across families/announcements/comments/reactions/availability_slots/ messages/playdate_requests (coach_events read-only per spec's own default), admin_audit_log (append-only). messages/playdate_requests needed a BEFORE UPDATE trigger beyond the literal spec since their existing column-grants would otherwise silently block admin's own-session-token writes. New admin Edge Function: users/content/messages routes, single is_admin() gate, service-role client only where Supabase's Admin API is required (email/ban/reset-password), every mutation audit-logged. Frontend /admin (Users/Content/Messages) wired into App.tsx + RequireAuth, including the required "private conversation" banner on the Messages view. Backend 147/147, frontend 139/139, Deno 12/12, tsc clean both workspaces. No pgTAP harness exists in this repo for the RLS/trigger SQL (manual-review only) and no E2E coverage this pass -- both flagged in the feature spec rather than silently skipped. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
An independent code-reviewer pass (separate session running this repo's real dispatcher) found 7 must-fix issues against commit 3e2321c. All fixed: - updateUser's single deferred audit-log call could leave a family-table mutation with zero audit trail if a later email-change step failed. Now writes two independent audit entries, one per persisted mutation. - Both non-admin-readonly-column triggers (messages, playdate_requests) didn't guard the id column, letting a non-admin rewrite a row's primary key -- something the pre-existing column grants used to fully block. - UsersView had no UI path to actually edit a user's email/name/bio/ kidCount/avatarUrl despite the backend route existing. Added an inline RHF+Zod edit form. - Deno test coverage claimed "every route's happy path" but 6 of 11 routes were untested. Expanded 12 -> 20 tests, including a regression test for the audit-log fix above. - MessagesView's lookup form and both inline content editors used hand-rolled useState instead of this codebase's established useForm + zodResolver convention. Refactored to match. - Request bodies had no runtime narrowing. Added typeof-guards matching message/index.ts's own precedent. Also applied both nice-to-haves (dropped unneeded SECURITY DEFINER on the trigger functions; admin_audit_log's INSERT policy now also checks admin_user_id = auth.uid()) and formally resolved the coach_events Open Question. Backend 147/147, frontend 140/140, Deno 20/20, tsc clean both workspaces. Adds real screenshots of all three admin views (Users incl. the new edit form, Content, Messages incl. the private-conversation banner), captured via headless Playwright against the actual dev server with mocked network responses and an injected fake admin session -- no real Supabase project touched. Documents a new deterministic PR-screenshot requirement in fofafu_vault/standards/engineering-standards.md per explicit request. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts: # fofafu_vault/kanban/company.md # fofafu_vault/kanban/engineering.md # fofafu_vault/log/2026-08-20.md # fofafu_vault/standards/engineering-standards.md # frontend/src/components/Navbar.tsx
reik
marked this pull request as ready for review
August 25, 2026 01:21
reik
added a commit
that referenced
this pull request
Aug 25, 2026
- Resolved PR #65's merge conflicts against master (kanban/company.md, kanban/engineering.md, log/2026-08-22.md), caused by #66/#67 landing on master after this PR's merge-base. - Corrects the record on the recurring "[Fact-Forcing Gate]" tool error that multiple prior sessions flagged as unexplained/injected: it's a real PreToolUse hook from the everything-claude-code plugin's gateguard skill, not injection. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
reik
added a commit
that referenced
this pull request
Aug 25, 2026
Status review -> shipped, kanban moved to Done on both boards. Also repointed PR #67's screenshot links from the feat/admin-access branch to master before the source branch gets deleted, and corrected the log record on the "Fact-Forcing Gate" -- confirmed real (everything-claude-code plugin's gateguard hook), not injection. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
is_admin()SECURITY DEFINER fn (matcheskurarei+5@gmail.com) +FOR ALLRLS policies across families/announcements/comments/reactions/availability_slots/messages/playdate_requests (coach_eventsread-only, per the feature spec's own proposed default), plus an append-onlyadmin_audit_logtable.supabase/functions/admin/index.ts: users/content/messages routes behind a singleis_admin()gate; service-role client constructed only where Supabase's Admin API is required (email edits, ban/unban, force password reset), never returned to the caller; every mutation writes one audit log row in the same request./adminfrontend route (Users / Content / Messages tabs), wired intoRequireAuth, including the spec-required "you are viewing a private conversation" banner on the Messages view. Nav link + page redirect are UX-only — the real gate is server-side.messages/playdate_requests, and an unrelated pre-existing bug inplaydate_requests' existing update path) is written up infofafu_vault/features/admin-access.md's Backend/Frontend/Test plan sections.Screenshots
Users — list, ban/unban, force-password-reset:

Users — edit (name/bio/kids/avatar/email; added after code review, see below):

Content — announcements/comments (editable) and reactions (delete-only):

Messages — conversation lookup, the required private-conversation banner, edit/delete:

Code review
An independent code-reviewer pass (a separate session running this repo's own
/dispatchprotocol) found 7 must-fix issues against the first commit here, including two real bugs: an audit-log completeness gap inupdateUser(a family-table mutation could persist with zero audit trail if a later email-change step failed) and a security-relevant gap where both non-admin-readonly-column triggers omitted theidcolumn, letting a non-admin rewrite a row's primary key. All 7 are now fixed — full writeup in the feature spec's Code review section (fofafu_vault/features/admin-access.md).Test plan
tsc --noEmitclean on both workspacesNot covered, flagged rather than silently skipped:
Still a draft given the above — the admin identity here has full read/write over every user's data including private DMs on a platform for foster families and children, so I'd rather this get a real look before it's mergeable than default to ready-for-review.
🤖 Generated with Claude Code