fix: store ai_insights with users.id and add FK + cascade delete#1765
Open
Ridanshi wants to merge 1 commit into
Open
fix: store ai_insights with users.id and add FK + cascade delete#1765Ridanshi wants to merge 1 commit into
Ridanshi wants to merge 1 commit into
Conversation
Root cause
----------
src/app/api/ai-insights/route.ts set user_id = session.githubId, which
is the GitHub numeric account ID (e.g. "12345678"). The ai_insights table
had no foreign-key constraint, so:
1. Rows referenced a non-existent concept of "user" — github_id is not
the primary key of the users table and carries no referential weight.
2. ON DELETE CASCADE could not fire because no FK existed, so deleting a
user account left all their ai_insights rows permanently orphaned.
3. The account deletion handler in data-export/route.ts did not include
ai_insights in its explicit deletion list, compounding the problem.
Changes
-------
src/app/api/ai-insights/route.ts
- Import and call resolveAppUser(session.githubId, session.githubLogin) to
obtain the application UUID (users.id) before touching the database.
- Use user.id (UUID) for all DB reads and writes instead of session.githubId.
- Return 404 if resolveAppUser returns null (unregistered session).
- Add insight_type validation against the DB CHECK constraint allowlist
('weekly_summary' | 'pattern' | 'recommendation') so unrecognised types
receive a clear 400 instead of a Supabase constraint-violation 500.
src/app/api/user/data-export/route.ts
- Add "ai_insights" to the tablesToDelete array in the DELETE handler.
The ON DELETE CASCADE on the new FK would handle removal automatically,
but the explicit delete is a defense-in-depth safeguard that works even
if the migration has not yet been applied.
supabase/migrations/20260531000000_fix_ai_insights_user_id.sql
- Remap existing ai_insights.user_id values from github_id strings to the
corresponding users.id UUIDs via a JOIN on users.github_id.
- Delete any rows that cannot be matched (accounts already deleted — these
are the orphaned records the issue describes).
- Add FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE to
enforce referential integrity going forward.
test/ai-insights-ownership.test.ts — 13 new tests:
- Auth guards (no session, unresolved user)
- resolveAppUser is called with the session github credentials
- Upsert and cache-read both use the UUID, not the GitHub numeric ID
- Regression for Priyanshu-byte-coder#1750: no DB operation receives githubId as user_id
- Cache-hit returns content with cached: true
- insight_type validation: invalid type → 400, valid types → 200
- Upsert conflict target is "user_id,insight_type"
- Cache-miss response shape is { data, cached: false }
Closes Priyanshu-byte-coder#1750
|
@Ridanshi is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel. A member of the Team first needs to authorize it. |
GSSoC Label Checklist 🏷️@Priyanshu-byte-coder — please apply the appropriate labels before merging: Difficulty (pick one):
Quality (optional):
Validation (required to score):
|
Owner
|
This PR has developed merge conflicts after recent merges to |
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.
Closes #1750
Problem
GET /api/ai-insightsstored insight rows usingsession.githubIdasuser_id:session.githubIdis the GitHub numeric account ID, not the application UUID (users.id). Theai_insightstable had no foreign-key constraint pointing atusers, so:Orphaned records — when a user deleted their account, all their
ai_insightsrows remained forever. The account-deletion handler (data-export/route.ts) did not includeai_insightsin its explicit deletion list, and there was noON DELETE CASCADEto fill in.No referential integrity — inserts could reference any arbitrary string as
user_idwith no guarantee that a matching user existed.Broken cascade — even if the cascade were to fire in the future, it would compare against
users.id(UUID), notusers.github_id(numeric string), so it would never match existing rows.Root cause (three locations)
src/app/api/ai-insights/route.tsline 51const userId = session.githubId— uses wrong identitysrc/app/api/user/data-export/route.ts—tablesToDeletearrayai_insightsnot listed; rows survive account deletionsupabase/schema.sql—ai_insightstableFix
src/app/api/ai-insights/route.tsresolveAppUser(session.githubId, session.githubLogin)to obtainuser.id(the stable UUID) and use it asuser_idthroughout.insight_typevalidation against the allowlist('weekly_summary' | 'pattern' | 'recommendation')that mirrors the DBCHECKconstraint. Unrecognised types now return 400 instead of a Supabase constraint-violation 500.src/app/api/user/data-export/route.ts"ai_insights"totablesToDeleteso explicit account deletion always removes insight rows — even before the FK migration is applied.supabase/migrations/20260531000000_fix_ai_insights_user_id.sqlThree steps inside a transaction:
ai_insights.user_idvalues fromgithub_idstrings to the correspondingusers.idUUIDs (viaJOIN users ON users.github_id = ai_insights.user_id).FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, enforcing integrity going forward and enabling automatic cleanup on account deletion.Identity chain (after fix)
Tests
test/ai-insights-ownership.test.ts— 13 new tests:resolveAppUsercalled with session credentials; upsert uses UUID; cache query uses UUIDgithubIdasuser_id{ cached: true, data }insight_typevalidationweekly_summary,pattern,recommendation→ 200onConflict: "user_id,insight_type"present{ data, cached: false }All 13 pass. The single pre-existing failure in
test/dateUtils.test.ts(timezone boundary) is unrelated to this change.