# Turista API

A Laravel 13 based API for managing vacation rentals, reservations, payments, and on-arrival guest bookings.

## Stack

- **Framework:** Laravel 13
- **PHP:** 8.4
- **Database:** MySQL (dev), SQLite in-memory (tests)
- **Frontend build:** Vite + Tailwind CSS 4
- **Testing:** Pest PHP 4
- **Authentication:** Laravel Sanctum
- **Roles & permissions:** Spatie Laravel Permission
- **Media uploads:** Spatie Media Library
- **Auditing:** OwenIt Auditing

## Requirements

- PHP 8.4+
- Composer 2.9+
- MySQL 8.0+
- Node.js 20+
- NPM 10+

## Quick start

```bash
# Install PHP dependencies
composer install

# Install JavaScript dependencies
npm install

# Create environment file
cp .env.example .env

# Generate application key
php artisan key:generate

# Create storage link for media uploads
php artisan storage:link

# Run migrations and seeders
php artisan migrate --seed

# Build frontend assets
npm run build
```

## Development

```bash
# Start the Laravel server, queue worker, and Vite dev server
composer run dev
```

## Testing

```bash
# Run the full Pest test suite
php artisan test

# Run code style checks
vendor/bin/pint --test

# Build frontend assets
npm run build
```

Tests use an in-memory SQLite database configured in `phpunit.xml`.

## Key domains

- **Auth:** Owner/customer registration with OTP verification, stateless Sanctum login/logout.
- **Users & profiles:** `User` identity with `Owner`, `Employee`, and `Customer` profiles.
- **Buildings & units:** CRUD, photo uploads, facilities, bulk unit creation.
- **Reservations:** Customer online booking and owner/employee on-arrival manual booking with OTP consent.
- **Billing:** Invoices, receipts, payments, refunds, and wallet support.
- **Promo codes:** Bulk generation by owners and redemption during reservations.
- **Notifications:** Scheduled reservation reminders.
- **Locations:** Admin CRUD for countries, cities, regions, and currencies.

## Security notes

- `Model::unguard()` is intentionally enabled globally per project decision. Removing it requires adding `$fillable`/`$guarded` to every model first.
- OTP codes are exposed in API responses only in `local` and `testing` environments for development convenience.
- Sanctum tokens expire after 1 week by default (`SANCTUM_TOKEN_EXPIRATION`).
- All WhatsApp notifications (`PaymentProcessed`, `ReservationCreated`, `ReservationReminder`) are queued via `ShouldQueue`; a queue worker must be running in production.
- Reservation / on-arrival ID documents are stored on the private disk and served only through the authorized `GET /api/v1/media/{media}/document` endpoint.
- Marketplace photos (buildings, units, logos) remain public and are compressed on upload.
- Password policy requires a minimum of 12 characters with mixed case, numbers, and symbols.
- Remaining open security/hardening items are tracked in `docs/REMAINING_FIXES.md`.

## Verification commands

```bash
php artisan test
vendor/bin/pint --test
npm run build
php artisan route:cache
php artisan optimize
```
