# PetalAir OS

Website, shop, subscriptions, invoicing and CRM for a scent-marketing company.
Laravel 12 + Blade + Tailwind v4, single deployable.

**Setup: [`docs/SETUP.md`](docs/SETUP.md)** — start there.
**cPanel shared hosting: [`docs/CPANEL.md`](docs/CPANEL.md)**
**Design system: [`docs/DESIGN.md`](docs/DESIGN.md)** — read before adding a page.

## Quick start

```bash
composer install
cp .env.example .env && php artisan key:generate
# set DB_* in .env (MySQL or Postgres — both work)
php artisan migrate --seed
php artisan storage:link
php artisan serve
```

Admin: `/admin` — `admin@petalair.com` / `password`. Change it before going live.

## What's in it

**Public** — home, about, products (filterable), plans, industries, blog, FAQ, contact.
**Shop** — cart, guest or account checkout, COD/bKash/Nagad/bank, order tracking by
number + phone.
**Subscriptions** — pick device + oil + plan, install visit, auto-billing, pause,
resume, cancel-at-period-end.
**Account** — subscriptions, orders, invoices with PDF, addresses, profile.
**Admin** — dashboard with an action-needed queue, orders, subscriptions, invoices with
payment recording, CRM pipeline, customers, products, categories, plans, reports with
CSV export.

CSS and JS ship pre-built in `public/css` and `public/js` — no Node, no Vite.
`npm run build` only if you change the design.

## Two things that will bite you if you skip SETUP.md

1. **Queue worker must run** or no email sends — silently.
2. **Cron must be installed** or subscriptions never bill.

```bash
php artisan queue:work
# * * * * * cd /path && php artisan schedule:run >> /dev/null 2>&1
```

## Architecture

Business logic lives in `app/Services`, not controllers. Money is decimal, never float.
Document numbers come from `Sequence::next()` and are gapless. Invoices are polymorphic
(order *or* subscription). Order items snapshot name/sku/price so deleting a product
never rewrites history.

Runs on Postgres or MySQL — `App\Support\Sql` isolates the two places the engines
disagree (case-insensitive LIKE, month formatting). Nothing else names a driver.
