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

5.6 KiB
Raw Blame History

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

Add indexes for common query patterns:

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:

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):

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:

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:

avatar VARCHAR(255)

Recommended future approach:

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.1 Current Design

  • One row per platform per user
  • Unique constraint on (user_id, platform)
  • Cascade delete enabled

This is solid.

Current:

platform VARCHAR(32)

Risk:

  • inconsistent values (twitter, x, Twitter, etc.)

Options:

Option A Enum (simple):

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:

UPDATE user_statistics SET downloads = downloads + 1;

At scale, this causes:

  • row locking
  • write contention
  • degraded performance
  • 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:

utf8mb4_unicode_ci

This is correct and safe.

Optional upgrade (MySQL 8+):

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:

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