mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-07-18 06:45:20 +00:00
feat(api): generate OpenAPI spec with Scramble for api-docs.invoiceshelf.com (#685)
Auto-generate an OpenAPI 3.1 spec from the v1 API's FormRequests and Resources (no annotations) for publishing at api-docs.invoiceshelf.com as a static Swagger UI site. - config/scramble.php: scope to api/v1, version from version.md, clean placeholder server, export to public/openapi.json - ScrambleServiceProvider: advertise Bearer (Sanctum) auth; add the required `company` tenancy header only to routes using the `company` middleware - OpenApiDocumentationTest: assert spec shape, auth scheme, company-header gating - .github/workflows/openapi.yml: export + commit spec on release, notify the api-docs site to rebuild - public/openapi.json: generated seed spec (184 paths) - dedoc/scramble added as a dev-only dependency Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
421c385fa7
commit
8d929ec09d
64
app/Providers/ScrambleServiceProvider.php
Normal file
64
app/Providers/ScrambleServiceProvider.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Dedoc\Scramble\Scramble;
|
||||
use Dedoc\Scramble\Support\Generator\OpenApi;
|
||||
use Dedoc\Scramble\Support\Generator\Operation;
|
||||
use Dedoc\Scramble\Support\Generator\Parameter;
|
||||
use Dedoc\Scramble\Support\Generator\Schema;
|
||||
use Dedoc\Scramble\Support\Generator\SecurityScheme;
|
||||
use Dedoc\Scramble\Support\Generator\Types\StringType;
|
||||
use Dedoc\Scramble\Support\RouteInfo;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Configures Scramble's OpenAPI generation for the InvoiceShelf API.
|
||||
*
|
||||
* Scramble is a dev-only dependency used to generate the spec in CI/local (see
|
||||
* `php artisan scramble:export`); it is absent in production (composer install
|
||||
* --no-dev). Every reference to it is therefore guarded by class_exists().
|
||||
*/
|
||||
class ScrambleServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot(): void
|
||||
{
|
||||
if (! class_exists(Scramble::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Scramble::configure()
|
||||
->withDocumentTransformers($this->documentTransformer(...))
|
||||
->withOperationTransformers($this->operationTransformer(...));
|
||||
}
|
||||
|
||||
/**
|
||||
* Advertise Bearer (Sanctum personal access token) auth as the global
|
||||
* security scheme. The customer-portal guard (auth:customer) is session-based
|
||||
* and not part of the token API surface, so it is intentionally not exposed.
|
||||
*/
|
||||
protected function documentTransformer(OpenApi $openApi): void
|
||||
{
|
||||
$openApi->secure(SecurityScheme::http('bearer'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the multi-tenancy `company` header to every company-scoped operation.
|
||||
* CompanyMiddleware (alias `company`) resolves the active tenant from this
|
||||
* header, so only routes that actually run it get the parameter — auth, ping,
|
||||
* and installation endpoints stay clean.
|
||||
*/
|
||||
protected function operationTransformer(Operation $operation, RouteInfo $routeInfo): void
|
||||
{
|
||||
if (! in_array('company', $routeInfo->route->gatherMiddleware(), true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$operation->addParameters([
|
||||
Parameter::make('company', 'header')
|
||||
->description('ID of the company the request operates on (multi-tenancy).')
|
||||
->setSchema(Schema::fromType(new StringType))
|
||||
->required(true),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user