Open-source shift planning software with AI assistance
Self-Hosted · Real-Time Collaboration · AI-Powered Optimization
Schichtplaner (German for "shift planner") is a fully-featured, self-hosted solution for shift scheduling and workforce management. Built with a modern tech stack, it covers everything from shift planning and time tracking to AI-powered schedule optimization — with no dependency on external SaaS services.
Note: The application UI is in German. Internationalization (i18n) support is planned for future releases.
- Flexible weekly schedules — create shifts with division assignments
- 4 schedule views — Flexible, Classic, Employee-centric, Monthly overview
- Live sessions — real-time shift booking via Socket.IO with deadline controls
- Wish plans (Mod-Requests) — employees can submit shift preferences
- PDF export — download schedules as PDF
- Briefings — weekly briefings per schedule
- Role system — Owner > Admin > Manager > Employee
- Divisions — color-coded divisions with member assignment
- Activation links — secure invitation via token
- Target hours — individual weekly hour goals per employee
- Notes — internal employee notes (manager+ only)
- 3 tracking modes — Manual (from/to), Stopwatch (live tracking), Manual duration
- Categories — configurable time categories per organization
- Warnings — automatic alerts when exceeding maximum hours
- Access control — enable time tracking for all or selected employees
- Categories — vacation, sick leave, and custom categories
- Approval workflow — Pending → Approved / Declined
- Holidays — holiday management with regional support (German federal states)
- Monthly reports — working hours per employee at a glance
- Target/actual comparison — automatic comparison with target hours
- PDF export — download reports as PDF
- Messaging — internal messaging with reply threads
- File management — folder structure with upload (S3/MinIO)
- Discussion forum — topics with posts for cross-team communication
Requires an Anthropic API key. All AI features are feature-gated and can be disabled per organization.
- Auto-Planner — AI-powered schedule suggestions based on availability
- Anomaly detection — automatic detection of unusual patterns
- Smart Briefing — AI-generated weekly summaries
- Forecasting — demand predictions based on historical data
- Chat — AI assistant for planning questions
- Multi-tenancy — multiple organizations on a single instance
- Dark mode — theme switching
- Real-time updates — Socket.IO for live changes
- Responsive — fully mobile-optimized
- German UI — complete German user interface
| Category | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Frontend | React 19, Tailwind CSS 4, shadcn/ui, Radix UI |
| Language | TypeScript 5 |
| Database | PostgreSQL 16, Prisma 7 ORM |
| Auth | NextAuth.js v5 (JWT, Credentials) |
| Real-time | Socket.IO |
| AI | Anthropic SDK (Claude) |
| State | Zustand + React Query |
| File Storage | MinIO / S3-compatible |
| Caching | Redis |
| Deployment | Docker + Caddy (Auto-HTTPS) |
The complete schema contains 23 models. Here's an overview of the core relationships:
erDiagram
User ||--o{ OrganizationMember : "member of"
User ||--o{ Booking : "books"
User ||--o{ TimeRecord : "tracks"
User ||--o{ Absence : "requests"
Organization ||--o{ OrganizationMember : "has"
Organization ||--o{ Division : "divisions"
Organization ||--o{ Schedule : "schedules"
Organization ||--o{ Branch : "branches"
Organization ||--|| OrgSettings : "AI settings"
Schedule ||--o{ Shift : "shifts"
Schedule ||--o| LiveSession : "live"
Shift ||--o{ Booking : "bookings"
Shift }o--o| Division : "division"
Division ||--o{ DivisionMember : "members"
LiveSession ||--o{ LiveDay : "days"
LiveSession ||--o{ LiveLog : "logs"
Message }o--o| Message : "reply to"
Message ||--o{ MessageRecipient : "recipients"
Topic ||--o{ TopicPost : "posts"
User {
string email UK
string firstName
string lastName
string locale
}
Organization {
string name
enum nameFormat
enum scheduleVisibility
}
OrganizationMember {
enum role "OWNER|ADMIN|MANAGER|EMPLOYEE"
boolean isActive
float targetHoursPerWeek
}
Schedule {
int weekNumber
int year
boolean isPublic
}
Shift {
int dayOfWeek
string shiftFrom
string shiftTo
int maxEmployees
}
Booking {
datetime bookedAt
}
TimeRecord {
date date
string timeFrom
string timeTo
enum type "MANUAL|WATCH|DURATION"
}
Absence {
date dateFrom
date dateTo
enum status "PENDING|APPROVED|DECLINED"
}
OrgSettings {
boolean aiEnabled
boolean aiAutoPlanner
boolean aiChatEnabled
boolean aiForecast
}
See the full ER diagram with all 23 models at
docs/db-schema.md.
- Node.js 20+
- Docker & Docker Compose
- (Optional) Anthropic API key for AI features
git clone https://github.com/lennystepn-hue/schichtplaner.git
cd schichtplanercp .env.example .envEdit the .env file:
DATABASE_URL="postgresql://schichtplaner:schichtplaner@localhost:5432/schichtplaner"
NEXTAUTH_SECRET="your-secret-key" # openssl rand -base64 32
NEXTAUTH_URL="http://localhost:3000"
ANTHROPIC_API_KEY="sk-ant-..." # Optional, for AI features
REDIS_URL="redis://localhost:6379"
S3_ENDPOINT="http://localhost:9000"
S3_ACCESS_KEY="minioadmin"
S3_SECRET_KEY="minioadmin"
S3_BUCKET="schichtplaner"
APP_URL="http://localhost:3000"docker compose up -d postgres redis minionpm install
npx prisma migrate dev
npx prisma db seed# Terminal 1: Next.js
npm run dev
# Terminal 2: Socket.IO server (for real-time features)
npm run dev:serverOpen http://localhost:3000.
Demo login:
| Role | Password | |
|---|---|---|
| Admin | admin@demo.de |
password123 |
For a full production setup with automatic HTTPS:
# Configure production environment
cp .env.production.example .env
# Start all services
docker compose up -dThe docker-compose.yml automatically starts:
- PostgreSQL 16 — database
- Redis 7 — caching
- MinIO — file storage (S3-compatible)
- Next.js App — application (port 3000)
- Caddy — reverse proxy with auto-HTTPS (Let's Encrypt)
schichtplaner/
├── prisma/
│ ├── schema.prisma # Database schema (23 models)
│ └── seed.ts # Demo data
├── src/
│ ├── app/
│ │ ├── (auth)/ # Login, registration, activation
│ │ ├── (dashboard)/ # All protected pages
│ │ │ ├── schedule/ # Shift planning (4 views)
│ │ │ ├── employees/ # Employee management
│ │ │ ├── divisions/ # Divisions
│ │ │ ├── time/ # Time tracking
│ │ │ ├── reporting/ # Reports
│ │ │ ├── portal/ # Messages, files, forum
│ │ │ ├── ai/ # AI chat & insights
│ │ │ └── settings/ # Settings
│ │ └── api/ # REST API (50+ endpoints)
│ ├── components/
│ │ ├── ui/ # shadcn/ui primitives
│ │ ├── schedule/ # Schedule components
│ │ ├── layout/ # Sidebar, navigation
│ │ └── ... # Feature-specific components
│ └── lib/
│ ├── auth.ts # NextAuth configuration
│ ├── db.ts # Prisma singleton
│ ├── ai/ # Claude AI integration
│ ├── hooks/ # Custom React hooks
│ └── socket.ts # Socket.IO client
├── server.ts # Socket.IO server
├── docker-compose.yml # Docker orchestration
├── Dockerfile # Multi-stage production build
└── Caddyfile # Reverse proxy config
npm run dev # Next.js dev server
npm run build # Production build
npm run lint # ESLint
npm run dev:server # Socket.IO server (watch mode)
npx prisma migrate dev # Database migrations
npx prisma generate # Regenerate Prisma client
npx prisma db seed # Load demo data
npx tsc --noEmit # TypeScript type checkContributions are welcome! Please read CONTRIBUTING.md for details on our workflow.
This project is licensed under the MIT License.
Built with Next.js, React, Prisma, and lots of coffee.