A lightweight, web-based booking system for U2ACN2/iThemba Labs instruments.
Built with Flask + Neon (Postgres) + Render so students can book lab time online and admins can manage schedules.
- Lab list homepage with links to each instrument
- Booking pages per lab
- Submit user details + experiment/sample details
- Choose a date/time manually (single slot)
- Select multiple slots from the “available slots” table (next 2 weeks)
- Availability pages per lab
- Shows next 2 weeks, Monday–Friday, 08:00–16:00
- Booked slots are blocked
- Clicking an available slot pre-fills the booking form (where applicable)
- No overlapping bookings: the system blocks conflicts automatically
- Separate admin login per lab (different credentials)
- Admin dashboard per lab
- View all bookings for that lab
- Reserve slots (single or multiple) for maintenance/VIP usage
- Export bookings to CSV and Excel
- Edit booking time/date
- Delete a booking from the edit page (optional user email notification)
- If SMTP is configured, when an admin changes a booking time (or deletes it), the user can be automatically notified by email.
- Email settings are not stored in code — they are set via environment variables on Render.
/
Landing page listing all available labs./labs/furnace
Furnace booking page./labs/xps
XPS booking page./labs/<lab_slug>/availability
Availability table for next 2 weeks (Mon–Fri, 08:00–16:00).
Examples:/labs/furnace/availability/labs/xps/availability
/bookings/<id>
Booking confirmation page after submitting.
/admin/furnace
Furnace admin dashboard (redirects to furnace login if not logged in)/admin/xps
XPS admin dashboard/admin/<lab_slug>/login
Lab-specific admin login form/admin/<lab_slug>/edit/<id>
Edit booking time/date (and delete booking) for a single record
/admin/export/<lab_slug>.csv/admin/export/<lab_slug>.xlsx
/health
Returns JSON{ "status": "ok" }
Use this for Render Health Check Path and external uptime monitors.
- Availability is shown for the next 2 weeks.
- Only weekdays (Mon–Fri) are offered.
- Working hours are 08:00–16:00.
- By default, slots follow
SLOT_MINUTES(commonly 60 minutes).
Only two blocks per day:
- 08:00–12:00
- 12:00–16:00
- Uses Neon Postgres via
DATABASE_URL - Table name:
bookings - The app auto-migrates missing columns on startup to avoid schema mismatch errors.
- Falls back to a local SQLite database file (
bookings.sqlite3) ifDATABASE_URLis not set.
- Create a Neon project and database.
- Copy the connection string and set it as
DATABASE_URLon Render.
- Create a new Web Service from your GitHub repo.
- Build command:
pip install -r requirements.txt
- Start command:
gunicorn wsgi:app --bind 0.0.0.0:$PORT --workers 2 --threads 4 --timeout 120
- Health Check Path:
/health
DATABASE_URL
Neon Postgres connection string.
These control who can access each lab’s admin dashboard:
Furnace
ADMIN_FURNACE_EMAILADMIN_FURNACE_PASSWORD
XPS
ADMIN_XPS_EMAILADMIN_XPS_PASSWORD
APP_TZ(default:Africa/Johannesburg)
SLOT_MINUTES(default:60)
Global SMTP server
SMTP_HOST(e.g.,smtp.gmail.com)SMTP_PORT(commonly587)SMTP_USE_TLS(truerecommended)SMTP_FROM_NAME(display name in outgoing emails)
Per-lab sender overrides (recommended) If you want explicit SMTP credentials (instead of using admin login details):
-
SMTP_FURNACE_USER -
SMTP_FURNACE_PASSWORD -
SMTP_FURNACE_FROM -
SMTP_XPS_USER -
SMTP_XPS_PASSWORD -
SMTP_XPS_FROM
For Gmail, use an App Password (not your normal password).
Many organizations block SMTP auth without app passwords.
- Login to
/admin/<lab> - Use “Admin quick booking”
- Select multiple available slots (checkboxes) OR enter a manual slot
- Submit → slots become unavailable to users
- Admin dashboard → click Edit
- Change date/time
- Save
- If SMTP is configured, user receives an email notification.
- Admin dashboard → Edit
- Click Delete booking
- Confirm
- If SMTP is configured, user receives a cancellation email.
Most common causes:
DATABASE_URLmissing/incorrect- Old database schema missing columns (auto-migration usually fixes this)
- Render still running an older commit (clear build cache & redeploy)
Check: Render → Logs → submit booking → read the traceback.
- Missing
ADMIN_<LAB>_EMAIL/ADMIN_<LAB>_PASSWORDenv vars - Wrong credentials entered
- SMTP not configured (
SMTP_HOSTmissing) - Wrong SMTP password (Gmail requires App Password)
- Provider blocks SMTP AUTH (common for institutional emails)
- Add calendar-style UI (weekly view)
- Add user cancellation link with token
- Add “maintenance mode” per lab
- Add admin management for multiple admins per lab