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

371 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Artworks Module Canonical Architecture (SkinBase)
> **Authoritative documentation for Copilot AI agent**
> This file defines the **single source of truth** for the `artworks` domain.
> All generated code **MUST follow this document**.
---
## 1. Purpose
The **Artworks module** is the core content system of SkinBase.
It must support:
* high-read traffic (browse/search)
* safe moderation (soft deletes, approvals)
* multilingual content
* SEO-friendly URLs
* scalable statistics
* future extensions (tags, EXIF, search engines)
Legacy tables **must NOT influence new code**.
---
## 2. Core Design Principles (DO NOT VIOLATE)
1. **Single responsibility per table**
2. **No counters on hot tables**
3. **Soft deletes on user-generated content**
4. **No legacy fields**
5. **Slug-based routing only**
6. **FK integrity everywhere**
7. **Indexes optimized for browsing**
8. **Stats updated asynchronously**
---
## 3. Database Schema (Canonical)
### 3.1 `artworks` (CORE TABLE)
**Purpose:**
Stores the authoritative artwork entity.
```sql
artworks
```
**Fields:**
| Field | Type | Notes |
| ------------ | ------------ | ---------------- |
| id | bigint | Primary key |
| user_id | bigint | Owner |
| title | varchar(150) | Default language |
| slug | varchar(160) | UNIQUE, URL |
| description | text | Optional |
| file_name | varchar | Original file |
| file_path | varchar | Storage path |
| file_size | bigint | Bytes |
| mime_type | varchar(64) | e.g. image/jpeg |
| width | int | Pixels |
| height | int | Pixels |
| is_public | boolean | Visibility |
| is_approved | boolean | Moderation |
| published_at | datetime | SEO timing |
| created_at | datetime | |
| updated_at | datetime | |
| deleted_at | datetime | Soft delete |
**Indexes:**
* `UNIQUE(slug)`
* `(is_public, is_approved, published_at)`
* `deleted_at`
---
### 3.2 `artwork_translations`
**Purpose:**
Multilingual titles and descriptions.
```sql
artwork_translations
```
| Field | Type |
| ----------- | -------- |
| artwork_id | FK |
| locale | char(2) |
| title | varchar |
| description | text |
| deleted_at | datetime |
**Rules:**
* One row per `(artwork_id, locale)`
* Default language lives in `artworks`
---
### 3.3 `artwork_stats`
**Purpose:**
High-write counters isolated from core table.
```sql
artwork_stats
```
| Field | Type |
| ------------ | ------- |
| artwork_id | PK + FK |
| views | bigint |
| downloads | bigint |
| favorites | bigint |
| rating_avg | float |
| rating_count | int |
**Rules:**
* NO soft deletes
* Updated via jobs / async
* Never eager-loaded by default
---
### 3.4 `artwork_category`
**Purpose:**
Many-to-many relation with categories.
```sql
artwork_category
```
| Field | Type |
| ----------- | ---- |
| artwork_id | FK |
| category_id | FK |
**Rules:**
* Categories handle hierarchy
* Artworks can belong to multiple categories
---
### 3.5 `artwork_comments`
**Purpose:**
User comments with moderation.
```sql
artwork_comments
```
| Field | Type |
| ----------- | -------- |
| artwork_id | FK |
| user_id | FK |
| content | text |
| is_approved | boolean |
| deleted_at | datetime |
---
### 3.6 `artwork_downloads`
**Purpose:**
Audit log of downloads.
```sql
artwork_downloads
```
| Field | Type |
| ---------- | ---------- |
| artwork_id | FK |
| user_id | nullable |
| ip | binary(16) |
| user_agent | varchar |
| created_at | datetime |
**Rules:**
* Append-only
* No soft deletes
* Used for abuse detection & stats aggregation
---
## 4. Eloquent Models (REQUIRED)
### 4.1 Artwork Model
```php
App\Models\Artwork
```
**Traits:**
* `SoftDeletes`
**Relationships:**
```php
belongsTo(User::class)
hasMany(ArtworkTranslation::class)
hasOne(ArtworkStats::class)
belongsToMany(Category::class)
hasMany(ArtworkComment::class)
hasMany(ArtworkDownload::class)
```
**Required Scopes:**
```php
public function scopePublic($q)
public function scopeApproved($q)
public function scopePublished($q)
```
---
### 4.2 ArtworkTranslation
```php
App\Models\ArtworkTranslation
```
* SoftDeletes
* BelongsTo Artwork
---
### 4.3 ArtworkStats
```php
App\Models\ArtworkStats
```
* No SoftDeletes
* BelongsTo Artwork
---
### 4.4 ArtworkComment
```php
App\Models\ArtworkComment
```
* SoftDeletes
* BelongsTo Artwork
* BelongsTo User
---
### 4.5 ArtworkDownload
```php
App\Models\ArtworkDownload
```
* Append-only
* BelongsTo Artwork
---
## 5. Query Rules (IMPORTANT)
### Public browsing MUST always include:
```sql
WHERE
deleted_at IS NULL
AND is_public = 1
AND is_approved = 1
```
### NEVER:
* eager-load stats on lists
* update counters inline
* expose IDs in URLs
---
## 6. Routing Rules
### Canonical URLs
```
/{content_type}/{category_path}/{artwork_slug}
```
Example:
```
/photography/abstract/dark/night-city
```
### Slug uniqueness is GLOBAL.
---
## 7. Search Rules
* Use MySQL FULLTEXT as fallback
* Prefer external search engines later
* Never search on `file_name` or paths
---
## 8. Caching Rules
* Category listings → Redis
* Homepage feeds → Redis
* Artwork stats → cached
* DB is source of truth
---
## 9. Soft Delete Behavior
| Action | Result |
| ------------------- | ------------------ |
| Soft delete artwork | Hidden from public |
| Restore | Fully restored |
| Force delete | Rare, GDPR only |
SEO:
* Soft-deleted artworks → 410 or 301
---
## 10. Forbidden Patterns (NEVER GENERATE)
❌ Counters on `artworks`
❌ IDs in URLs
❌ Hard deletes
❌ Category logic inside artworks
❌ Mixed language columns
❌ MyISAM
❌ Polymorphic abuse
---
## 11. Future Extensions (Allowed)
Copilot MAY extend with:
* `artwork_tags`
* `artwork_exif`
* `artwork_versions`
* `artwork_reports`
* external search engines
BUT must not modify core tables without migrations.
---
## 12. Final Rule (MANDATORY)
> **If generated code conflicts with this document,
> THIS DOCUMENT WINS.**