# Repository Guidelines

## Project Structure & Module Organization
- Entry flows through `public_html/index.php` into `userfrosting/initialize.php`; point your web server at `public_html/`.
- PHP domain code lives in `userfrosting/src/BuyerKiosk/` (PSR-4); notable areas include `Core/` (stores, auth, queues), `Workbook/`, `Backstock/`, `Cash/`, and `SMS/`.
- Routes are defined under `userfrosting/routes/`; Twig templates sit in `userfrosting/templates/themes/default/`.
- Tests live in `tests/`; specs and guides are in `docs/` (see `docs/specs/`, `docs/features/`, `docs/systems/`, `docs/patterns/`).
- Utility scripts: `./test.sh`, `./deploy.sh`, and `dev/` helpers; SSL certs and data samples stay outside versioned code.

## Build, Test, and Development Commands
- `cd userfrosting && composer install` — install PHP dependencies before first run.
- `./test.sh` — runs the PHPUnit suite; use before every PR.
- `./deploy.sh` — runs tests then deploys (mirror release pipeline).
- `cd userfrosting && ./vendor/bin/phpstan analyse` — run static analysis (PHPStan level 2).
- `cd userfrosting && ./vendor/bin/phpstan analyse --memory-limit=2G` — run with increased memory for large codebase.
- Local dev is proxied via ngrok to `dev2.buyerkiosk.com`; align your tunnel/config with that hostname rather than the PHP built-in server.

## TaskEngine Commands
- `php userfrosting/bin/task worker:start` — start a single worker process.
- `php userfrosting/bin/task worker:start --queues=high,default,low` — start worker monitoring specific queues.
- `php userfrosting/bin/task worker:manager --status` — check worker pool status (healthy, stale, needed).
- `php userfrosting/bin/task queue:status` — view pending job counts per queue.
- `php userfrosting/bin/task queue:status --detailed` — view pending, processing, and delayed counts.
- `php userfrosting/bin/task scheduler:run` — run one scheduler cycle (invoke via cron every minute).
- `php userfrosting/bin/task job:list` — list all registered job definitions.
- `php userfrosting/bin/task job:dispatch <job-name>` — manually dispatch a global job.
- `php userfrosting/bin/task job:dispatch <job-name> --store=<typeNum>` — dispatch a per-store job.

### Local Workers (macOS launchd)
Worker plists are in `~/Library/LaunchAgents/com.buyerkiosk.taskengine-worker*.plist`. Logs go to `logs/task-worker*.log`.
- `launchctl list | grep buyerkiosk` — check running workers.
- `launchctl load ~/Library/LaunchAgents/com.buyerkiosk.taskengine-worker*.plist` — start all workers.
- `launchctl unload ~/Library/LaunchAgents/com.buyerkiosk.taskengine-worker*.plist` — stop all workers.
- `tail -f logs/task-worker.log` — watch worker output.

## Coding Style & Naming Conventions
- PHP 8.x, Slim 2.x (legacy routing), Twig 1.44. Use 4-space indentation and PSR-4 namespaces under `BuyerKiosk\`.
- Place new features under `userfrosting/src/BuyerKiosk/<Area>/`, with matching controllers and routes; keep class and file names StudlyCase.
- Database naming: camelCase columns and foreign keys (e.g., `templateId`, `integrationType`); timestamps stay snake_case (`created_at`, `updated_at`); prefer camelCase for new tables.
- Store identifiers (`typeNum`) follow `[a-z][a-z]\d+` (e.g., `ou00`); validate early.
- In Twig that embeds Handlebars, wrap `{{` in `{% raw %}...{% endraw %}` to avoid collisions.

## Routing Notes
- Slim 2.x routing is opinionated and old; mirror existing route patterns when adding endpoints.
- Avoid `->conditions()` (unsupported in our stack); rely on pattern matching used in current routes.
- Always pair store routes with access checks and `checkStoreGroup($typeNum)` before work.

## Testing Guidelines
- Use spec-driven and test-driven flow: start with specs in `docs/specs/*` and add PHPUnit coverage in `tests/`, mirroring the source module layout.
- When touching queues, SMS, or workbook flows, stub external services and assert `dbConnectByName` targets the expected store.
- Run `./test.sh` locally; include failing-repro steps in PRs if you cannot fix a test.

## Commit & Pull Request Guidelines
- Follow the repository’s short, imperative history (`feat: ...`, `fix: ...`, or concise summary like “Catch up on small changes”); keep commits scoped and reviewable.
- PRs should summarize the change, list affected routes/stores, mention migrations or config flags, and link issues/tickets.
- Include screenshots for UI changes and note any Ably/Twilio/Redis impacts; confirm `./test.sh` output and any manual QA steps.

## Security & Configuration Tips
- Never commit secrets; rely on your local `.env`/server config for DB, Twilio/Vonage, Ably, and other keys.
- Always enforce access: `checkAccess('uri_*')` and `checkStoreGroup($typeNum)` before store actions; obtain DB connections via `dbConnectByName($store->getDbName())`.
