Commit Graph

4 Commits

Author SHA1 Message Date
86ea731eb0 feat(backend): finish all deferred items — Sentry, audit, bulk, FCM, Reverb, PSGC
- **Sentry** wired in bootstrap/app.php via Sentry\Laravel\Integration.
  No-op when SENTRY_LARAVEL_DSN is empty.

- **Audit logging** broadened: LogsActivity applied to Household, QrCode,
  Trip, Payment with tight logOnly whitelists and named log channels
  ('household', 'qr_code', 'trip', 'payment') to keep the activity
  stream useful.

- **Bulk admin actions**:
  POST /admin/households/bulk-approve — skips already-approved /
  no-proof / unknown ids, reports per-id outcomes
  POST /admin/bulk/users/{suspend,activate} — admins protected
  POST /admin/bulk/qr-codes/void — respects state machine transitions

- **FCM push scaffold**: PushDriver contract with LogPushDriver
  (default) and FcmPushDriver (activates when FCM_SERVER_KEY is set).
  PushChannel adapts notifications. RoutesByPreferences now also
  routes via push when push_enabled + fcm_token. toPush() payloads
  added to HouseholdApproved / QrBalanceLow / PickupImminent.

- **Reverb WebSocket broadcast**: laravel/reverb installed.
  TruckLocationBroadcast fires on every TruckTracker::record().
  routes/channels.php authenticates: admins → private-admin.live,
  residents → area.{id}.trucks (only if their household barangay is
  covered by the service area).

- **PSGC seeder** expanded: all 17 PH regions, 4 NCR districts,
  all 17 NCR cities. Sample barangays still carry rectangular
  boundaries for point-in-polygon resolution tests.

- **Conditional SPATIAL INDEX migration** for barangays.boundary —
  safe no-op until every row has a polygon (i.e., after full PSA
  dataset import). Re-running `php artisan migrate` after import
  flips the column to NOT NULL and adds the index.

196 feature tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:22:43 +08:00
58a7d3680a feat(backend): hardening sprint — docs, schedulers, validation, email + pickup
1. API docs via dedoc/scramble at /docs/api (scoped to api/v1).
   Linked from the admin sidebar Settings group.

2. Scheduled commands registered in routes/console.php:
   - reports:aggregate (02:00) — daily/weekly/monthly aggregations
   - qr:expire (02:30) — flips past-due allocated/active codes to expired
   - trucks:prune-locations (03:00) — drops history older than retention
     window (default 7 days, config('verde.location_retention_days'))
   All idempotent + withoutOverlapping. --dry flags on qr:expire and
   trucks:prune-locations for safe inspection.

3. Trip double-booking validation: AdminTripController::store rejects
   new trips when the team or truck already has a non-cancelled trip on
   the same date. override_conflicts: true bypasses for emergencies.
   Cancelled trips don't block rebooking.

4a. Email verification: User implements MustVerifyEmail.
    VerifyEmailNotification overrides verificationUrl() for our
    namespaced route. Register sends the link automatically (best
    effort, won't block signup). POST /auth/email/resend (auth) +
    GET /auth/email/verify/{id}/{hash} (signed URL).

4b. Password change while logged in: POST /me/password validates
    current_password, requires the new password to differ, revokes
    every other active token on success — current session stays.

5a. PickupImminent notification: when TripStop -> arrived,
    TripExecutor::notifyAssignedHouseholds() finds households whose
    assigned_drop_off_point_id matches and sends DB + SMS.

5b. Auto-geofence on truck location: TruckTracker::record() now
    auto-fires TripExecutor::arriveAtDumpsite() when an in-progress
    trip's truck pings inside its dumpsite boundary. The executor's
    status guard prevents duplicate timeline events if the driver also
    presses arrive-dumpsite manually.

190 feature tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:13:00 +08:00
d458e74301 feat(backend): complete Module 7 — QR code system (core)
qr_code_batches + qr_codes tables. State machine via
spatie/laravel-model-states (unassigned → allocated → active → used,
plus expired/voided). Serial format PH-{area}-{YYMM}-{batch}-{code}-
{checksum} with 2-char SHA-256-derived checksum. BatchGenerator
bulk-inserts in chunks. QrAllocator allocates free codes to verified
households (prefers area-targeted batch, falls back to any). Real
HouseholdVerified listener replaces the placeholder. QrBalanceLow
event for Module 11.

Admin: batch CRUD, mark-printed, void code, lifecycle search, PDF
print sheet (24/A4 via dompdf + endroid/qr-code + picqer/barcode).
Resident: list own codes, balance with low_balance flag, activate
allocated codes.

Removed explicit Event::listen for HouseholdVerified — Laravel 11
auto-discovers it via handle() type-hint, and double-registering was
causing double-dispatch.

130 feature tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 02:12:41 +08:00
a58e5eb60e feat(backend): scaffold Laravel 11 API with Module 1 foundation
- Laravel 11.51 + PHP 8.4 in backend/
- MySQL 9 connection (DBngin, db: verde)
- Installed Sanctum, Spatie permission/activitylog/model-states,
  matanyadaev/laravel-eloquent-spatial
- API routes prefixed /api/v1 in bootstrap/app.php
- Standard response envelope { success, data, message, errors, meta }
  via ApiResponse + ApiController base class
- Global exception handlers for validation/auth/not-found/http errors
  on api/* routes (always JSON, never redirect to login)
- Extended users migration: uuid, phone+verified_at, role enum
  (admin/resident/driver/helper/scanner/store_partner), status,
  first/middle/last name, avatar_path, preferred_language, fcm_token,
  last_login_at, soft deletes
- User model: HasApiTokens, HasRoles, LogsActivity, SoftDeletes,
  role/status constants, auto-uuid on create
- Health endpoint at GET /api/v1/health verifies DB connection
- backend/CLAUDE.md documenting backend conventions

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:34:40 +08:00