frontend fetches volunteer
frontend fetches shifts
frontend fetches programs
frontend joins manually
Nonprofit operations backend
The backend had to reflect real event coordination: what is public, what is private, what admins can see, and how volunteers actually register.
Operation Surf is a nonprofit operations platform for coordinating programs, shifts, volunteer profiles, and signups. The case study is not just about CRUD; it is about shaping data flows so staff and volunteers see the right information at the right time.
The strongest backend work lives in the API boundaries: filtering private program data, enriching signup responses with shift/program details, trimming admin-only fields, and validating inputs that have real operational meaning.
This project appears under Projects on my resume.

System flow
API boundaries and permissions
The backend owns access rules and returns coordination-shaped data before the UI sees it.
frontend fetches volunteer
frontend fetches shifts
frontend fetches programs
frontend joins manually
single enriched API response
admin-only fields removed from public payloads
signup responses include shift and program context
GET /api/programsGET /api/signups/:idPOST /api/volunteersPATCH /api/admin/shifts/:idProgram has many Shifts
Volunteer has many Signups
Signup belongs to Volunteer and Shift
Project artifacts
Real project media appears where available, with placeholder cards only where sanitized screenshots are still needed.





Technical deep dives
The UI should not be the only permission boundary.
The API builds an auth context from the session and environment-defined admin identifiers. Program and day queries then filter private data for unauthenticated users, so access rules are enforced before data leaves the server.
A signup ID alone is not what a volunteer needs to see.
The registered-shifts view joins signups to day and program records, returning a payload that is directly useful to the frontend. That avoids making the UI reconstruct coordination context from multiple unrelated responses.
A false waiver value is valid data, not a missing field.
The signup route explicitly handles the waiver boolean so false does not get rejected by a generic truthiness check. That small branch matters because operational data often has meaningful false values.
Animated artifact
The workflow diagram shows access decisions happening at the route/data layer before payloads reach the UI.
Code evidence
Snippets are trimmed for readability and paired with the source file they came from.
Operation-Surf/src/app/api/volunteer/route.ts
const payload = authContext.isAdmin
? volunteers.map(toAdminVolunteerPayload)
: volunteers.map(toNonAdminVolunteerPayload);The route does not rely on the frontend to hide sensitive fields. It returns different data shapes based on server-side auth context.
Operation-Surf/src/app/api/signup/route.ts
const shifts = await Day.find({ dayId: { $in: shiftIds } });
const programs = await Program.find({ programId: { $in: programIds } });
return signups.map((signup) => ({
signupId: signup.signupId,
shift: shiftById.get(signup.shiftId),
program: programById.get(programId),
}));This turns normalized database records into the workflow-shaped response the UI needs for volunteer coordination.
Outcome and reflection
Operation Surf shows my backend thinking: data models are not neutral. If the API mirrors how people coordinate work, the software reduces friction instead of creating another admin chore.