Back to Portfolio
ShelterSync Card

ShelterSync

Full-stack animal shelter coordination platform

ReactTanStack RouterNode.jsExpressPostgreSQLPrismaZodZustandDocker

The Challenge

Animal shelters face critical coordination challenges: managing foster placements across families, tracking inventory across multiple locations, maintaining medical records, and balancing staff access with foster family permissions.

The system needed to:

  • Coordinate foster placements with real-time assignment tracking
  • Manage inventory (food, medicine, supplies) with expiration dates
  • Maintain comprehensive medical logs and preventive care records
  • Enforce role-based permissions (staff vs. foster access)
  • Create audit trails for compliance and tracking
Miro Board - Flowcharts and ERD

The Approach

We built ShelterSync using a modular, feature-based architecture that separates concerns across the frontend and backend. The design prioritizes scalability, auditability, and role-based security from the ground up.

Frontend: React with TanStack Router for navigation, Zustand for state management, and Tailwind CSS for styling. Each feature has its own set of pages and components.

Backend: Node.js/Express with PostgreSQL via Prisma ORM. We use Zod for schema validation and implement role-based permissions at the API level.

Batch-Based Inventory

Each batch (identified by expiration date) is a separate row with dedicated transactions for all movements, ensuring compliance and audit trails.

Transaction-Driven Audit

No direct quantity edits. All changes flow through transaction endpoints, creating an immutable record of every action.

Consolidated Endpoints

Single PATCH endpoints with an action parameter reduce API surface area while improving consistency and reducing error states.

Schema-Driven Validation

Zod schemas ensure type safety across frontend and backend, catching issues at request time before they reach business logic.

Technical Deep Dives

Inventory Batch System

Traditional inventory systems store quantity as a single number. ShelterSync creates a separate inventory row for each batch (identified by expiration date). This design achieves two critical goals:

First, it provides granular control over expiration dates - essential for food and medicine. Second, it creates a natural audit trail: each batch row's history tells the complete story of that inventory's lifecycle.

When a staff member checks out supplies, they select from specific batches and quantities are decremented on that batch row. For crate loans, an entire batch (the crate) moves between states: pending → active → returned.

Transaction Audit Trail

Every change to inventory is recorded as a transaction. There are two transaction types:

  • Distributed (Food & Medicine): Intake → immediate distribution, no return flow
  • Loan (Crates): Pending → Active → Returned lifecycle

This ensures compliance auditors can trace any discrepancy to the exact transaction. No data is overwritten; every state change creates a new record. This immutable pattern is foundational for correctness and accountability.

Role-Based Access Control

The system distinguishes between two user types: Staff (full control) and Foster Families (limited, read-mostly access). Rather than limiting at the page level, we enforce permissions at the API level.

Each endpoint's response filters fields based on user role. A foster family can view their assigned animals but not medical notes reserved for staff. A staff member can see everything. This centralized approach ensures security cannot be bypassed by client-side changes.

API Design Philosophy

The backend uses consistent plural naming (e.g., `/api/animals`, `/api/inventory-transactions`) and consolidates related actions into single endpoints with an `action` parameter instead of proliferating separate endpoints. This reduces the API surface area and makes the contract more discoverable.

For example, instead of `/api/animals/assign` and `/api/animals/unassign`, we use `PATCH /api/foster-assignments` with `action: 'assign' | 'unassign'`. This pattern appears throughout the API and improves consistency.

Process & Collaboration

Team Workflow (6 Developers)

Planning: Jira for ticket tracking and sprint planning

Communication: Discord for real-time screen shares and decisions

Git Workflow: Branch naming `ANIMALS-[number]-[description]`, always rebase against main before PR

Code Review: Peer reviews before merge, iterative feedback culture

Challenge: Managing 6 simultaneous developers, merge conflicts, keeping UI in sync with API changes

Jira Project Board

Jira Project Board showing team tasks and sprints

Deliverables

Successfully coordinated a relay-style demo video with all six team members, demonstrating the full system lifecycle from intake to foster assignment to medical tracking.

Visual Assets

ShelterSync Home Page

Database Schema

Database ERD showing Animals, Inventory, Transactions, Foster Assignments, and Medication tables

Results & Learnings

Outcomes

  • Fully functional system managing animals, inventory, medical logs, foster assignments, crate loans
  • Role-based access control enforced at API level, not just UI
  • Immutable audit trail for every inventory transaction
  • Demonstrated full-stack capability: React + Node + PostgreSQL

Key Learnings

  • Batch-based inventory modeling is essential for compliance and auditability
  • Enforcing permissions at API level prevents security bypasses
  • Iterative code review and feedback culture improves code quality and team cohesion

Project Demo