Skip to content

fix: tenant-admin blog create 500 — authorId stamped the Clerk id, violating posts_authorId_fkey - #226

Merged
AutomatosAI merged 1 commit into
mainfrom
fix/tenant-admin-post-author-fk
Aug 6, 2026
Merged

fix: tenant-admin blog create 500 — authorId stamped the Clerk id, violating posts_authorId_fkey#226
AutomatosAI merged 1 commit into
mainfrom
fix/tenant-admin-post-author-fk

Conversation

@AutomatosAI

@AutomatosAI AutomatosAI commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Problem

The lekkerweed tenant admin has been unable to create a blog post for weeks — every attempt 500s. Railway logs (2026-08-06 13:26–13:27 WEST, correlationIds 85073817 / 7396fd0a) show the actual failure:

Invalid prisma.posts.create() invocation:
Foreign key constraint violated on the constraint: posts_authorId_fkey

This is not a permissions problem — auth passed (500, not 401/403). POST /api/tenant-admin/posts stamps authorId: user.id, and getCurrentUser() returns the Clerk user id verbatim. That only matches users.id for rows the Clerk webhook itself created (which keys new rows by the raw Clerk id — the webhook even carries a comment about this exact FK trap). Admins provisioned by tenant-create / team-invite / seeding have UUID primary keys, so the FK fails on every create. Super-admin works only because that row happens to be Clerk-keyed.

Fix

  • POST resolves the local users row (clerkUserIdidemail, all unique) and stamps its id. The lookup runs tenant-scoped, so an impersonating super-admin (row outside the tenant) misses and falls back to user.id — exactly the Clerk-keyed row the FK already accepts today, preserving current super-admin behaviour.
  • Residual P2003 now returns a clear 409 ("author account not linked") instead of an opaque 500.
  • Bonus fix: both API GETs used include: { author }, but the introspected Prisma relation is named users — those routes threw P2009 and 500'd whenever called. Now include users and alias it back to author in the JSON response (the UI doesn't call these — it server-renders — so no consumer change).

Audit-log userId: user.id writes were swept and are safe (audit_logs.userId is a plain string, no FK). posts.authorId was the only FK-constrained stamp of the Clerk id.

Test plan

  • New tests/unit/posts-author-fk.test.ts (mirrors posts-slug-scope.test.ts mocking):
    • provisioned tenant admin → authorId = local UUID row id
    • no visible local row (impersonation) → falls back to Clerk id
    • residual P2003 → 409 with actionable message
  • After deploy: lekkerweed admin creates a post on The Wire; verify it lands with the correct authorId and renders on the storefront blog.

Follow-ups (not this PR)

  • security.tenant_context_missing warnings flood the logs for posts.findMany — server components (the-wire, store/[slug]) query with explicit where: { tenantId } but outside the ALS tenant context. Benign but noisy.
  • [id] posts routes still use withAuth + manual email/tenant checks rather than withTenantAuthParams — works, but inconsistent with the collection route.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed post details so author information displays correctly.
    • Improved post creation for provisioned accounts by reliably matching the author.
    • Added a clear conflict response when an author account cannot be linked, helping explain how to resolve the issue.
    • Preserved existing post data while correcting author information in API responses.

…eate 500

posts.authorId FKs users.id, but getCurrentUser().id is the Clerk id; they
only coincide for webhook-provisioned rows keyed by the raw Clerk id. Tenant
admins provisioned by tenant-create/team-invite/seeding have UUID PKs, so
every blog create violated posts_authorId_fkey and 500'd (lekkerweed, weeks).
Resolve the tenant-scoped local row (clerkUserId -> id -> email) and fall
back to the Clerk id only when no row is visible (impersonating super-admin,
whose Clerk-keyed row the FK already accepts). Residual P2003 now maps to a
clear 409 instead of an opaque 500.

Also fix include:{author} in both API GETs — the Prisma relation is named
users (introspected), so author threw P2009 and 500'd those routes; alias
the relation back to author in the JSON response.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e854455d-b955-490f-ac00-15f3f3044e45

📥 Commits

Reviewing files that changed from the base of the PR and between 04488ab and 2c6080c.

📒 Files selected for processing (3)
  • nextjs_space/app/api/tenant-admin/posts/[id]/route.ts
  • nextjs_space/app/api/tenant-admin/posts/route.ts
  • nextjs_space/tests/unit/posts-author-fk.test.ts

📝 Walkthrough

Walkthrough

Tenant-admin post creation now resolves tenant users before author assignment and handles missing author records. Post GET handlers load the users relation and preserve the author response field. Unit tests cover these behaviors.

Changes

Tenant post author handling

Layer / File(s) Summary
POST author resolution and FK handling
nextjs_space/app/api/tenant-admin/posts/route.ts, nextjs_space/tests/unit/posts-author-fk.test.ts
POST resolves the local author by Clerk ID, database ID, or email. It returns HTTP 409 for residual author foreign-key errors. Unit tests cover local UUID resolution, Clerk ID fallback, and error mapping.
Author relation response mapping
nextjs_space/app/api/tenant-admin/posts/route.ts, nextjs_space/app/api/tenant-admin/posts/[id]/route.ts
GET handlers query the users relation and expose it as author in the response.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TenantAdmin
  participant POSTRoute
  participant PrismaUsers
  participant PrismaPosts
  TenantAdmin->>POSTRoute: Submit post
  POSTRoute->>PrismaUsers: Resolve tenant user
  PrismaUsers-->>POSTRoute: Return local user or no match
  POSTRoute->>PrismaPosts: Create post with resolved author ID
  PrismaPosts-->>POSTRoute: Return post or foreign-key error
  POSTRoute-->>TenantAdmin: Return post or HTTP 409
Loading

Possibly related PRs

Suggested reviewers: gerard161-site

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tenant-admin-post-author-fk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AutomatosAI
AutomatosAI merged commit 410efdc into main Aug 6, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants