Open
Conversation
- Rename _horses+ route directory to _animals+ with animalId params - Rename HorseListbox to AnimalListbox in listboxes component - Rename horseDateConflicts/renderHorseConflictMessage to animal equivalents - Update createHorse -> createAnimal in db-utils and seed - Update seed.ts to use prisma.animal.create Co-Authored-By: George Badulescu <gbadulescu@example.com>
…c copy - Rename HorseData -> AnimalData, HorseAssignment -> AnimalAssignment - Update volunteerTypes: horse leaders -> animal handlers with generic copy - Update siteName to TrotTrack Volunteer Portal, siteBaseUrl to trottrack.org - Rename getHorseImgSrc -> getAnimalImgSrc in misc.ts - Update EventWithAllRelations/EventWithVolunteers to use animals, animalHandlers Co-Authored-By: George Badulescu <gbadulescu@example.com>
- calendar/$eventId.tsx: animals/animalAssignments/animalHandlers, AnimalInfoPopover - calendar/$eventId.edit.tsx: AnimalListbox, animals, animalHandlersReq - calendar/index.tsx: animals loader, animalHandlers filter/tooltip, AnimalListbox - event-register.tsx: animalHandlers role type union - registration/unregistration emails: animalHandlers role type union - users.edit: animalHandler role instead of horseLeader - users.tsx: animal handler column header - email.tsx: animalHandler field instead of horseLeader - root.tsx: nav link updated to /admin/animals Co-Authored-By: George Badulescu <gbadulescu@example.com>
- Add signupOrg() to auth.server.ts: creates Org + admin User atomically in a single Prisma session transaction, connecting the admin role - Add /org-signup route with two-section form (org details + admin account) including slug generation, duplicate username/email/org validation - Add /org-setup redirect page for authenticated users without an org - Update landing page hero: TrotTrack branding + Register Your Organization CTA alongside existing volunteer signup button Co-Authored-By: George Badulescu <gbadulescu@example.com>
- users.delete: add requireOrgMember, use findFirst with orgId - users.edit: add requireOrgMember, fix isHorseLeader -> isAnimalHandler - users.promote: add requireOrgMember, verify userId belongs to org before update - $eventId.delete: add requireOrgMember, scope event lookup by orgId - email.tsx: scope getRecipientsFromRoles and getUpcomingEvents by orgId ensuring bulk emails only go to users in the same organization
- $eventId.edit: add requireOrgMember, scope instructors/animals/event queries by orgId; verify event ownership before update - super-admin/orgs: new page listing all organizations with user/animal/ event counts, protected by requireSuperAdmin
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.
This is the first pass at turning EVS into a proper multi-tenant platform.
The three big things:
1. Any org can sign up
There's now a public /org-signup page where a nonprofit can register their organization, pick their animal type, and create their admin account. No manual setup needed on our end.
2. Data is fully isolated between orgs
Every event, animal, and user is scoped to an org. Tested this with two orgs side by side — they can't see each other's data at all.
3. Not just horses anymore
Renamed the Horse model to Animal with a species field. Roles and all the copy throughout the app are now animal-agnostic, so this works for any nonprofit regardless of what animals they work with.
Also added a Super Admin view at /super-admin/orgs to see all orgs in the system with their stats.
To test locally: