# HiTech University Management System

Laravel 11 modular monolith. **Rule: every module keeps its own routes
(`routes/modules/<module>.php`), models (`app/Models/<Module>/`), migrations
(one per module), services (`app/Services/<Module>/`), and per-panel Filament
resources (`app/Filament/<Panel>/Resources`). Never share a generic
controller/route/table across modules.**

## Stack
- PHP 8.3 · Laravel 11 · Livewire 3 · Filament 3 · Tailwind 3 (+ Alpine bundled by Livewire — do NOT import alpinejs separately, it breaks component mounting)
- Dev DB: SQLite (`database/database.sqlite`). Production: MySQL 8 via `docker-compose.yml` — switch the DB block in `.env`.
- Spatie permission/medialibrary/activitylog · Cashier (Stripe) · srmklive/paypal · Sanctum · DomPDF

## Panels & portals
| Surface | Path | Guard / roles |
|---|---|---|
| Super Admin | `/superadmin` | web · super_admin |
| Registrar | `/registrar` | web · registrar, admissions_officer |
| Faculty | `/faculty` | web · instructor, department_head |
| Finance | `/finance` | web · finance_officer |
| Librarian | `/librarian` | web · librarian |
| Student portal | `/portal` | web · role:student (Livewire, not Filament) |
| Applicant portal | `/apply` | `applicant` guard (own table) |

Panel access is gated in `User::canAccessPanel()`.

## Key domain services (all mutations go through these)
- `Services/Finance/JournalService` — ONLY write-path into the double-entry ledger; enforces balance.
- `Services/Finance/InvoiceService`, `PaymentService` — invoices/payments/refunds post balanced entries atomically. Account codes in `Services/Finance/AccountCodes`.
- `Services/Registration/RegistrationService` — prereq/capacity/clash/credit-cap + waitlist promotion.
- `Services/Grading/GradebookService` — weighted totals → letter grades → GPA/CGPA; publish workflow via `ResultPublication`.
- `Services/Attendance/AttendanceService` — session generation + marking + low-attendance alerts.
- `Services/Library/CirculationService` — issue/return/renew; overdue fines invoice into the ledger.
- `Services/Admissions/AdmissionService` — applicant → student conversion (atomic).
- `app/Payments/` — `PaymentGatewayInterface` + Stripe/PayPal drivers + webhook controller (`/webhooks/payments/{gateway}`, idempotent).

## Commands
- Tests: `php artisan test` (SQLite in-memory; fixtures via `Tests\Support\BuildsUniversity`)
- Serve: `php artisan serve --port=8090` (8000 is taken by Apache)
- Assets: `npm run build` (rerun `php artisan filament:assets` after Filament updates)
- Seed: `php artisan db:seed` (roles + accounts + grade scale) then `php artisan db:seed --class=DemoDataSeeder`

## Demo logins (password: `password`)
admin@hitech.edu · registrar@ · instructor@ · finance@ · librarian@ · student01–10@hitech.edu

## Known gaps / next steps
- CSV/PDF exports (transcripts via DomPDF) not yet wired.
- Offer-letter / invoice email sending: templates table exists, mailer wiring pending.
- Composer audit: laravel/framework 11.x has 3 advisories (block relaxed in composer.json `policy`); revisit or move to Laravel 12.
- MySQL not installed locally (winget install was cancelled); schema is MySQL-8 compatible.
