# Architecture

## Overview

Venue Events Manager is a server-rendered Laravel 12 application. The browser receives Blade HTML; Alpine.js and vanilla JavaScript enhance interactivity without becoming an SPA.

## Layering

```
HTTP Request
  → Routes (web.php) + middleware (auth, permission, throttle)
    → Form Request (validation)
      → Controller (orchestration only)
        → Policy (authorization)
          → Service (business rules, transactions)
            → Eloquent Models / Query Builder
              → MySQL / MariaDB
```

Views receive view models / Eloquent models prepared by controllers. Blade never contains pricing formulas, availability math, or document numbering.

## Domain Aggregate

The **Booking** is the aggregate root for operational state.

- Quotations and invoices reference a booking; they do not clone it.
- Issued documents store JSON/text snapshots of customer, event, spaces, and line items.
- Payments attach to invoices (and optionally booking/customer for reporting).

## Concurrency

| Operation | Mechanism |
|-----------|-----------|
| Confirm reservation | Transaction + `lockForUpdate` on space reservations/blocks + re-check availability |
| Document numbers | `number_sequences` row locked inside transaction |
| Quote conversion | Lock quotation row; refuse if already converted |
| Payments | Transaction; recalculate balance from posted payments |
| Void invoice | Transaction; audit reason mandatory |

## Availability Overlap Rule

```
conflict = new_setup_start < existing_breakdown_end
       AND new_breakdown_end > existing_setup_start
```

Adjacent bookings (end == next start) are allowed.

States: Available (computed), Provisional hold, Confirmed, In progress, Internal block, Maintenance block.

Expired holds are cleared lazily before checks/calendars/views (optional cron documented).

## Pricing

All money math goes through `PricingService` using `brick/math` BigDecimal with scale 2 rounding.

Charge bases: `once_per_event`, `per_reservation_day`, `per_guest`, `per_guest_per_day`, `per_hour`, `per_unit`, `complimentary`, `fixed_package`.

## Authorization

Custom roles ↔ permissions (many-to-many). Controllers and Blade gates check permission slugs (e.g. `bookings.confirm`), not role names.

Default roles: System Administrator, Events and Sales Officer, Reservations Officer, Finance Officer, Operations User, Management User.

## UI

Radminly-inspired Tailwind layout:

- Left sidebar + top bar + mobile drawer
- Reusable Blade components (forms, badges, money, datetime, tables, alerts, empty states)
- FullCalendar for availability
- Bundled production assets (no CDN requirement; no Node on production)

## File Storage

- Private attachments under `storage/app/attachments` streamed via controller
- Public branding/space images via public media controller or script-disabled upload dir
- No `storage:link` required for cPanel split deploy

## Installation Paths

1. Document root → `public/`
2. Split: `application/` + `public_html/` with adjusted `index.php`

Web installer at `public/install/` writes `.env`, imports `database/install.sql`, seeds admin/roles/settings, creates lock file.
