# Changelog

This project follows [Semantic Versioning](https://semver.org/). Dates are in the business timezone (America/New_York).

## [1.0.0] — 2026-10-11

First release of the USA Reseller / Sub-Reseller Service & Work Order Management Portal (MVP).

### Added

**Platform and tenancy**
- Main Reseller → Sub-Reseller hierarchy with per-sub-reseller vendor availability (all or selected vendors).
- Three-layer tenant isolation: global organization scope, explicit `visibleTo()` scopes and policies. Foreign records return 404.
- ULID public identifiers and generated business numbers (`CUS-000001`, `SLR-000001`, `WO-2026-000001`).

**Modules**
- Dashboard: 10 clickable KPI cards, requires-attention list, upcoming deadlines, lazily loaded charts, organization filter.
- Customers: residential/business, US address and phone validation, service and mailing addresses, seller assignment,
  search, filters, CSV export, soft delete for customers without orders.
- Vendors: per-catalog codes, encrypted account reference, contact data, deactivate instead of delete.
- Service Master: Internet, TV / Streaming, Home Phone / Voice, Mobile (inactive, ready for Quad Play).
- Packages: service-specific details, **automatic play type** (Single / Double / Triple / Quad), pricing with
  promotion and effective dates, versioned price history.
- Sellers: generated codes, optional portal login (row-restricted), performance summary.
- Work orders: guided entry with quick customer creation; snapshot of package, services, play type, pricing and
  service address; status workflow with history; scheduling with arrival windows; deadlines (Due Soon / Due Today /
  Overdue / Completed On Time / Late); internal notes; secure attachments; print view; CSV export; upcoming /
  overdue / completed views.
- Reports (11): work orders, deadlines, status summary, completed, overdue, customers, vendors, sellers, packages,
  service types, play types. Each has filters, print / Save as PDF and CSV export, all from one query per report.
- Administration: resellers and sub-resellers, users, roles and permissions (42 permissions, 6 default roles,
  custom roles), audit log viewer, settings (branding, timezone, date format, prefixes, deadline defaults, password
  policy, login throttling, session timeouts, 2FA enforcement).
- In-app notifications: assignments, important status changes, due-soon and overdue alerts
  (`work-orders:deadline-alerts`, hourly during business hours).

**Security**
- Argon2id, configurable password policy (optional breached-password check), per-account and per-IP sign-in
  throttling, enumeration-safe responses, optional TOTP 2FA (enforceable for administrators), recovery codes.
- Encrypted database sessions with idle and absolute timeouts; sessions end on password, role or status changes.
- Nonce-based Content Security Policy, frame, sniffing, referrer and permissions headers, optional HSTS.
- Uploads checked by byte content, stored privately under random names, downloaded with sandboxing headers;
  logo re-encoded with GD.
- Append-only audit log (model guards + database triggers) with secret redaction; separate security log channel.
- Rate limits for Livewire requests, exports, downloads, password reset and 2FA.

**Quality**
- 210 automated tests: authorization, tenant isolation, IDOR, workflow, deadlines and DST, uploads, headers,
  reports and dashboard consistency.
- Documentation: README, INSTALLATION, ARCHITECTURE, DATABASE, SECURITY, ROLES_AND_PERMISSIONS, WORK_ORDER_FLOW,
  TESTING, REQUIREMENTS_TRACEABILITY.

### Technology

PHP 8.2+ · Laravel 12.69 · Livewire 3.8 (Alpine.js) · Tailwind CSS 4.3 · Vite 7.3 · Chart.js 4.5 · bacon/bacon-qr-code 3.1 ·
MySQL 8.0.16+ or MariaDB 10.4+. Sessions, cache and queue use the database. No Redis, no Docker.

### Decisions

| Decision | Reason |
|---|---|
| **Laravel 12 instead of Laravel 11** | The brief preferred Laravel 11, but Composer blocks every 11.x release because of unpatched security advisories: CVE-2026-48019 (high-severity CRLF injection in the `email` rule, affects all 11.x), debug-page XSS (< 12.69.0) and signed-URL path confusion (< 12.61.1). Laravel 12 keeps the same structure and PHP 8.2 support, and receives security fixes. |
| MariaDB 10.4 compatibility | The local XAMPP stack ships MariaDB. The schema uses only features shared with MySQL 8 (CHECK constraints, triggers, JSON as LONGTEXT on MariaDB), and the connection is forced to UTC. |
| Custom RBAC instead of a package | One role per user, privilege levels and role scopes; small, fully tested, no extra dependency. |
| Livewire bundled through Vite | Allows a nonce-based CSP. `'unsafe-eval'` is still needed by Alpine (documented trade-off). |
| Synchronous database notifications | No queue worker needed on Windows. |
| Browser printing for PDF | No PDF library or headless browser needed; print stylesheets give clean output. |

### Fixed before release (found in internal review)

- **Upload type confusion:** a script renamed to an allowed extension (e.g. `.pdf`) could pass framework MIME
  validation, which falls back to the extension for text content. Uploads are now verified with `finfo` against the
  real bytes (plus the ZIP signature for DOCX/XLSX).
- **Privilege escalation by proxy:** a non-platform user who had been delegated `role.manage` could give a lower role
  permissions they did not hold (e.g. global `settings.manage`). Delegated role managers can now only grant or
  revoke permissions they hold. Not exploitable with the default roles, where only Super Admin holds `role.manage`.
- The work order form validated the empty quick-customer sub-form on save, which blocked valid saves.
- Priority sorting was alphabetical; it now follows Low → Normal → High → Urgent.
- Play type filters listed Quad and Multi Play even when nothing used them. They now offer Single, Double and Triple,
  plus any other type that is in use.
- Test runs wrote into the development log files. They now log to the null channel, and the security channel is a
  configurable stack (`LOG_SECURITY_STACK`, e.g. to add syslog).

### Known limitations

- `'unsafe-eval'` in the CSP (Livewire 3 / Alpine); see SECURITY.md.
- No antivirus is bundled; a `FileScanner` hook is provided.
- Notifications are in-app only (no e-mail/SMS), by design for the MVP.
- Real-browser, cross-browser, accessibility (screen reader) and load testing are still to do; see TESTING.md.
