fix(seed): populate built-in role assignments in marketing seed (#252)#277
Merged
Merged
Conversation
The marketing seed created publishers via raw prisma.member.create, bypassing the Member aggregate that calls syncBuiltInRoleAssignments. Seeded members had zero MemberRoleAssignment rows, so the assign-part loader's fallback (built-in `member` role) returned no candidates and speaker/reader/service-role comboboxes rendered empty. - seed-marketing.ts: seed built-in Role rows after the congregation exists (fresh-DB safety) and call syncBuiltInRoleAssignments after each member create. - built-in-roles.server.ts: scope the built-in Role lookup by congregationId. Production callers run inside an RLS scope so this is a no-op there, but callers that bypass RLS (seeds run as the DB owner) would otherwise match every congregation's built-in roles and write cross-tenant assignments. - check-aggregate-boundaries.ts: widen the write regex to catch prisma.* (not just db.*) and move the app/database/** seed exemption from prose into enforcement — this is why the bypass never tripped the boundary check.
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
Fixes #252. The marketing seed created publishers via raw
prisma.member.create(...), bypassing theMemberaggregate that callssyncBuiltInRoleAssignments. Seeded members ended up with zeroMemberRoleAssignmentrows, so the assign-part loader's fallback (built-inmemberrole) returned no candidates and the speaker/reader/service-role comboboxes rendered empty.Changes
app/database/seed-marketing.ts— seed the built-inRolerows after the congregation exists (fresh-DB safety, regardless of whetherdb:seedran first) and callsyncBuiltInRoleAssignmentsafter eachmember.create.app/shared/domain/built-in-roles.server.ts— scope the built-inRolelookup bycongregationId. Production callers run inside an RLS scope (SET LOCAL app.congregation_id), so this is a no-op there. But callers that bypass RLS — seed scripts run as the DB owner — would otherwise match every congregation's built-in roles and write cross-tenant assignments. Discovered while verifying: without this, a member got each role ~10× (44 foreign-congregation assignments) on a multi-congregation dev DB.scripts/check-aggregate-boundaries.ts— the flagged CI hole. Widen the write regex to catchprisma.member.*/prisma.attribution.*(not justdb.*), and move theapp/database/**seed exemption from prose indocs/development/architecture-conventions.mdinto actual enforcement. This is why the seed's bypass never tripped the boundary check.prisma.-prefixed writes being flagged andapp/database/**being exempt.Verification
pnpm db:seed:marketingruns clean. Post-seed:marc.dupont@demo.unitae.apphas exactly[baptized, brother, elder, member, publisher], 0 foreign-congregation assignments, 0 active demo members with empty roles, and all 45 publishers hold thememberbuilt-in role →resolveEligibleUserIdsnow returns 45 candidates (was[]), so the comboboxes populate.pnpm test:typecheckclean ·pnpm test:aggregate-boundaries1124 files, no violations · unit tests green (built-in-roles 17/17, boundary 16/16).