# Remaining Fixes — Turista Project

> Living list of outstanding items and recent security/bug cleanup.
> **Current test status:** 640 passed, 0 failed.
> **Last security pass:** 2026-07-06 — all high and medium findings from the 2026-06-22 audit and subsequent review were implemented or explicitly mitigated.

---

## Intentionally Retained

| Item | Why it is still here |
|------|----------------------|
| Global `Model::unguard()` | Kept per project instruction (`AGENTS.md`). Removing it requires adding `$fillable`/`$guarded` to **every** model first. |

---

## Recently Completed

- **Reservation / on-arrival ID documents** moved to the private `local` disk and are now served only through the authorized `GET /api/v1/media/{media}/document` endpoint.
- **All public marketplace photos** (buildings, units, owner logos) remain on the public disk and are compressed on upload.
- **Upload size limits** aligned: `config/media-library.php` sets `max_file_size` to 20 MB, matching `PhotoFileRules`. Controllers now catch `FileIsTooBig` and return a validation error instead of a 500.
- **Account enumeration** removed from `verify-account` and `resend-otp` endpoints; missing users receive the same generic response as invalid OTPs.
- **Employee WhatsApp login enumeration** removed; unverified employees now receive the same generic `401 Invalid credentials.` as any other failed login, while the verify-account → force-change-password onboarding flow remains intact.
- **Password policy** strengthened to `min(12)->mixedCase()->numbers()->symbols()` via `Password::defaults()` in `AppServiceProvider`; factory and tests updated.
- **`verifyAccount`** no longer issues a fresh token for already-verified accounts.
- **`admin:create-super`** no longer accepts `--password`; it always prompts securely with `$this->secret('Password')`.
- **Scheduled commands** now use `->onOneServer()` for cross-server deduplication.
- **Dead `AppDatabaseChannel`** removed.
- **`locations:download`** now uses a pinned release URL, validates the JSON schema, and writes the output with `0750` directory / `0640` file permissions.
- All WhatsApp notifications (`PaymentProcessed`, `ReservationCreated`, `ReservationReminder`) now implement `ShouldQueue`.

---

## Open Items

### Low / Deferred

| Item | Why it is still open |
|------|----------------------|
| Mail driver defaults to `log` | You asked to skip mail configuration changes for now. Production deployments must set `MAIL_MAILER` to a real provider. |

---

## Verification Commands

```bash
php artisan test
vendor/bin/pint --test
vendor/bin/phpstan analyse --no-progress --memory-limit=1G
npm run build
php artisan route:cache
php artisan optimize
composer audit
```

> **Notes:**
> - `php artisan optimize:clear` may report a missing MySQL `cache` table in local environments; this is an environment quirk and does not affect the test suite, which uses SQLite in-memory.
> - A queue worker must be running in any environment where WhatsApp notifications are enabled, because `PaymentProcessed`, `ReservationCreated`, and `ReservationReminder` are queued.
> - `->onOneServer()` requires the scheduler to use a shared cache store (e.g., Redis or database) in multi-server deployments.
