Files
SkinbaseNova/.copilot/update_user_schema.md
2026-02-08 10:42:01 +01:00

313 lines
5.6 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.
# 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 Whats 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
```