A full-stack web application for planning and managing the CAIC cocurricular calendar at IIT Delhi
- Overview
- Architecture
- Installation
- Configuration
- Usage
- NPM Scripts
- API Reference
- Database Schema
- Security
- Troubleshooting
The CAIC Cocurricular Calendar is a centralized tool for CAIC coordinators at IIT Delhi to plan, visualize, and manage the academic cocurricular calendar across both semesters. It supports the full 18-week semester structure including mid-sem exams, mid-sem break, end-sem exams, and post-exam periods.
- 📅 Visual semester grid with drag-and-drop event placement (admin)
- 🗓 Timeline view with inline editing (admin)
- 🔐 JWT-based admin authentication — public read-only, admins can edit
- 👥 Multi-admin support with an in-app admin management panel
- 🗄 PostgreSQL database backend
- ⚡ FastAPI REST API
caic-calendar/
├── .env ← single config file for the whole project
├── package.json ← root npm scripts (init-db, seed, dev, etc.)
├── scripts/
│ ├── init-db.js ← creates PostgreSQL tables
│ └── seed.js ← seeds default data + admin user
├── backend/ ← FastAPI (Python)
│ ├── main.py
│ ├── auth.py
│ ├── models.py
│ ├── schemas.py
│ ├── database.py
│ ├── requirements.txt
│ └── routes/
│ ├── auth_routes.py
│ ├── events.py
│ └── semdefs.py
└── frontend/ ← Vite + React
└── src/
├── App.jsx
├── main.jsx
├── AuthContext.jsx
├── api.js
├── CAICCalendar.jsx
├── LoginPage.jsx
└── AdminPanel.jsx
- Node.js 16+ and npm
- Python 3.10+
- PostgreSQL 15+ running locally
PostgreSQL must already be installed and running on your machine.
The default user is usuallypostgres. Adjust.envif yours differs.
git clone <repo-url> caic-calendar
cd caic-calendarcreatedb caic_calendarIf your setup needs a specific user:
createdb -U postgres caic_calendarEdit .env at the project root — this is the single config file for both the Node scripts and the Python backend:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=caic_calendar
DB_USER=postgres
DB_PASSWORD=
DATABASE_URL=postgresql://postgres:@localhost:5432/caic_calendar
SECRET_KEY=change-this-to-a-long-random-string-before-sharing
ACCESS_TOKEN_EXPIRE_MINUTES=480Generate a secure secret key:
python -c "import secrets; print(secrets.token_hex(32))"npm installThen install Python backend dependencies:
cd backend
pip install -r requirements.txt
cd ..npm run init-dbCreates all required PostgreSQL tables: users, events, semester_defs.
Safe to run multiple times — uses CREATE TABLE IF NOT EXISTS.
npm run seedInserts:
- Semester 1 & 2 definitions (Academic Year 2026-27)
- All 10 default events from the calendar
- A default admin account
Default admin credentials:
Username : admin
Password : changeme123
⚠️ Change this immediately after first login via the Admin Panel in the app.
Seeding skips rows that already exist — safe to run multiple times.
npm run devThis starts both servers concurrently:
- Backend → http://localhost:8000
- Frontend → http://localhost:5173
Or run them separately:
npm run backend # FastAPI only
npm run frontend # Vite only- PostgreSQL installed and running
-
createdb caic_calendar -
.envconfigured with correct DB credentials -
npm install -
pip install -r backend/requirements.txt -
npm run init-db -
npm run seed -
npm run dev - Open http://localhost:5173
- Login as
admin/changeme123 - Change the default password via Admin Panel → Manage Admins
All configuration lives in .env at the project root:
| Variable | Description | Default |
|---|---|---|
DB_HOST |
PostgreSQL host | localhost |
DB_PORT |
PostgreSQL port | 5432 |
DB_NAME |
Database name | caic_calendar |
DB_USER |
PostgreSQL user | postgres |
DB_PASSWORD |
PostgreSQL password | (empty) |
DATABASE_URL |
Full connection URL for the Python backend | assembled from above |
SECRET_KEY |
JWT signing key — change before sharing | placeholder |
ACCESS_TOKEN_EXPIRE_MINUTES |
JWT validity window | 480 (8 hours) |
- Open http://localhost:5173
- Click Admin Login (top right)
- Sign in with your credentials
- Edit controls appear: drag events between weeks, click event names to rename, click Remove to delete
- Use + Add Event to create new events
- Use Manage Admins to add or remove other admin accounts
The calendar is visible at http://localhost:5173 without logging in. All events are shown in read-only mode — no edit controls are visible.
npm run init-db # Create PostgreSQL tables (run once on setup)
npm run seed # Seed default events, semester defs, and admin user
npm run dev # Start both backend and frontend concurrently
npm run backend # Start FastAPI backend only (port 8000)
npm run frontend # Start Vite dev server only (port 5173)
npm run setup # Full first-time setup: install + init-db + seed| Method | Path | Description |
|---|---|---|
| GET | / |
Health check |
| GET | /events/ |
List events (?sem=1 to filter by semester) |
| GET | /semester-defs/ |
List semester definitions |
| Method | Path | Description |
|---|---|---|
| POST | /auth/login |
Get JWT token |
| GET | /auth/me |
Current user info |
| POST | /auth/users |
Create admin user |
| GET | /auth/users |
List all admin users |
| DELETE | /auth/users/{id} |
Delete admin user |
| POST | /events/ |
Create event |
| PATCH | /events/{id} |
Update event (partial) |
| DELETE | /events/{id} |
Delete event |
| PATCH | /semester-defs/{sem} |
Update semester definition |
Interactive docs: http://localhost:8000/docs
| Column | Type | Notes |
|---|---|---|
| id | SERIAL PK | |
| username | VARCHAR UNIQUE | |
| hashed_password | VARCHAR | bcrypt, cost 12 |
| is_admin | BOOLEAN | default true |
| is_active | BOOLEAN | default true |
| created_at | TIMESTAMP |
| Column | Type | Notes |
|---|---|---|
| id | SERIAL PK | |
| name | VARCHAR | |
| week | VARCHAR | "1"–"14" or "midExam", "midBreak", "endExam", "postExam" |
| day_in_week | INTEGER | 1–7 |
| duration_days | INTEGER | ≥ 1 |
| sem | INTEGER | 1 or 2 |
| type | VARCHAR | caic, academic, holiday, board |
| created_at | TIMESTAMP | |
| updated_at | TIMESTAMP | auto-updated via trigger |
| Column | Type | Notes |
|---|---|---|
| id | SERIAL PK | |
| sem | INTEGER UNIQUE | 1 or 2 |
| name | VARCHAR | |
| start_date | DATE | |
| end_date | DATE | |
| holidays | JSONB | [{"name": "Dussehra", "week": 8}] |
| updated_at | TIMESTAMP | auto-updated via trigger |
- Passwords are hashed with bcrypt (cost 12) — never stored in plaintext
- JWT tokens are stored in JS memory only — not in localStorage — so they cannot be stolen by XSS and clear on page refresh
- All write endpoints require a valid admin JWT
- The
.envfile contains secrets — add it to.gitignoreand never commit it
npm run init-db fails
- Make sure PostgreSQL is running:
pg_isready - Verify
DB_USERandDB_PASSWORDin.env - Make sure the database exists:
createdb caic_calendar
Backend fails to start
- Confirm you ran
pip install -r backend/requirements.txt - Verify
DATABASE_URLin.envmatches your local setup
Frontend shows "Connection Error"
- Make sure the backend is running on port 8000
- Check browser console for CORS errors
createdb: command not found
- Add your PostgreSQL bin to PATH, e.g.
/usr/lib/postgresql/15/bin/ - Or create the database via pgAdmin
CAIC Cocurricular Calendar — IIT Delhi 2026-27