Files
Verde-Web/config/scramble.php
admin 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

137 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
use Dedoc\Scramble\Http\Middleware\RestrictedDocsAccess;
return [
/*
* Your API path. By default, all routes starting with this path will be added to the docs.
* If you need to change this behavior, you can add your custom routes resolver using `Scramble::routes()`.
*/
'api_path' => 'api/v1',
/*
* Your API domain. By default, app domain is used. This is also a part of the default API routes
* matcher, so when implementing your own, make sure you use this config if needed.
*/
'api_domain' => null,
/*
* The path where your OpenAPI specification will be exported.
*/
'export_path' => 'api.json',
'info' => [
/*
* API version.
*/
'version' => env('API_VERSION', '1.0.0'),
/*
* Description rendered on the home page of the API documentation (`/docs/api`).
*/
'description' => 'Verde — garbage monitoring platform API. Auth: Sanctum bearer for mobile, session for admin web. Geo: SRID 4326. Times stored UTC.',
],
/*
* Customize Stoplight Elements UI
*/
'ui' => [
/*
* Define the title of the documentation's website. App name is used when this config is `null`.
*/
'title' => null,
/*
* Define the theme of the documentation. Available options are `light`, `dark`, and `system`.
*/
'theme' => 'light',
/*
* Hide the `Try It` feature. Enabled by default.
*/
'hide_try_it' => false,
/*
* Hide the schemas in the Table of Contents. Enabled by default.
*/
'hide_schemas' => false,
/*
* URL to an image that displays as a small square logo next to the title, above the table of contents.
*/
'logo' => '',
/*
* Use to fetch the credential policy for the Try It feature. Options are: omit, include (default), and same-origin
*/
'try_it_credentials_policy' => 'include',
/*
* There are three layouts for Elements:
* - sidebar - (Elements default) Three-column design with a sidebar that can be resized.
* - responsive - Like sidebar, except at small screen sizes it collapses the sidebar into a drawer that can be toggled open.
* - stacked - Everything in a single column, making integrations with existing websites that have their own sidebar or other columns already.
*/
'layout' => 'responsive',
],
/*
* The list of servers of the API. By default, when `null`, server URL will be created from
* `scramble.api_path` and `scramble.api_domain` config variables. When providing an array, you
* will need to specify the local server URL manually (if needed).
*
* Example of non-default config (final URLs are generated using Laravel `url` helper):
*
* ```php
* 'servers' => [
* 'Live' => 'api',
* 'Prod' => 'https://scramble.dedoc.co/api',
* ],
* ```
*/
'servers' => null,
/**
* Determines how Scramble stores the descriptions of enum cases.
* Available options:
* - 'description' Case descriptions are stored as the enum schema's description using table formatting.
* - 'extension' Case descriptions are stored in the `x-enumDescriptions` enum schema extension.
*
* @see https://redocly.com/docs-legacy/api-reference-docs/specification-extensions/x-enum-descriptions
* - false - Case descriptions are ignored.
*/
'enum_cases_description_strategy' => 'description',
/**
* Determines how Scramble stores the names of enum cases.
* Available options:
* - 'names' Case names are stored in the `x-enumNames` enum schema extension.
* - 'varnames' - Case names are stored in the `x-enum-varnames` enum schema extension.
* - false - Case names are not stored.
*/
'enum_cases_names_strategy' => false,
/**
* When Scramble encounters deep objects in query parameters, it flattens the parameters so the generated
* OpenAPI document correctly describes the API. Flattening deep query parameters is relevant until
* OpenAPI 3.2 is released and query string structure can be described properly.
*
* For example, this nested validation rule describes the object with `bar` property:
* `['foo.bar' => ['required', 'int']]`.
*
* When `flatten_deep_query_parameters` is `true`, Scramble will document the parameter like so:
* `{"name":"foo[bar]", "schema":{"type":"int"}, "required":true}`.
*
* When `flatten_deep_query_parameters` is `false`, Scramble will document the parameter like so:
* `{"name":"foo", "schema": {"type":"object", "properties":{"bar":{"type": "int"}}, "required": ["bar"]}, "required":true}`.
*/
'flatten_deep_query_parameters' => true,
'middleware' => [
'web',
// RestrictedDocsAccess::class, // re-enable in production
],
'extensions' => [],
];