A full-stack TypeScript staffing schedule generator with TanStack Router frontend and comprehensive data models for managing staff assignments, constraints, and scheduling requirements.
This project provides a robust scheduling system for managing staff assignments with:
- TanStack Router frontend for building the user interface
- TypeScript data models for staff members, requirements, and schedules
- Comprehensive validation with detailed error messages
- Flexible qualification matching and constraint handling
- Statistical analysis of schedules and workload distribution
- Modern React application with TanStack Router
- Server-side rendering (SSR) support
- File-based routing
- Tailwind CSS styling
- Cloudflare Workers deployment ready
- StaffMember: Staff information with qualifications and constraints
- StaffConstraint: Time-based availability and preferences
- ScheduleRequirement: Input requirements with time slots
- StaffAssignment: Staff-to-slot mappings
- Schedule: Complete schedules with analytics
npm installRun the development server:
npm run devThe app will be available at http://localhost:3000
npm run buildThis will:
- Build the TypeScript type definitions
- Build the frontend application
Run all tests:
npm run testRun type model tests:
npm run test:typesDeploy to Cloudflare Workers:
npm run deploy.
├── src/
│ ├── components/ # React components
│ ├── routes/ # TanStack Router routes
│ ├── types/ # TypeScript data models
│ │ ├── StaffMember.ts
│ │ ├── StaffConstraint.ts
│ │ ├── StaffSlot.ts
│ │ ├── ScheduleRequirement.ts
│ │ ├── StaffAssignment.ts
│ │ └── Schedule.ts
│ ├── __tests__/ # Unit tests for data models
│ └── examples/ # Example usage
├── public/ # Static assets
└── dist/ # Build output
Represents a staff member with:
- Name and numeric rank
- Start of service date
- List of qualifications/certifications
- Optional scheduling constraints
View StaffMember Documentation →
Represents scheduling constraints and preferences:
- Time period with start and end timestamps
- Preference level: unavailable, not preferred, neutral, or preferred
- Optional reason/note
View Staff Constraints Documentation →
Represents scheduling requirements (inputs):
- StaffSlot: Individual time slots with required qualifications
- ScheduleRequirement: Collection of slots within a time window
View Schedule Requirements Documentation →
Represents scheduling results (outputs):
- StaffAssignment: Maps a staff member to a staff slot with start/end times
- Schedule: Collection of assignments with unfilled slots tracking
View Schedule Assignment Documentation →
import { createStaffMember } from '@/types';
const staff = createStaffMember({
name: 'Dr. Sarah Johnson',
rank: 5,
startOfService: new Date('2018-03-15'),
qualifications: ['MD', 'Board Certified', 'Emergency Medicine'],
});import { createScheduleRequirement, createStaffSlot } from '@/types';
const requirement = createScheduleRequirement({
id: 'week-46-2025',
name: 'Week of November 17-23, 2025',
scheduleStart: new Date('2025-11-17T00:00:00'),
scheduleEnd: new Date('2025-11-23T23:59:59'),
staffSlots: [
createStaffSlot({
name: 'Morning Shift Nurse',
startTime: new Date('2025-11-17T07:00:00'),
endTime: new Date('2025-11-17T15:00:00'),
requiredQualifications: ['RN', 'BLS'],
}),
],
});import { createStaffConstraint } from '@/types';
const constraint = createStaffConstraint({
startTime: new Date('2025-11-20T00:00:00'),
endTime: new Date('2025-11-21T23:59:59'),
preference: 'unavailable',
reason: 'Vacation',
});This project uses TanStack Router with file-based routing. Routes are managed as files in src/routes.
To add a new route, create a new file in the ./src/routes directory:
// src/routes/schedule.tsx
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/schedule')({
component: ScheduleComponent,
});
function ScheduleComponent() {
return <div>Schedule Page</div>;
}Use the Link component for SPA navigation:
import { Link } from '@tanstack/react-router';
<Link to="/schedule">View Schedule</Link>This project uses Tailwind CSS for styling.
This project uses:
# Run all tests
npm run test
# Run type model tests
npm run test:types
# Run with coverage
npm run test -- --coverage- Frontend: React 19, TanStack Router
- Styling: Tailwind CSS 4
- Language: TypeScript 5.7
- Testing: Vitest, Jest
- Deployment: Cloudflare Workers
- Build Tool: Vite
npm run dev- Start development servernpm run build- Build for productionnpm run build:types- Build TypeScript typesnpm run test- Run testsnpm run test:types- Run type model testsnpm run deploy- Deploy to Cloudflarenpm run preview- Preview production buildnpm run lint- Lint codenpm run format- Format code with Prettier
For a detailed implementation roadmap, see IMPLEMENTATION_PLAN.md.
MIT
Ethan Harstad