This repository has been archived on 2026-03-14. You can view files and clone it, but cannot push or open issues or pull requests.
php-api/CLAUDE.md
Snider 64f9c7246b
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
docs: add CLAUDE.md project instructions
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-13 13:38:02 +00:00

3.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Package Overview

This is lthn/php-api, a Laravel package providing REST API infrastructure: OpenAPI documentation, rate limiting, webhook signing, API versioning, and secure API key management. Part of the Core PHP Framework monorepo ecosystem.

Commands

./vendor/bin/pest                    # Run all tests
./vendor/bin/pest --filter=ApiKey    # Run tests matching "ApiKey"
./vendor/bin/pint --dirty            # Format changed files
./vendor/bin/pint src/               # Format specific directory
./vendor/bin/pint --test             # Check formatting without changes (CI uses this)

Tests live in src/Api/Tests/Feature/, not the root tests/ directory.

Architecture

Three-namespace design:

  • Core\Front\Api\ (src/Front/Api/) — API frontage: middleware group, versioning middleware, rate limiter config. This is the Laravel auto-discovered provider (registered in composer.json extra.laravel.providers). It fires ApiRoutesRegistering during boot.
  • Core\Api\ (src/Api/) — Backend API logic: authentication, scopes, models, webhook services, OpenAPI docs. Uses the event-driven $listens pattern to register lazily when ApiRoutesRegistering fires.
  • Core\Website\Api\ (src/Website/Api/) — Frontend documentation UI: controllers, views, web routes for /api/docs.

Boot chain: Front\Api\Boot (auto-discovered) → fires ApiRoutesRegisteringApi\Boot registers middleware aliases and routes via event handler.

Event-driven boot via $listens array in Core\Api\Boot:

public static array $listens = [
    AdminPanelBooting::class => 'onAdminPanel',
    ApiRoutesRegistering::class => 'onApiRoutes',
    ConsoleBooting::class => 'onConsole',
];

Middleware aliases registered via events (not bootstrap/app.php):

  • api.auth / auth.apiAuthenticateApiKey (bcrypt + legacy SHA-256 key validation)
  • api.scope / api.scope.enforceCheckApiScope / EnforceApiScope (wildcard-capable permissions)
  • api.rateRateLimitApi (tier-based with burst allowance)
  • api.versionApiVersion (URL/header version parsing)
  • api.sunsetApiSunset (deprecation headers)

Key services:

  • WebhookService — HMAC-SHA256 signed delivery with exponential backoff retries
  • RateLimitService — Sliding window, per-workspace, tier-based (freeenterprise)
  • IpRestrictionService — API key IP whitelisting with CIDR support
  • OpenApiBuilder — Generates spec from PHP attributes on controllers

OpenAPI Documentation Attributes

use Core\Api\Documentation\Attributes\{ApiTag, ApiResponse, ApiParameter, ApiSecurity, ApiHidden};

#[ApiTag('Products')]
#[ApiResponse(200, ProductResource::class)]
#[ApiSecurity('apiKey')]
class ProductController
{
    #[ApiParameter('filter', 'query', 'string', 'Filter products')]
    public function index() { }
}

Conventions

  • UK English (colour, organisation, centre)
  • PSR-12 with declare(strict_types=1);
  • Type hints on all parameters and return types
  • Pest for testing (not PHPUnit directly)
  • Font Awesome Pro icons (not Heroicons)
  • Flux Pro components (not vanilla Alpine)

License

EUPL-1.2 (copyleft applies to Core\ namespace)