Skip to content

shieldss/RTA-App

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

RTA Instructor Scheduler

Responsive PHP 8 + MySQL scheduling app for a multi-location Brazilian Jiu-Jitsu academy. It includes an admin calendar, instructor check-ins, class coverage queue, monthly hour tracking, notification preferences, OAuth hooks, and per-instructor iCal feeds.

Stack

  • PHP 8 front controller with REST-style JSON endpoints
  • MySQL or MariaDB via PDO
  • FullCalendar.js for schedule views
  • Tailwind CDN plus local CSS for the dashboard UI
  • Firebase Cloud Messaging service hook for push notifications
  • Google and Facebook OAuth redirect/callback flow

Local Setup

  1. Copy .env.example to .env.
  2. Create a MySQL database named rta_scheduler.
  3. Run the schema and demo seed:
SOURCE www/database/migrations/001_create_scheduler_schema.sql;
SOURCE www/database/seeders/demo_seed.sql;
  1. Point your web server document root at www.
  2. Open / in the browser.

If no database credentials are configured, the app falls back to session-backed demo mode. Demo email login is admin@example.com with password password.

Important Routes

  • GET / dashboard UI
  • GET /index.php/api/bootstrap app bootstrap data
  • GET /index.php/api/classes calendar events and class data
  • POST /index.php/api/classes create a class
  • PUT /index.php/api/classes/{id} update a class
  • DELETE /index.php/api/classes/{id} soft-delete a class
  • POST /index.php/api/classes/{id}/checkin instructor check-in
  • POST /index.php/api/classes/{id}/unavailable create coverage request
  • POST /index.php/api/classes/{id}/claim claim an open class
  • GET /index.php/api/coverage-requests coverage queue
  • POST /index.php/api/coverage-requests/{id}/claim claim coverage
  • POST /index.php/api/users, PUT /index.php/api/users/{id}, DELETE /index.php/api/users/{id} admin user CRUD
  • PUT /index.php/api/users/{id}/goal configure monthly instructor goal
  • POST /index.php/api/schools, PUT /index.php/api/schools/{id}, DELETE /index.php/api/schools/{id} admin school CRUD
  • GET /index.php/ical/{calendar_token} unique instructor iCal feed
  • GET /index.php/auth/google and /index.php/auth/facebook OAuth start URLs

Apache and Azure/IIS rewrite configs are included in www/.htaccess and www/web.config. The frontend uses index.php/... URLs, so it also works without rewrites.

Roles

  • Instructor: schedule view, check-ins, history, hours, preferences, unavailable/claim actions
  • Location Manager: instructor features plus schedule management for assigned schools and staffing alerts
  • Super User: global schedule management and conflict override surface
  • Admin: full access to users, schools, roles, goals, notifications, and entities

Calendar Sync

Each user has a unique calendar_token. The Settings view exposes the iCal URL and a Google Calendar add-by-URL button. Rotate a feed by changing the user’s calendar_token.

Notifications

In-app notifications are stored in notifications with the in_app channel. Mail and browser-push deliveries are queued in notification_jobs so schedule saves, check-ins, and coverage updates do not wait on external delivery providers. Browser push subscriptions are stored per user/device in push_subscriptions, and user category preferences are stored in user_notification_preferences.

OAuth

Create OAuth apps with redirect URIs:

  • Google: https://your-domain/index.php/auth/callback/google
  • Facebook: https://your-domain/index.php/auth/callback/facebook

Then set the matching client IDs/secrets in .env.

Project Layout

  • www/index.php front controller
  • www/app/Core request, response, auth, config, database, application wiring
  • www/app/Controllers page, API, and OAuth controllers
  • www/app/Repositories MySQL repository plus session demo repository
  • www/app/Services iCal, OAuth, and notification services
  • www/views/dashboard.php main UI template
  • www/app.js dashboard/calendar interactions
  • www/styles.css responsive dashboard styling
  • www/database migrations and seed data

Performance Notes

The main dashboard and post-login path are intentionally split between critical and non-critical work:

  • /index.php/api/bootstrap returns only the near-term dashboard window, recent/unread notifications, cached school/class type lists, and cached instructor monthly summaries. It no longer requires loading all historical classes before the dashboard can render.
  • Calendar requests must include the visible start and end range. The frontend sends FullCalendar's visible range and asks for compact event payloads with compact=calendar so the server does not hydrate unused instructor profile details for every event.
  • Large list endpoints accept page and per_page; defaults are capped server-side to keep accidental unbounded loads from slowing login or updates.
  • Dashboard summaries are cached for 30 seconds. Instructor monthly summaries are cached for 5 minutes and invalidated after class, check-in, goal, school, class type, user, preference, coverage, and notification mutations.
  • Local/dev timing logs are emitted as [perf] METHOD path Nms queries=N. Slow production endpoints over 500 ms are also logged. Set APP_ENV=local or APP_DEBUG=true to log query counts for every endpoint while profiling.
  • Run www/database/migrations/002_add_performance_indexes.sql after the base schema to add indexes used by dashboard, schedule, check-in, calendar, coverage, and notification queries.

Bottlenecks found during the audit

  • dashboard() loaded a broad class list, then filtered it in PHP for today/upcoming/understaffed cards.
  • Instructor monthly totals were recalculated by calling classes() once per instructor, and each class hydration queried schools, class types, assignments, assigned users, check-ins, coverage, and recurrence separately.
  • coverageRequests() and recentActivity() hydrated classes one row at a time.
  • Rendering the initial dashboard immediately initialized the calendar and instructor/month panels, which caused duplicate /classes calls while the user was still waiting for the overview.
  • Notification and calendar calls had no explicit pagination or compact payload mode.

Remaining recommended improvements

  • Move file-cache storage to Redis or APCu if the app is deployed across multiple PHP workers/servers.
  • Add a dedicated /api/dashboard endpoint if the bootstrap payload grows again.
  • Add a dedicated /api/instructor-month-stats aggregate endpoint so the instructor table never needs to inspect class payloads client-side.
  • Add database-level generated columns or summary tables if historical check-in volume becomes very large.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors