SST Hostel Leave System is a production-grade leave and movement management platform for Scaler School of Technology (SST) hostel operations.
The system manages:
- Leave requests and leave extensions
- Config-driven approval workflows (no hardcoded approval chains)
- Parent approvals via tokenized email/portal links
- QR-based hostel entry/exit tracking with a guard scanner
- Overdue leave detection and resolution
- Multi-channel notifications (SMS, email, Slack)
- Policy enforcement and dynamic leave forms
- Audit trails for every state transition
The platform is designed as a configurable workflow engine rather than a hardcoded leave approval application, allowing future expansion into broader institutional operations.
- Leave approval is not movement. Permission (leave) and reality (movement) are independent systems — a student may have an approved leave while still inside the hostel.
- Leave extensions are not new leaves. Extending a leave always uses
leave_extensions; a new leave request is never created. - Workflows are configuration-driven. Approval chains are read from
workflow_definitions/workflow_steps, never hardcoded (e.g. noParent → Wardenliterals). - Forms are dynamic. Leave type forms are driven by
leave_types.form_schema; no database columns are added per form field. - QR represents authorization. QR tokens only carry a token and identifier — never history.
- Hostel leave workflows with dynamic leave categories
- Leave extensions (multi-step approval, QR window growth)
- Holiday-aware submission, dynamic forms, policy engine
- Vacation / stay requests, group leave support
- Multi-step configurable approval chains per workflow definition
- Parent approvals via tokenized email/portal links
- POC / Admin / Super Admin approval queues
- Workflow snapshots for audit consistency, parent override flows
- QR-based hostel exit/entry with scan validation
- Guard scanner UI (
@yudiel/react-qr-scanner) - Movement state machine (
IN_HOSTEL,OUTSIDE_HOSTEL, ...) - Overdue detection, overdue returns, QR expiry invalidation
- See
docs/movement-contract.mdfor the full contract
- SMS via Infobip (India DLT compliant)
- Email via AWS SES with Resend fallback
- Slack bot alerts for staff (incl. POC-channel targeting)
- Provider abstraction, template engine, retry-safe delivery
- Outbox pattern for event-driven notification/audit delivery (DB-backed, no Redis)
- Vercel Cron jobs for outbox delivery, QR cleanup, and daily maintenance
- Audit logging on every state change; rate limiting
- Bounded batch processing for cron jobs
- Super Admin configuration: workflows, leave types, hostels, departments, academic groups, policies, notification rules/templates, users, parents, students
- Leave / movement / rejection analytics with occupancy insights
- Document uploads (Cloudinary) with MIME/size validation
The codebase enforces a strict architectural flow:
Route → DTO Validation → Service → Repository → Database
- Routes handle auth, authorization, validation, and response mapping only
- DTOs define Zod contracts for every externally supplied payload
- Services own workflows, approvals, notifications, policy evaluation, QR generation, and movement coordination
- Repositories are thin and own select/insert/update/delete only
- Schema files define persistence structure only
auth academics hostel leave movement policy notification audit
Each domain owns its schema, repositories, services, and business rules. Cross-domain coupling is avoided.
State changes publish events into an outbox_events table inside the same transaction. A cron-driven worker delivers them (notifications, QR scans, leave lifecycle events) with retries and crash recovery (claimed_at requeue).
├── docs/ Architecture & engineering documentation
├── scripts/ Migrations (migrate-00XX.ts), seed & ops scripts
├── src/
│ ├── app/
│ │ ├── (auth)/ Clerk sign-in / redirect / sso-callback
│ │ ├── (dashboard)/ admin · guard · poc · student · super-admin · profile
│ │ ├── parent-approve/ Parent approval pages (tokenized links)
│ │ ├── api/v1/ REST API per domain (leaves, movements, qr, ...)
│ │ ├── api/cron/ Vercel cron endpoints (outbox, cleanup, maintenance)
│ │ └── api/webhooks/ Clerk webhooks
│ ├── components/ shadcn/ui primitives + shared components
│ ├── constants/ Enums & configuration constants
│ ├── db/
│ │ ├── schema/ Drizzle schema per domain
│ │ ├── repositories/ Thin data-access layer per domain
│ │ ├── seed/ Seed data (roles, workflows, leave types, ...)
│ │ └── drizzle/ Generated migrations
│ ├── dto/ Zod contracts (request/response schemas)
│ ├── features/ Feature-scoped UI (components + hooks)
│ ├── hooks/ Shared data hooks (SWR-based)
│ ├── lib/ Infrastructure (auth, db, errors, api, messaging, crypto)
│ ├── providers/ React providers
│ ├── services/ Domain services (leave, movement, notification, outbox, ...)
│ ├── types/ · utils/
├── tests/ Vitest suites
├── .env.example
├── AGENTS.md Engineering constitution for AI agents & contributors
├── drizzle.config.ts
├── vercel.json Cron schedules
└── package.json| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript 5 |
| Database | PostgreSQL (Neon serverless) |
| ORM | Drizzle ORM |
| Authentication | Clerk (staff/student); parent approvals via tokenized links |
| Validation | Zod 4 |
| Forms | react-hook-form + zodResolver |
| Data Fetching | SWR |
| Styling | Tailwind CSS 4 |
| UI Components | shadcn/ui, lucide-react, recharts, sonner |
| SMS | Infobip (India DLT) |
| AWS SES (Resend fallback) | |
| Chat | Slack Bot API |
| File Storage | Cloudinary |
| QR | qrcode + @yudiel/react-qr-scanner |
| Background Jobs | Outbox pattern + Vercel Cron (no Redis) |
| Tests | Vitest + Testing Library |
| Lint / Format | ESLint 9, Prettier, husky, commitlint, lint-staged |
| Package Manager | pnpm |
- Node.js 20.9+
- pnpm
- A PostgreSQL database (local or Neon)
# Clone repository
git clone https://github.com/Scaler-Innovation-Labs/SST-Hostel-Leave.git
cd SST-Hostel-Leave
# Install dependencies
pnpm install
# Configure environment variables
cp .env.example .env.local
# Apply database migrations in order
# (schema evolution is tracked via numbered scripts)
npx tsx scripts/migrate-0003.ts
# ... run each migrate-*.ts script up to the latest, e.g.:
npx tsx scripts/migrate-0026-audit-p1-cleanups.ts
# Seed initial data (roles, workflows, leave types, users, ...)
npx tsx scripts/clear-and-seed.ts
# Start the development server
pnpm devMigrations are standalone scripts under scripts/ (npx tsx scripts/migrate-00XX.ts). Run them in numeric order against your database.
See .env.example for the full list with comments.
# Database
DATABASE_URL=postgresql://user:password@host:5432/dbname
# Next.js auth secret
AUTH_SECRET=
# Clerk (authentication)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
CLERK_WEBHOOK_SECRET=
# Email provider (ses | resend | sst)
EMAIL_PROVIDER=sst
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
SES_FROM_EMAIL=
RESEND_API_KEY=
# SMS (Infobip)
INFOBIP_BASE_URL=https://api.infobip.com
INFOBIP_API_KEY=
INFOBIP_SENDER_ID=Scaler
INFOBIP_DLT_CONTENT_TEMPLATE_ID=
INFOBIP_DLT_PRINCIPAL_ENTITY_ID=
INFOBIP_CUSTOM_DOMAIN=
# Slack
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_CHANNEL_ID=C1234567890
SLACK_POC_CHANNEL_ID=
# Cloudinary (document storage)
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
# Cron jobs
CRON_SECRET=
# App settings
NEXT_PUBLIC_BASE_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000
LOG_LEVEL=debugDefined in vercel.json:
| Endpoint | Schedule | Purpose |
|---|---|---|
/api/cron/outbox |
every 5 min | Deliver pending outbox events (retry-safe) |
/api/cron/cleanup |
every 6 hrs | QR pass expiry invalidation + audit logging |
/api/cron/maintenance |
daily 03:00 | Maintenance: rate-limit pruning, reconciliation |
pnpm test # run tests once (Vitest)
pnpm test:watch # watch mode
pnpm test:coverage # coverage report
pnpm typecheck # TypeScript type checking
pnpm lint # ESLint
pnpm lint:fix # ESLint with autofix
pnpm format # PrettierThe suite covers services, repositories, routes, and state machines (153 test files, 871 tests). Commits are enforced with commitlint (conventional commits) and lint-staged via husky. The project also ships pnpm audit:architecture (see scripts/audit-architecture.sh).
docs/architecture/system-overview.md— purpose, core principles, domain modeldocs/architecture/leave-flow.md— leave lifecycledocs/architecture/movement-flow.md— movement lifecycledocs/movement-contract.md— QR/movement contracts (T-series rules)docs/architecture/domain-rules.md— domain responsibilities and boundariesdocs/architecture/engineering-rules.md— engineering conventionsdocs/architecture/backend-development-workflow.md— backend dev workflowdocs/architecture/code-review-checklist.md— review checklistdocs/workflows.md— config-driven workflow enginedocs/ui-system.md— UI system and componentsdocs/folder-structure.md— folder structure referencedocs/decisions.md— architecture decisionsAGENTS.md— engineering constitution (layering, naming, error handling, review rules)
This project is licensed under the MIT License.
Copyright (c) 2026 SST Hostel Leave System