refactor(backend): build the dev fixture through the API - #240
Merged
Conversation
The seed wrote every row with ent and then hand-wrote the casbin rows that should have accompanied them, so the fixture drifted from the handlers it was imitating: the capability→policy switch was copied out of SetCapabilities, votes were written without the checks SubmitVote makes, and an answer's storage format had to be kept true by hand. It now stands the gRPC server up in-process on a bufconn pipe and drives it with tokens it signs itself. That is the only way to act as the 106 fixture identities — four of which exist in Keycloak — and the only way to give anyone a display name, which can come from JWT claims and nowhere else. All 24 AddRole/AddPolicy call sites are gone; the handlers grant every role themselves. Two consequences shape how each hackathon now reads. A capability has to be on at the moment it is used, so each one switches capabilities on as its history needs them and ends with a call declaring the set it should be left in. And H3 is created with a live window and backdated last of all, because Join refuses a hackathon that has already finished — a past hackathon cannot be populated as one. Seeding is no longer atomic and cannot be: several handlers open a transaction of their own, and ent refuses one inside another. Instead of the guarantee the run checks all four hackathon names — all present skips, none seeds, and some is an error telling you to wipe, because a half fixture that looks whole is worse than either. It was never fully atomic anyway, since casbin writes through its own connection and a rollback always left the policy rows. Diffed row by row against the old fixture: 90 lines of 864 change. Two are fixes the fixture had missed. The three public hackathons finally carry `*, hackathon:read`, so anonymous browsing works and public-hackathon-read is stale; and H3 gains the `member, submission:read` row that the hand-written vote capability dropped, without which a voter cannot read what they are voting on. One deliberate divergence goes the other way: the `owner, project:join` rows the seed used to add so an owner could express a preference are gone, and seeded hackathons now behave exactly as the API does. The rest is the fixture no longer improving on the handlers — page order starts at 0, questions with no options store null, Approve and Team.Create leave the modifier alone, a single-choice vote stores 0 — plus Team Gamma passing from bob to the admin, because team:create is Owner-only and a participant-assembled team is not a state the API can produce. Registration answers are the one direct write left, because no answer can be stored through the API at all (TODO(backend: answer-upsert-sql)). The seed calls SubmitAnswers anyway so the handler still validates them, falls back to ent on exactly that failure, and stops falling back the day the ticket lands.
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.
The seed wrote every row with ent and then hand-wrote the casbin rows that should have accompanied them, so the fixture drifted from the handlers it was imitating: the capability→policy switch was copied out of SetCapabilities, votes were written
Seed the dev fixture through the API
As a developer working on Hackagon
I want the dev fixture to be built by calling the backend
So that what I see locally is always a state the app itself could have produced.
Why
The seed wrote rows with ent and hand-copied the casbin rules that should go with
them. Those copies drifted: it duplicated the capability→policy switch out of
SetCapabilities, wrote votes without the checksSubmitVotemakes, and kept ananswer's storage format true by hand. When a handler got fixed, the fixture didn't.
What changed
The seed now starts the gRPC server in-process on a bufconn pipe and drives it with
tokens it signs itself — the only way to act as all 106 fixture identities, of which
four exist in Keycloak. All four hackathons go through real RPCs; 24 hand-written
AddRole/AddPolicycalls are gone, andmain.godrops from 1962 lines to 208.What you'll notice
(
public-hackathon-readis stale), and H3 gained themember, submission:readrow the hand-written vote capability had missed.
team:createis Owner-only, soa participant-assembled team was never a reachable state.
just db::seedlogs oneupsert answerERROR per answering participant. That'sthe handler's own log line from
answer-upsert-sql; the seed still succeeds.just clean::state.Verification
Row-by-row diff of the old and new fixtures: 90 lines of 864 differ, each one an
explained handler behaviour.
check::lint,check::build,check::testandtreefmt --cipass. Smoke-tested against the running backend as alice, bob andcharles.