Auth: keep content public and restrict uploads to administrators#917
Conversation
Persist signed-in favourites and preferences in Supabase, enforce administrator claims on corpus mutations, and keep published document reads anonymous. Verified with verify:pr-local; production-readiness remains environment-blocked without local provider variables.
|
Updates to Preview Branch (codex/public-content-account-access) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis change adds administrator authorization for uploads and document mutations, introduces account-backed favourites and preferences, gates administrative UI, removes public-upload configuration, and adds database policies, scripts, documentation, and regression coverage. ChangesAccess and account model
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant AccountDataProvider
participant AccountAPI
participant Supabase
Client->>AccountDataProvider: load or update account data
AccountDataProvider->>AccountAPI: request favourites or preferences
AccountAPI->>Supabase: read or write owner-scoped records
Supabase-->>AccountAPI: account data or status
AccountAPI-->>AccountDataProvider: normalized response
AccountDataProvider-->>Client: synchronized UI state
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79355ba425
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79355ba425
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
src/components/clinical-dashboard/use-app-preferences.ts (1)
9-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winFragile string-matching for the "outside AuthProvider" escape hatch.
useAuthSessionIfAvailabledistinguishes "not wrapped in AuthProvider" from any other error solely by matching the literal message text thrown insrc/lib/supabase/client.tsx'suseAuthSession(). If that message is ever reworded, this silently stops catching it and starts re-throwing in any consumer not wrapped byAuthProvider, turning a previously graceful degradation into a crash.Consider exporting a dedicated optional accessor from
src/lib/supabase/client.tsx(e.g.useAuthSessionOptional()returningnullwhen there's no provider) instead of coupling two files via exact error text.♻️ Proposed direction
+// in src/lib/supabase/client.tsx +export function useAuthSessionOptional() { + return useContext(AuthContext); +}-function useAuthSessionIfAvailable() { - try { - return useAuthSession(); - } catch (error) { - if (error instanceof Error && error.message === "useAuthSession must be used within AuthProvider.") return null; - throw error; - } -} +function useAuthSessionIfAvailable() { + return useAuthSessionOptional(); +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/clinical-dashboard/use-app-preferences.ts` around lines 9 - 16, Replace the error-message matching in useAuthSessionIfAvailable with a dedicated optional auth-session accessor exported from the Supabase client module, such as useAuthSessionOptional. Have that accessor return null when no AuthProvider exists while preserving normal error propagation, and update useAuthSessionIfAvailable to use it directly.src/lib/account-preferences.ts (1)
1-119: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate
AppPreferencestype andnormalizePreferenceslogic across client and server.
src/lib/account-preferences.tswas introduced to back the server-side/api/account/preferencesroute, butuse-app-preferences.tskeeps its own near-identical copy of theAppPreferencestype andnormalizePreferences(plus the option-list constants) instead of importing the new shared module. Any future preference field change now has to be made in both places or the client/server contracts silently drift.
src/lib/account-preferences.ts#L1-L119: keep as the single canonical source forAppPreferences, option lists, andnormalizePreferences.src/components/clinical-dashboard/use-app-preferences.ts#L124-L152: drop the localnormalizePreferences(and the localAppPreferencestype/option constants it depends on) and import them from@/lib/account-preferencesinstead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lib/account-preferences.ts` around lines 1 - 119, Keep src/lib/account-preferences.ts lines 1-119 as the canonical source for AppPreferences, option constants, and normalizePreferences. In src/components/clinical-dashboard/use-app-preferences.ts lines 124-152, remove the duplicated local definitions and import the shared symbols from `@/lib/account-preferences`, updating references as needed without changing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/api/account/preferences/route.ts`:
- Around line 38-41: Update both the GET and PUT success responses in the
account preferences route to include an explicit Cache-Control header set to
private, no-store, matching the existing account-scoped response pattern while
preserving the current JSON payloads.
In `@src/components/account-data-provider.tsx`:
- Around line 123-186: The favourites actions currently collapse unauthenticated
and request failures into a boolean, causing callers to show misleading sign-in
messages. Update setFavourite and clearFavourites in
src/components/account-data-provider.tsx (lines 123-186) to surface a distinct
failure reason, then update the clearFavourites handling in
src/components/clinical-dashboard/settings-dialog.tsx (lines 234-237) and
setFavourite handling in
src/components/differentials/differential-detail-page.tsx (lines 975-985) to use
that reason or accountData.error, showing sign-in guidance only for
unauthenticated users and the request error otherwise.
In `@src/components/DocumentViewer.tsx`:
- Around line 2658-2670: Pass the administrator authorization gate explicitly
from the DocumentViewer render to DocumentManagementActions by using its
existing canManage or disabled prop, setting it from canUseAdministrativeApis.
Preserve the current callbacks and display behavior while ensuring rename/delete
controls are unavailable whenever canUseAdministrativeApis is false, including
serverDemoMode cases.
---
Nitpick comments:
In `@src/components/clinical-dashboard/use-app-preferences.ts`:
- Around line 9-16: Replace the error-message matching in
useAuthSessionIfAvailable with a dedicated optional auth-session accessor
exported from the Supabase client module, such as useAuthSessionOptional. Have
that accessor return null when no AuthProvider exists while preserving normal
error propagation, and update useAuthSessionIfAvailable to use it directly.
In `@src/lib/account-preferences.ts`:
- Around line 1-119: Keep src/lib/account-preferences.ts lines 1-119 as the
canonical source for AppPreferences, option constants, and normalizePreferences.
In src/components/clinical-dashboard/use-app-preferences.ts lines 124-152,
remove the duplicated local definitions and import the shared symbols from
`@/lib/account-preferences`, updating references as needed without changing
behavior.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 55e436a9-4875-4189-bbfc-aae8bc634b18
📒 Files selected for processing (49)
.env.exampledocs/branch-review-ledger.mddocs/site-map.mdpackage.jsonscripts/set-site-administrator.tssrc/app/api/account/favourites/route.tssrc/app/api/account/preferences/route.tssrc/app/api/documents/[id]/labels/route.tssrc/app/api/documents/[id]/reindex/route.tssrc/app/api/documents/[id]/reviews/route.tssrc/app/api/documents/[id]/route.tssrc/app/api/documents/[id]/summarize/route.tssrc/app/api/documents/[id]/table-facts/route.tssrc/app/api/documents/bulk/reindex/route.tssrc/app/api/documents/bulk/route.tssrc/app/api/eval-cases/route.tssrc/app/api/ingestion/batches/route.tssrc/app/api/ingestion/jobs/[id]/retry/route.tssrc/app/api/ingestion/jobs/route.tssrc/app/api/ingestion/quality/route.tssrc/app/api/jobs/route.tssrc/app/api/setup-status/route.tssrc/app/api/upload/route.tssrc/app/layout.tsxsrc/components/ClinicalDashboard.tsxsrc/components/DocumentViewer.tsxsrc/components/account-data-provider.tsxsrc/components/clinical-dashboard/favourites-command-library-page.tsxsrc/components/clinical-dashboard/settings-dialog.tsxsrc/components/clinical-dashboard/use-app-preferences.tssrc/components/clinical-dashboard/use-saved-registry-favourites.tssrc/components/differentials/differential-detail-page.tsxsrc/components/forms/form-detail-page.tsxsrc/components/services/service-detail-page.tsxsrc/lib/account-preferences.tssrc/lib/authorization.tssrc/lib/client-env.tssrc/lib/env.tssrc/lib/public-api-access.tssrc/lib/supabase/auth.tssrc/lib/supabase/client.tsxsrc/lib/supabase/database.types.tssupabase/migrations/20260719064735_user_account_data_and_admin_uploads.sqltests/account-access-model.test.tstests/audit-navigation-auth-regressions.test.tstests/client-secret-surface.test.tstests/document-admin-rate-limit.test.tstests/private-access-routes.test.tstests/supabase-schema.test.ts
💤 Files with no reviewable changes (2)
- src/lib/client-env.ts
- src/lib/env.ts
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. The branch was updated while autofix was in progress. Please try again. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 812cbf7466
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 5 file(s) based on 3 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 5 file(s) based on 3 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7a2c423de4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Service and form detail pages treated setFavourite's failure object as truthy, so signed-out or rejected saves still showed a success notice. Align both pages with the differential detail pattern and add a regression assertion that all detail pages inspect result.success. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #3549 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
Static PR checks failed format:check on this file; apply Prettier so CI can pass. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: de0cddb1bd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b1cb54c00
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Add user_favourites and user_preferences tables, RLS policies, grants, and storage.objects upload revoke to the canonical schema snapshot. Regenerate supabase/drift-manifest.json so drift verification matches the post-migration live inventory. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Return Cache-Control: private, no-store on GET /api/account/favourites so signed-in saved-item lists cannot be cached across sign-out or account switches, matching the preferences endpoint. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Align the Answer from this document control with the administrator-only summarize API so signed-in non-admin sessions no longer see an enabled action that returns 403. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Implement the skills listing/check script referenced by npm run skills and npm run check:skills so the commands validate .agents/skills against the maintained database-skills.md catalog. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Summary
app_metadata.site_role = administrator.Verification
npm run verify:pr-localnpm run verify:uiwhen UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changednpm run ensurestarted the app at the repository-selected URL and/api/local-project-idconfirmed the Clinical KB identity before the local server was stopped.npm run verify:releasebefore release or handoff confidence claimsnpm run eval:retrieval:quality(must stay 36/36)npm run eval:rag -- --limit 15+npm run eval:quality -- --rag-onlynpm run check:production-readiness.env/.env.local, so Supabase/OpenAI variable checks were environment-blocked.npm run check:deployment-readinessRisk and rollout
user_idconstraint. The focused auth review found no remaining P0-P2 issue and the behavior is regression-tested.20260719064735_user_account_data_and_admin_uploadsis already recorded onClinical KB Database(sjrfecxgysukkwxsowpy), and the approved existing Auth account received the administrator claim. No content rows were modified.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
origin/main; unrelated CI, audit, skills, ingestion-worker, schema-snapshot, and migration-repair changes are excluded.Summary by CodeRabbit