current state
This commit is contained in:
181
.copilot/favourites_artworks.md
Normal file
181
.copilot/favourites_artworks.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# 1️⃣ Final SQL – New Favorites Table (Artwork-only)
|
||||
|
||||
**Table name:** `user_favorites`
|
||||
**Scope:** users ↔ artworks
|
||||
**Engine:** InnoDB
|
||||
**Charset:** utf8mb4
|
||||
|
||||
```sql
|
||||
CREATE TABLE user_favorites (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
artwork_id BIGINT UNSIGNED NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE KEY uniq_user_artwork (user_id, artwork_id),
|
||||
KEY idx_artwork (artwork_id),
|
||||
KEY idx_user_created (user_id, created_at),
|
||||
|
||||
CONSTRAINT fk_user_favorites_user
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT fk_user_favorites_artwork
|
||||
FOREIGN KEY (artwork_id) REFERENCES artworks(id)
|
||||
ON DELETE CASCADE
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
This is **production-ready** and matches everything we discussed:
|
||||
|
||||
* no legacy fields
|
||||
* no duplication
|
||||
* proper constraints
|
||||
* fast queries
|
||||
|
||||
---
|
||||
|
||||
# 2️⃣ VS Code Agent Markdown (Laravel 12 Migration Prompt)
|
||||
|
||||
Save this as for example:
|
||||
|
||||
```
|
||||
.vscode/agents/laravel-user-favorites-migration.md
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
.cursor/rules/laravel-user-favorites.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```markdown
|
||||
# Laravel 12 – User Favorites Migration & Model
|
||||
|
||||
## Context
|
||||
We are migrating legacy "favourites" functionality into a clean, modern Laravel 12 system.
|
||||
Each user can add artworks to their favorites list.
|
||||
This is a many-to-many relationship between users and artworks.
|
||||
|
||||
Legacy table MUST NOT be reused.
|
||||
|
||||
---
|
||||
|
||||
## Goal
|
||||
Create a Laravel 12 database migration and Eloquent model for a new table named:
|
||||
|
||||
```
|
||||
|
||||
user_favorites
|
||||
|
||||
````
|
||||
|
||||
This table stores **which user favorited which artwork**, with a timestamp.
|
||||
|
||||
---
|
||||
|
||||
## Database Requirements
|
||||
|
||||
### Table: user_favorites
|
||||
|
||||
| Column | Type | Notes |
|
||||
|------|------|------|
|
||||
| id | BIGINT UNSIGNED | Primary key |
|
||||
| user_id | BIGINT UNSIGNED | FK → users.id |
|
||||
| artwork_id | BIGINT UNSIGNED | FK → artworks.id |
|
||||
| created_at | TIMESTAMP | When artwork was favorited |
|
||||
|
||||
### Constraints & Indexes
|
||||
|
||||
- UNIQUE (user_id, artwork_id)
|
||||
→ prevents duplicate favorites
|
||||
|
||||
- INDEX artwork_id
|
||||
→ fast favorite count per artwork
|
||||
|
||||
- INDEX (user_id, created_at)
|
||||
→ fast "my favorites" queries
|
||||
|
||||
### Foreign Keys
|
||||
|
||||
- user_id → users.id (ON DELETE CASCADE)
|
||||
- artwork_id → artworks.id (ON DELETE CASCADE)
|
||||
|
||||
### Engine & Charset
|
||||
|
||||
- Engine: InnoDB
|
||||
- Charset: utf8mb4
|
||||
- Collation: utf8mb4_unicode_ci
|
||||
|
||||
---
|
||||
|
||||
## Laravel Migration Requirements
|
||||
|
||||
- Use `Schema::create`
|
||||
- Use `foreignId()->constrained()->cascadeOnDelete()`
|
||||
- Use `timestamps()` **ONLY if created_at is needed**
|
||||
(do NOT add updated_at)
|
||||
|
||||
- Add explicit indexes and unique constraints
|
||||
|
||||
---
|
||||
|
||||
## Laravel Model Requirements
|
||||
|
||||
### Model: UserFavorite
|
||||
|
||||
- Table: `user_favorites`
|
||||
- `$timestamps = false` (created_at handled manually or via DB default)
|
||||
- Fillable:
|
||||
- user_id
|
||||
- artwork_id
|
||||
- created_at
|
||||
|
||||
### Relationships
|
||||
|
||||
```php
|
||||
UserFavorite belongsTo User
|
||||
UserFavorite belongsTo Artwork
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
|
||||
* This table is interaction-based, NOT content-based
|
||||
* Do NOT store favorite counts here
|
||||
* Favorite counts will be aggregated separately (Redis or statistics table)
|
||||
* This table must be lean and write-optimized
|
||||
|
||||
---
|
||||
|
||||
## Deliverables
|
||||
|
||||
* Migration file for Laravel 12
|
||||
* Eloquent model `UserFavorite`
|
||||
* Proper naming and clean schema
|
||||
* No legacy fields, no polymorphic logic
|
||||
|
||||
Generate clean, production-quality code.
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## 3️⃣ How to Use This in VS Code (Quick Steps)
|
||||
|
||||
1. Paste markdown into `.vscode/agents/` or `.cursor/rules/`
|
||||
2. Open VS Code
|
||||
3. Ask your AI agent:
|
||||
> “Create Laravel 12 migration and model based on this document”
|
||||
4. Review generated migration
|
||||
5. Run:
|
||||
```bash
|
||||
php artisan migrate
|
||||
````
|
||||
312
.copilot/update_user_schema.md
Normal file
312
.copilot/update_user_schema.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# Skinbase – User Schema Review & Upgrade Plan
|
||||
|
||||
**Database:** MySQL / Percona 8.x
|
||||
**Project:** Skinbase (new system, no legacy dependencies)
|
||||
**Reviewed tables:** users, user_profiles, user_social_links, user_statistics
|
||||
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
The current user-related database schema is **well designed**, modern, and suitable
|
||||
for long-term growth.
|
||||
Key strengths include:
|
||||
|
||||
- Clear separation of concerns
|
||||
- Proper use of foreign keys and cascading deletes
|
||||
- BigInt primary keys
|
||||
- Soft deletes on users
|
||||
- Migration-friendly legacy password handling
|
||||
|
||||
This document summarizes:
|
||||
- what is already good
|
||||
- recommended optimizations
|
||||
- future-proofing steps (non-breaking)
|
||||
- performance considerations for scale
|
||||
|
||||
---
|
||||
|
||||
## 2. users Table
|
||||
|
||||
### 2.1 What’s Good
|
||||
|
||||
- Unique `username` and `email`
|
||||
- `legacy_password_algo` allows smooth migration from old systems
|
||||
- `needs_password_reset` improves security posture
|
||||
- Role stored as string allows flexibility in early stages
|
||||
- Soft deletes enabled
|
||||
|
||||
### 2.2 Recommended Indexes
|
||||
|
||||
Add indexes for common query patterns:
|
||||
|
||||
```sql
|
||||
CREATE INDEX idx_users_active ON users (is_active);
|
||||
CREATE INDEX idx_users_role ON users (role);
|
||||
CREATE INDEX idx_users_last_visit ON users (last_visit_at);
|
||||
````
|
||||
|
||||
These improve:
|
||||
|
||||
* active user filtering
|
||||
* admin queries
|
||||
* “last seen” or online user features
|
||||
|
||||
### 2.3 Future Role Normalization (Planned)
|
||||
|
||||
Current approach is fine short-term:
|
||||
|
||||
```text
|
||||
role = 'user' | 'admin' | 'moderator'
|
||||
```
|
||||
|
||||
Planned future upgrade:
|
||||
|
||||
* `roles` table
|
||||
* `user_roles` pivot table (many-to-many)
|
||||
|
||||
This allows:
|
||||
|
||||
* multiple roles per user
|
||||
* temporary or scoped roles
|
||||
* better permission modeling
|
||||
|
||||
⚠️ No immediate action required — just avoid hard-coding role logic.
|
||||
|
||||
### 2.4 Optional Security Enhancements
|
||||
|
||||
Recommended additions (optional but advised):
|
||||
|
||||
```sql
|
||||
last_password_change_at TIMESTAMP NULL,
|
||||
failed_login_attempts INT UNSIGNED DEFAULT 0,
|
||||
locked_until TIMESTAMP NULL
|
||||
```
|
||||
|
||||
Enables:
|
||||
|
||||
* rate limiting
|
||||
* temporary account locking
|
||||
* better auditability
|
||||
|
||||
---
|
||||
|
||||
## 3. user_profiles Table
|
||||
|
||||
### 3.1 Strengths
|
||||
|
||||
* Clean one-to-one relationship with `users`
|
||||
* Public profile data separated from auth data
|
||||
* Nullable fields for progressive profile completion
|
||||
* Inclusive gender enum with safe default
|
||||
* Localization-ready (`language`, `country_code`)
|
||||
|
||||
### 3.2 Country Handling Recommendation
|
||||
|
||||
Prefer using only:
|
||||
|
||||
```text
|
||||
country_code (ISO 3166-1 alpha-2)
|
||||
```
|
||||
|
||||
Benefits:
|
||||
|
||||
* language-independent
|
||||
* avoids inconsistent country naming
|
||||
* easier frontend mapping
|
||||
|
||||
`country` text field can be deprecated later if needed.
|
||||
|
||||
### 3.3 Avatar & Media Metadata (Future)
|
||||
|
||||
Current:
|
||||
|
||||
```text
|
||||
avatar VARCHAR(255)
|
||||
```
|
||||
|
||||
Recommended future approach:
|
||||
|
||||
```text
|
||||
avatar_hash CHAR(64)
|
||||
avatar_ext VARCHAR(10)
|
||||
avatar_updated_at TIMESTAMP
|
||||
```
|
||||
|
||||
This aligns with:
|
||||
|
||||
* hash-based file storage
|
||||
* CDN-friendly URLs
|
||||
* cache invalidation control
|
||||
|
||||
---
|
||||
|
||||
## 4. user_social_links Table
|
||||
|
||||
### 4.1 Current Design
|
||||
|
||||
* One row per platform per user
|
||||
* Unique constraint on `(user_id, platform)`
|
||||
* Cascade delete enabled
|
||||
|
||||
This is solid.
|
||||
|
||||
### 4.2 Platform Normalization (Recommended)
|
||||
|
||||
Current:
|
||||
|
||||
```text
|
||||
platform VARCHAR(32)
|
||||
```
|
||||
|
||||
Risk:
|
||||
|
||||
* inconsistent values (`twitter`, `x`, `Twitter`, etc.)
|
||||
|
||||
Options:
|
||||
|
||||
**Option A – Enum (simple):**
|
||||
|
||||
```sql
|
||||
ENUM('twitter','x','instagram','deviantart','artstation','github','website')
|
||||
```
|
||||
|
||||
**Option B – Reference Table (best long-term):**
|
||||
|
||||
* `social_platforms`
|
||||
* foreign key `platform_id`
|
||||
|
||||
Option B is preferred for Skinbase as platforms evolve.
|
||||
|
||||
---
|
||||
|
||||
## 5. user_statistics Table
|
||||
|
||||
### 5.1 Strengths
|
||||
|
||||
* Isolated counters
|
||||
* One row per user
|
||||
* Minimal row size
|
||||
* Clean FK relationship
|
||||
|
||||
### 5.2 Performance Warning (Important)
|
||||
|
||||
Avoid frequent direct updates like:
|
||||
|
||||
```sql
|
||||
UPDATE user_statistics SET downloads = downloads + 1;
|
||||
```
|
||||
|
||||
At scale, this causes:
|
||||
|
||||
* row locking
|
||||
* write contention
|
||||
* degraded performance
|
||||
|
||||
### 5.3 Recommended Strategy
|
||||
|
||||
* Use **Redis** (or in-memory cache) for real-time increments
|
||||
* Periodically flush aggregated values to MySQL
|
||||
* Use jobs / cron for batch updates
|
||||
|
||||
This ensures:
|
||||
|
||||
* fast user interactions
|
||||
* scalable statistics tracking
|
||||
|
||||
---
|
||||
|
||||
## 6. Charset & Collation
|
||||
|
||||
Current:
|
||||
|
||||
```text
|
||||
utf8mb4_unicode_ci
|
||||
```
|
||||
|
||||
This is correct and safe.
|
||||
|
||||
Optional upgrade (MySQL 8+):
|
||||
|
||||
```text
|
||||
utf8mb4_0900_ai_ci
|
||||
```
|
||||
|
||||
Benefits:
|
||||
|
||||
* newer Unicode rules
|
||||
* slightly better performance
|
||||
|
||||
Not required immediately.
|
||||
|
||||
---
|
||||
|
||||
## 7. Tables Planned for Future Expansion
|
||||
|
||||
Not required now, but expected as Skinbase grows:
|
||||
|
||||
### 7.1 user_activity_log
|
||||
|
||||
* logins
|
||||
* uploads
|
||||
* profile edits
|
||||
* moderation actions
|
||||
|
||||
### 7.2 user_followers
|
||||
|
||||
* artist-to-artist following
|
||||
* social graph features
|
||||
|
||||
### 7.3 user_settings
|
||||
|
||||
* privacy preferences
|
||||
* notification settings
|
||||
* email subscriptions
|
||||
|
||||
These should remain **separate tables** to avoid bloating `users`.
|
||||
|
||||
---
|
||||
|
||||
## 8. Laravel Implementation Notes
|
||||
|
||||
Recommended model casting:
|
||||
|
||||
```php
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'needs_password_reset' => 'boolean',
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_visit_at' => 'datetime',
|
||||
];
|
||||
```
|
||||
|
||||
Best practices:
|
||||
|
||||
* Eager load profiles (`with('profile')`)
|
||||
* Cache public profile + statistics
|
||||
* Keep statistics out of main user queries
|
||||
|
||||
---
|
||||
|
||||
## 9. Final Verdict
|
||||
|
||||
**Schema quality:** Excellent
|
||||
**Scalability:** Very good
|
||||
**Migration readiness:** Excellent
|
||||
**Long-term Skinbase fit:** Excellent
|
||||
|
||||
The current schema is production-ready and significantly better than typical legacy
|
||||
user databases. Most future improvements can be introduced **without breaking changes**.
|
||||
|
||||
Primary future wins:
|
||||
|
||||
* Redis-backed statistics
|
||||
* normalized roles and social platforms
|
||||
* hash-based media storage
|
||||
|
||||
---
|
||||
|
||||
**Status:** Approved for production
|
||||
**Next steps:** API design, public profile queries, legacy user migration
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user