Current state
This commit is contained in:
310
.copilot/api-first.md
Normal file
310
.copilot/api-first.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user