I built ShiftSync as a web-based scheduling platform for Coastal Eats, a fictional restaurant group operating across multiple locations and time zones. I designed it to solve the complexities of real-world workforce management by balancing manager control with staff flexibility and labor law compliance.
I built this platform to address critical pain points in hospitality management:
- Coverage Gaps: Preventing shifts from going unfilled.
- Overtime Control: Real-time tracking to prevent spiraling labor costs.
- Fairness: Equitable distribution of "premium" shifts (e.g., weekend nights).
- Visibility: A centralized view for corporate oversight across all locations.
Based on the requirements for Coastal Eats, I made the following technical and domain assumptions during development:
- Single Organization: I scoped the platform to a single organization (Coastal Eats). Multi-tenancy is handled via
locationId. - Manager Data Isolation: I strictly restrict managers to seeing staff, schedules, and analytics for locations they are assigned to manage. Corporate Admins maintain global visibility.
- Staff Swap Visibility: Staff members can see all other staff in the organization when requesting a swap to facilitate cross-location coverage. However, I only allow selection of "qualified" peers (those with the required skill and location certification).
- Shift Skills: I modeled a single shift to require exactly one primary skill (e.g., "Bartender"). Shifts needing multiple distinct skills are modeled as separate parallel shift records.
- Group Assignments: I designed a single shift record to accommodate multiple staff members (
headcountNeeded> 1) to prevent duplicating identical shift definitions. - Timezone Robustness: I built all compliance calculations (10-hour rest, availability) to use
Intl.DateTimeFormatwith explicit timezone support (e.g.,America/Los_Angeles). This ensures that a manager in Nairobi (EAT) can accurately schedule a staff member in California (PDT) without "off-by-one-day" errors. - 48-Hour Schedule Lock: To ensure operational stability, I prevent managers from editing or unpublishing shifts within 48 hours of their start time. Admins can bypass this lock for emergency adjustments.
- Unified Swap/Drop Model: I modeled a shift "drop" (putting a shift up for grabs) as a
swapRequestwith anulltarget user. - Peer Rejection & Withdrawal: Staff members can decline incoming swap requests, and requesters can withdraw pending requests, automatically reverting shift assignments to their original state.
- Regret Swap Logic: If a manager modifies a shift's critical details (time, location, or skill), I built the system to automatically cancel any associated pending swap or drop requests.
- Marketplace Guardrails: I limit staff members to three active pending requests (swaps or drops) to prevent schedule churn.
- Shared Type Safety: I use a unified
@shiftsync/data-accesslibrary containingclass-validatordecorated DTOs, serving as the single source of truth for both API contracts and database schema. - Repository Pattern Architecture: I designed all NestJS business logic to operate strictly independent of database implementation. Raw
drizzle-ormtransactions and complex aggregations are tightly encapsulated within domain-driven repositories, injected globally via@shiftsync/data-access.
- Constraint Enforcement: Prevents double-booking, ensures 10-hour rest periods, and validates staff skills/certifications.
- Multi-Location Support: Handles staff certified at different branches across various time zones.
- Conflict Resolution: Provides automated suggestions for alternative staff when constraints are violated.
- Peer-to-Peer Swaps: Staff can request swaps or offer shifts for "grabs."
- Manager Approval Workflow: Maintains schedule integrity through a multi-step approval process.
- Real-Time Updates: Instant notifications for all parties involved in a swap via WebSockets.
- Labor Law Alerts: Automated warnings for weekly (40h) and daily (8h/12h) limits.
- Consecutive Day Tracking: Tracks 6th and 7th consecutive workdays with mandatory manager overrides.
- Fairness Score Index: Analytical reports on shift distribution and "premium" shift equity, normalized from 0-100.
- Live Dashboards: "On-duty now" view showing active staff across all locations.
- Shared Notification State: A unified unread counter that stays synced across all browser tabs in real-time.
- Full Audit Trail: Comprehensive logs of every schedule modification (Who, When, Before/After) for accountability.
- Monorepo Management: Nx
- Frontend: Next.js (TypeScript, Tailwind CSS, Lucide React)
- Backend: NestJS (TypeScript, WebSockets/Socket.io)
- Database: PostgreSQL with Drizzle ORM
- Testing: Jest (Server), Playwright (Client)
- Node.js (v20+)
- Docker & Docker Compose
npm installThe easiest way to run the entire stack (Frontend, Backend, and Database) is using Docker Compose.
-
Configure Environment: Create a
.envfile in the root directory:POSTGRES_PASSWORD=your_secure_password DATABASE_URL=postgresql://postgres:your_secure_password@localhost:5432/shiftsync?sslmode=disable JWT_SECRET=your_secret_key
-
Launch the Stack:
docker-compose up --build
-
Access the Applications:
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001/api
I wrote these to verify complex business logic, labor law compliance, and database state.
npx nx e2e server-e2eThese simulate end-to-end user journeys including Audit Trails, Fairness UI, and Staff Swap flows.
npx nx e2e client-e2eNote: The client suite uses a single worker and handles automated database seeding via a global setup.
npm run db:seed| Role | Timezone | Scope / Details | |
|---|---|---|---|
| Admin | admin@coastaleats.com |
America/New_York |
Global visibility & 48h lock bypass |
| Manager | bob.manager@coastaleats.com |
America/New_York |
Manages Downtown & Uptown (NY) |
| Manager | diana.manager@coastaleats.com |
America/Los_Angeles |
Manages Beach Grill (LA) |
| Staff | charlie.staff@coastaleats.com |
America/New_York |
NY certified (Unavailable Mondays) |
| Staff | dave.staff@coastaleats.com |
America/Chicago |
NY certified (Unavailable Tuesdays) |
| Staff | eva.staff@coastaleats.com |
America/Denver |
Uptown certified (Unavailable Wednesdays) |
| Staff | frank.staff@coastaleats.com |
America/Los_Angeles |
NY & Uptown certified (24/7 available) |
| Staff | grace.staff@coastaleats.com |
America/Los_Angeles |
Beach Grill certified |
| Staff | heidi.staff@coastaleats.com |
America/Los_Angeles |
Beach Grill certified |
| Staff | ivan.staff@coastaleats.com |
America/Los_Angeles |
Beach Grill certified (Available for swaps) |
| Staff | judy.staff@coastaleats.com |
America/Los_Angeles |
Beach Grill certified (Available for swaps) |
# Generate & Push Schema
npm run db:push
# Seed Data
npm run db:seed
# Start Backend
npx nx serve server
# Start Frontend
npx nx serve clientThis project is licensed under the MIT License - see the LICENSE file for details.
