Current state

This commit is contained in:
2026-02-07 08:23:18 +01:00
commit 0a4372c40d
22479 changed files with 1553543 additions and 0 deletions

370
.copilot/artworks.md Normal file
View File

@@ -0,0 +1,370 @@
# 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.**