| Factor | Option A — Present | Option B — Integrated |
|---|---|---|
| Infrastructure per client | Another container on existing infra | None — part of Pharos360 |
| Time to enable for a client | Deploy a container and configure | Toggle a setting in pharos.maintenance |
| Feature completeness today | Complete | Complete (email notifications now built) |
| Production readiness | Test suite + security review done | Test suite + reviews done; needs developer sign-off |
| Ongoing maintenance | Two separate systems | One system |
| Rollout control | All-or-nothing per deployment | Per-client toggle, can be disabled live |
| Risk if something breaks | Isolated from Pharos360 | Inside Pharos360 — broader blast radius |
Option A — What was built
Present is a complete Laravel 11 application. Authentication piggybacks on Pharos360's
PHPSESSID cookie — if a user is logged into Pharos360, Present reads their session
and logs them in automatically. Courses, students, and photos come from the shared PostgreSQL
database. Attendance data is stored in the roster_* tables.
The Laravel app has controllers, Blade views, Eloquent models, and middleware — standard Laravel MVC. It is clean, readable, and well-structured. Each client deployment runs as its own container — the same per-client container model already in use — alongside Pharos360.
Option B — What was built
The integrated module adds seven new PHP pages to Pharos360's site/ directory,
five helper functions to classes/queries.php, and small edits to three existing
files (partials/userland.php, settings.php, login.php).
No new tables — it uses the same roster_* tables Present uses. It ships as part of
Pharos360, so there is no separate deployment process.
has_attendance is a boolean in
site_configuration_settings. When false, all attendance pages redirect to home
and the nav link is hidden. Pharos360 looks and behaves exactly as it did before.
When pharos.maintenance enables it through Settings, faculty immediately see the Attendance
link in the top nav.
What Option B needed — and what's since been done
- Email handlers — ✓
attendance_email_notify.phpandattendance_email_summary.phpare now built, following Present'sEmailControllersemantics and using the house email transport - Test coverage — ✓ a framework-free test suite (33 checks) covers the query helpers, the full save path, and both email endpoints, wired to CI against Postgres 14 / PHP 8.3
- Security & code review — ✓ automated passes ran over a clean feature branch; findings (an admin-toggle CSRF gap, an open redirect, a transaction-integrity bug in the save path, and several edge-case crashes) are fixed
- Full developer review — ! still required: the primary Pharos360 developer signs off on the ~300 lines of shared-file edits that run inside the live app. A reviewer's guide maps the branch to make this fast.
Auth and session — both options
Faculty access attendance the same way in both options: they log into Pharos360 and click
Attendance in the top navigation. Option A takes them to the standalone Present app (via
roster.php redirect). Option B takes them to attendance_courses.php
inside Pharos360. The nav entry point is identical; the destination differs.
In a client deployment, only one option would be active at a time:
roster_url set → Option A; has_attendance enabled → Option B.
Database
Both options use the same roster_* tables in the shared PostgreSQL database. If a
client were to switch from Option A to Option B (or vice versa), no data migration would be needed.
Both approaches were built against fake data in a local Docker environment. Since June, both have been substantially hardened — each now has an automated test suite and green CI, and both have had security and code-review passes with the findings fixed. What each still needs before production:
- Load testing — neither has been run against a class roster larger than the local fake data set
- Production data verification — both write the same
roster_*tables; a one-time check confirms the production schema matches and that legacy Roster data doesn't need a status backfill (a ready-to-run SQL script exists) - Option B only: the primary Pharos360 developer's sign-off on the ~300 lines of shared-file edits — the part that runs inside the live app
queries.php is not. That's why the remaining gate for Option B is specifically the primary developer's review of the shared-file edits, even with tests and review passes done.
If the decision is purely operational
Option B is operationally lighter — one deployment to maintain and a per-client toggle rather than a separate app running alongside Pharos360. The missing email notifications are a few hours of work. The developer review is the same work that would be required for any new Pharos360 feature.
If the decision is about code quality and architecture
Option A is cleaner. Laravel enforces separation of concerns, the codebase is testable by design, and bugs stay isolated from Pharos360. Since the team already works in Laravel and already runs per-client containers, neither the framework nor the extra deployment is a barrier — making it the more defensible long-term choice where code quality is the priority.
What AI-assisted development revealed
Option B was built — seven pages, five helper functions, the feature flag, the nav wiring, and the database write — in a single afternoon session. The Pharos360 PHP patterns are simple enough that an AI can produce working code quickly. Option A took longer to rewrite (it replaced a full Java application) but ended up more structured.
The comparison is not "which one is better code" but "what trade-off fits the team and the clients." Both are real, running, and usable today.
Both options are running in Docker on this machine. Use the flows below to see each one.
Present — Standalone App
- 1 Log into Pharos360 as
pharos.maintenance/Maintenance!→ Settings → disable Attendance - 2 Use Test User Accounts to become
judy.fakey - 3 Click Attendance in the top nav bar
- 4 Select a course → Take Attendance → click student cards to mark status
Integrated — Pharos360 Attendance
- 1 Log into Pharos360 as
pharos.maintenance/Maintenance!→ Settings → enable Attendance - 2 Use Test User Accounts to become
judy.fakey - 3 Click Attendance in the top nav bar
- 4 Select a course → same workflow as Present, inside Pharos360
- 5 Bonus: try the AI Assistant in Manage Attendance
The feature flag can be toggled off at any time to restore the original Pharos360 experience.