# Phase 1 — Build Notes

Read this alongside `README.md` (CodeIgniter's stock readme). This file covers what's
specific to Ahenfie: local environment setup, what was built, and decisions flagged for
your review.

## Local environment

- **MySQL**: a standalone MySQL 8.4 instance was initialized at `C:\mysql-data\ahenfie`
  (separate from any other MySQL install on this machine) and is started with:
  ```
  "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysqld.exe" \
    --datadir="C:/mysql-data/ahenfie/data" \
    --basedir="C:/Program Files/MySQL/MySQL Server 8.4" \
    --port=3306 --bind-address=127.0.0.1 \
    --socket="C:/mysql-data/ahenfie/mysql.sock" \
    --pid-file="C:/mysql-data/ahenfie/mysqld.pid" \
    --log-error="C:/mysql-data/ahenfie/mysqld.err"
  ```
  root password: `ahenfie_root_dev`. App DB user: `ahenfie_app` / `ahenfie_app_dev`, with
  grants on `ahenfie_control` and any `tenant_*` database (needed so the provisioning
  command can `CREATE DATABASE` for new hotels). Consider wrapping the mysqld command
  above in a Windows service or scheduled task so it survives reboots — it is **not**
  currently registered as a service.
- **App**: `composer install`, then `php spark serve` (defaults to `127.0.0.1:8080`).
- **Demo hotel**: already provisioned. Slug `demo`, resolved automatically in local dev via
  `tenant.defaultSlug = demo` in `.env` (no subdomain needed on localhost). Logins:
  - Manager: `manager@ahenfie-demo.test` / `Manager123!`
  - Front desk: `frontdesk@ahenfie-demo.test` / `FrontDesk123!`
- **Provision another hotel** any time with:
  `php spark tenant:create --name "..." --slug ... --admin-email ... --admin-password ... [--demo]`

## What was built

Multi-tenant foundation (control DB + database-per-hotel, subdomain/session/`.env`-based
tenant resolution, `TenantModel` base class, `tenant_settings` table unused-but-present),
then Module 1 (room types, rooms, room status board, booking calendar, check-in/check-out,
folios with line items/split-billing allocations/payments), Module 2 (guest CRM with
duplicate warning and normalized phone numbers), and the Module 9 subset (manager/
front_desk roles, activity log with `module` column). Screens were built in the order the
brief specified.

## Assumptions flagged for your review

- **Split-billing granularity**: payer allocations are folio-level totals per payer (e.g.
  "guest owes GHS 375, company owes GHS 375"), not tied to specific line items. A guest and
  a company can't currently each be assigned specific *charges* — just specific *amounts*.
  If you need line-item-level splitting, that's a bigger schema change worth doing before
  Phase 2 builds more billing on top of this.
- **Cancelled booking + folio**: a booking can only be cancelled while still `confirmed`
  (before check-in) — once checked in, there's no folio-side "cancel mid-stay" flow. If a
  guest leaves early, front desk checks them out normally (settle balance, mark
  checked-out); nothing currently prorates or voids already-posted nightly charges.
- **Nightly room charges are posted in full at check-in**, one line item per night, based
  on the booking's original check-out date. An early or extended stay doesn't auto-adjust
  those line items — staff add/remove folio charges manually to correct it. This was the
  most direct reading of "line items have a date field," but if you'd rather charge nightly
  via a scheduled job or only at checkout, that's a different (bigger) design.
- **Checkout requires a zero balance.** Front desk can record partial payments while a
  guest is still in-house, but the "Complete Checkout" button stays disabled until the
  folio balance hits GHS 0.00. No "check out with balance owing, invoice later" path exists
  yet.
- **Guest phone/ID duplicate detection warns, never blocks** — confirmed as the intended
  behavior per the brief, since two guests can legitimately share a household number.
- **Room type deletion is blocked** if any room still references it (no cascade/orphan).
- **No corporate account table yet** — split-billing payers who aren't guests are just a
  free-text name (e.g. "Acme Ltd"), not linked to any structured record. Phase 3 explicitly
  adds `corporate_account`; this was left alone rather than half-building it early.
- **Bootstrap/Bootstrap Icons load from CDN**, not vendored locally. Fine for development;
  swap for a self-hosted copy before relying on this in a location with unreliable internet.

## Not built (explicitly out of scope per the brief)

F&B/POS, charge-to-room, loyalty, Hubtel/WhatsApp/SMS, housekeeping task workflow,
maintenance, inventory, KPI dashboards, AI features — all left with schema room to attach
later (see inline comments in the migrations under `app/Tenant/Database/Migrations/`).
