feat/structured experience tables - #51
Merged
Merged
Conversation
…able name from Event to TournamentEvent and Membership to TournamentMembership
…'s past school and event; updated migrations
…ually added past tournaments and NEXUS tournamens; updated migrations
…since TournamentMembership can be used to auto-populate a user's profile later
…, UserSlim, and UserFull responses
…Membership so that TDs can age verify their registered volunteers
…ment_memberships; remove temp profile fields that were being stored in tournament memberships
… circular imports
… exp to user full response; updated missing profile fields logic to check for empty user exp lists
…ema; moved student/employer, exp, shirt, and dietary fields from slim to full
…ields while FullResponse returns the list; missing profile fields is computed in the routes via helper functions
… routes; update TestMissingProfileFields; moved test suite from SQLite to a dedicated Postgres database
…ubmitted their own unchanged email because check_if_email_exists still checks their own email; added verify email tets; added admin permission tests on users route
…mbiguity; GET /users/me/ supports param ?full=true to return UserMeFullResponse
…leted /auth/me/; added tests to cover the ?full=true param on /users/me/
…ed all POST PATCH DELETE routes for both competition and volunteer user experience
…red event helper fixtures; refactored test_events to use the new event fixtures
…ges made in backend
…an 3 digits works properly
…fields; extract profile questions; create new combobox component; create new radio group component to handle groups of radio options for a question
…list on start-up of all env
…ove gap between input and dropdown; for custom allowed combobox custom option shows at bottom of dropdown
…error prop to combobox
19 tasks
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🚅 Deployed to the nexus-pr-51 environment in nexus
|
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.
Background
Free-text
competition_expandvolunteer_expcolumns onUsercan't be searched or filtered. TDs need to find volunteers by event experience. This replaces the blobs with structured entries that support filtering by event and expertise.Changes
Canonical
Event/EventCategorycatalogNote: this is a different concept from
TournamentEvent(a per-tournament event instance with room/building/volunteers-needed, renamed from the old tournament-scopedEventin this same commit range).Event/EventCategoryhere is a global catalog used only for tagging user experience entries — don't confuse the two.EventCategory:id,name(unique)Event:id,name(unique),category_idFK toEventCategory(required)GET/POST/PATCH/DELETE /events/{event_id}/,GET/POST/PATCH/DELETE /event-categories/{category_id}/DELETEis a hard delete on both, blocked with 409 if the row is still referenced (an event with experience entries, or a category with events)app/db/seed_canon_events.py, idempotentINSERT ... ON CONFLICT DO NOTHING)test_events.py)UserCompetitionExperiencetableid,user_idFK,event_idFK,school,notes/users/me/competition-experience/:POST,PATCH /{id}/,DELETE /{id}/UserVolunteerExperiencetableid,user_idFK,tournament_name(required),year(required),event_idFK (nullable — some roles are tournament-wide staff not tied to a specific event),role(bounded string),notes(JSON:{event, other})TournamentMembership/Tournament; auto-populating entries from archived NEXUS tournaments is future work, not part of this PRevent_idornotes.event(a free-text event name) is set/users/me/volunteer-experience/:POST,PATCH /{id}/,DELETE /{id}/, same 404-on-not-owner check as competition experienceUsermodel changeshas_competition_experienceandhas_volunteer_experience(Boolean, nullable=True) —null=unanswered,False=explicitly none,True=claims entries existcompetition_expandvolunteering_exp(Text columns) — confirmed no real data existed before droppingapp/core/profile_status.py(not a stored property):compute_missing_profile_fields(user)→list[str], used byUserMeFullResponse.missing_profile_fieldsis_profile_complete(user)→bool, used byUserMeSlimResponse.is_profile_completehas_*_experience is None→ incomplete;False→ skipped (explicitly none);Truewith no matching entries → still incompleteReads
GET /users/me/?full=truereturnsUserMeFullResponsewith nestedcompetition_experience/volunteer_experience, eagerly loaded viaselectinloadGET /admin/users/{user_id}/(admin) returns the same nested lists viaUserFullResponse, but lazy-loaded (not eager)GET /auth/me/was removed and folded intoGET /users/me/to reduce ambiguity — any remaining callers need to migratecheck_if_email_existsnow excludes the current user's own row, fixing a 409 that fired when a user PATCHed their profile without changing their emailAlso included — frontend wiring
This range also sweeps in frontend commits that support the tables above and were developed alongside them, not called out as separate tasks in the original issue:
ComboboxandRadioGroupcomponents (used for event/school selection on experience entries)useAuthupdated to match the newUserMeSlimResponse/UserMeFullResponsesplitAlso included — tournament membership age verification
This range also includes a related-but-separate feature that landed in the same commit stretch: age verification on
TournamentMembership.is_over_18/is_over_21(hybrid properties, computed from birthdate) added toTournamentMembership, so TDs can age-verify registered volunteersMembershiprenamed toTournamentMembership; temporary profile fields that had been stored there removed (superseded by theUser-level fields in this PR)Testing
test_events, competition/volunteer experience route tests, and profile-completeness coverage for all three boolean states across both Slim and Full responses?full=truereturns nested experience lists correctlyevent_id/notes.eventexactly-one-of validatorNotes
event_idonUserVolunteerExperienceis nullable — some roles are tournament-wide staff not tied to a specific eventTournamentMembership(see above) are unrelated to this issue's scope but included in this PR for commit-grouping reasons