Files
SkinbaseNova/.copilot/api-first.md
2026-02-07 08:23:18 +01:00

4.9 KiB
Raw Blame History

API-First Architecture Canonical Rules (SkinBase)

This document defines how Copilot must generate API-first code. It applies to Artworks and all future modules. If generated code conflicts with this file, this file wins.


1. What “API-First” Means (MANDATORY)

API-first means:

  • Business logic lives in Services
  • Controllers are thin adapters
  • Output is defined by API Resources
  • Web (Blade), API, Admin all use the same services
  • No duplicated logic between web & API

Copilot MUST assume:

  • Web UI exists (Blade / SSR)
  • API exists (JSON)
  • Both consume the same backend logic

2. Layered Architecture (STRICT)

Copilot MUST generate code following this flow:

Request
  → Controller (Web or API)
     → Service (business rules)
        → Models / Queries
     → Resource (output shape)

Forbidden shortcuts

Controller → Model directly Controller → DB query Resource contains logic Model contains business logic


3. Directory Structure (REFERENCE)

Copilot MUST follow this structure:

app/
├── Http/
│   ├── Controllers/
│   │   ├── Api/
│   │   │   └── ArtworkController.php
│   │   └── Web/
│   │       └── ArtworkController.php
│   │
│   ├── Resources/
│   │   ├── ArtworkResource.php
│   │   ├── ArtworkListResource.php
│   │   └── CategoryResource.php
│
├── Services/
│   ├── ArtworkService.php
│   ├── ArtworkStatsService.php
│   └── CategoryService.php
│
├── Policies/
│   └── ArtworkPolicy.php
│
├── Models/
│   └── Artwork.php

4. Services Layer (CORE)

4.1 ArtworkService (MANDATORY)

Copilot MUST generate an ArtworkService that handles:

  • Fetch public artwork by slug
  • Fetch artworks by category
  • Apply visibility rules
  • Apply soft delete rules
  • Throw domain-appropriate exceptions

Example responsibilities (NOT code):

  • getPublicArtworkBySlug(string $slug)
  • getCategoryArtworks(Category $category)
  • getLatestArtworks(int $limit)

Rules

  • Services MUST NOT return JSON
  • Services MUST return models or collections
  • Services MUST enforce visibility rules

5. Controllers (ADAPTERS ONLY)

5.1 API Controllers

Location:

app/Http/Controllers/Api/

Rules:

  • Return API Resources only
  • Never return models directly
  • No business logic
  • Stateless

Example:

return new ArtworkResource(
    $this->service->getPublicArtworkBySlug($slug)
);

5.2 Web Controllers

Location:

app/Http/Controllers/Web/

Rules:

  • Use same services as API
  • Prepare data for Blade
  • No duplication of logic
  • SEO handled here (meta tags, schema)

Example:

return view('artworks.show', [
    'artwork' => new ArtworkResource($artwork),
]);

6. API Resources (OUTPUT CONTRACT)

Rules

Copilot MUST:

  • Use Laravel JsonResource
  • Define explicit fields
  • Never expose internal fields accidentally
  • Avoid N+1 queries
  • Include relations conditionally

ArtworkResource MUST include:

  • slug
  • title
  • description
  • dimensions
  • categories
  • URLs (canonical)

ArtworkListResource MUST:

  • Be lightweight
  • Exclude heavy relations
  • Exclude stats unless requested

7. Routes (SEO-Safe)

API routes

Location:

routes/api.php

Rules:

  • Stateless
  • Slug-based
  • Versionable (/api/v1/...)

Example:

GET /api/v1/artworks/{slug}
GET /api/v1/categories/{slug}/artworks

Web routes

Location:

routes/web.php

Rules:

  • Slug-based
  • No IDs
  • SEO-friendly
  • SSR output

8. Stats Handling (High Load Rule)

Copilot MUST:

  • Use ArtworkStatsService
  • Increment stats via Jobs
  • Never mutate counters inline
  • Assume Redis may be present

Forbidden:

$artwork->increment('views') Updating stats inside controllers


9. Caching Rules

Copilot SHOULD assume:

  • Redis is available
  • Cache keys are service-level
  • Resources are cacheable

Examples:

  • artwork:{slug}
  • category:{slug}:artworks

Cache invalidation:

  • On update
  • On delete
  • On restore

10. Error Handling Rules

Copilot MUST:

  • Return 404 for missing public content
  • Return 410 or 301 for soft-deleted content (if requested)
  • Never expose private content via API

11. Testing Philosophy

Copilot MUST generate tests that:

  • Hit API endpoints
  • Validate JSON structure
  • Test visibility & approval
  • Do NOT test Blade HTML

12. Forbidden Patterns (ABSOLUTE)

Controllers with logic Models with business rules Duplicate logic between API & Web Direct DB queries in controllers Different rules for API vs Web


13. Final Instruction (NON-NEGOTIABLE)

API is the primary contract. Web UI, Admin UI, Mobile apps are clients.

Copilot MUST always ask:

“Can this logic live in a service?”

If yes → put it there.


End of API-First Architecture Instructions