# 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: ```php 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: ```php 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