Files
turbovault-app/docs/REQUIREMENTS.md
2026-03-28 19:24:29 -04:00

17 KiB

TurboVault Web - Requirements Document

Project Overview

TurboVault is a video game collection tracker for managing both physical and digital game collections. Users can organize their games into collections and subcollections, track what they're playing, rate games, and view their collection statistics.

Target Users: Video game collectors who want to catalog and track their physical and digital game libraries.


Technical Stack

  • Framework: Rails 8.1.2
  • Database: PostgreSQL (all environments) with Row Level Security (RLS)
  • Frontend: Hotwire (Turbo + Stimulus), Importmap
  • Development: Nix + direnv for environment management, Taskfile for task automation, Docker Compose for services
  • Authentication: Built-in (email/password) → SSO in Phase 2
  • API: RESTful JSON API for all CRUD operations
  • Future Integrations: IGDB API for game metadata

User Roles & Authentication

Phase 1: Built-in Authentication

  • Email/password authentication
  • Password reset flow
  • Email verification (optional but recommended)
  • Session management

Users

  • Each user has their own collections
  • Collections are private by default
  • Users can opt-in to make collections public on their profile
  • User profiles: Keep simple (username, optional bio, collection visibility settings)

Phase 1: Core Features (MVP)

1. Game Management

Game Attributes:

  • Title (required)
  • Platform/System (required) - e.g., Nintendo 64, PlayStation 5, PC
  • Genres (multiple) - e.g., RPG, Action, Puzzle
  • Format: Physical or Digital (required)
  • Date Added to Collection (auto-set, editable)
  • Completion Status: Backlog, Currently Playing, Completed, On Hold, Not Playing
  • User Rating (optional, 1-5 stars)
  • Notes (freeform text field)

Physical Game Specific:

  • Condition: CIB (Complete in Box), Loose, Sealed, etc.
  • Price Paid (optional, decimal)
  • Location (optional, freeform text) - e.g., "Shelf A", "Storage Box 3"

Digital Game Specific:

  • Digital Store/Platform - e.g., Steam, PlayStation Store, eShop

Game Entry:

  • Pick from existing game list (seeded database)
  • If not found, allow user to create custom game entry
  • All fields manually editable

2. Collections & Organization

Collections:

  • Users can create multiple collections
  • Collections can have subcollections (nested one level)
    • Example: "Nintendo 64 Games" → "Mario Games" subcollection
  • Collections have: Name, Description (optional), Game count
  • Games can belong to multiple collections

Default Views:

  • All Games (full library)
  • By Platform (all games for a specific system)
  • By Genre (all games of a specific genre)
  • By Collection (user-created collections)
  • Currently Playing
  • Completed Games
  • Backlog

3. Search, Filter & Sort

Search:

  • Search by game title
  • Search across all user's games

Filter:

  • By Platform
  • By Genre
  • By Format (Physical/Digital)
  • By Completion Status
  • By Collection

Sort:

  • Alphabetically (A-Z, Z-A)
  • Date Added (newest/oldest)
  • Rating (highest/lowest)
  • Platform

4. Statistics & Dashboard

Collection Stats:

  • Total games in collection
  • Games by platform (count)
  • Games by genre (count)
  • Physical vs Digital breakdown
  • Completion statistics (backlog count, completed count, etc.)
  • Total spent (sum of price paid fields)

Dashboard:

  • Recently added games
  • Currently playing games
  • Collection overview stats
  • Quick actions (Add game, View collection, etc.)

5. Non-Game Items (Nice to Have - Phase 1 if time permits)

Item Types:

  • Consoles
  • Controllers
  • Accessories/Peripherals
  • Other (freeform)

Attributes:

  • Name
  • Type
  • Platform/Compatibility
  • Condition
  • Price Paid (optional)
  • Location (optional)
  • Date Added
  • Notes

6. User Profiles & Privacy

Profile Settings:

  • Username (required, unique)
  • Email (required)
  • Bio (optional)
  • Privacy: Make collection public/private toggle

Public Profile (when opted-in):

  • Show username and bio
  • Show public collections
  • Show basic stats (total games, platforms collected, etc.)
  • Hide personal data (email, prices paid, locations)

7. Bulk Game Insert

Critical for user onboarding - Allow users to quickly add multiple games at once:

  • Upload CSV file with game data
  • Or use a multi-row form interface
  • Validate entries before saving
  • Show summary of successful/failed imports
  • Support bulk adding to specific collection

CSV Format (minimum required fields):

  • Title, Platform, Format (Physical/Digital)
  • Optional fields: Genres, Condition, Price Paid, Date Added, Location, Notes, Rating, Completion Status

8. RESTful API

All features must be accessible via API endpoints for future integrations:

  • GET /api/v1/games - List user's games (with filters)
  • POST /api/v1/games - Create new game
  • POST /api/v1/games/bulk - Bulk create games
  • GET /api/v1/games/:id - Show game details
  • PUT/PATCH /api/v1/games/:id - Update game
  • DELETE /api/v1/games/:id - Delete game
  • Similar endpoints for collections, items, etc.

Authentication:

  • Web users: Session-based authentication (standard Rails sessions)
  • API users: Token-based authentication (API keys) for external integrations
  • Support both authentication methods simultaneously

API Token Permissions:

  • API tokens have the same permissions as the user who created them
  • Tokens are scoped to the user's own data only (can't access other users' collections)
  • Users can only create/read/update/delete their own games, collections, and items

Data Models

User

  • email (string, required, unique, indexed)
  • encrypted_password (string, required)
  • username (string, required, unique, indexed)
  • bio (text, optional)
  • profile_public (boolean, default: false)
  • timestamps

ApiToken

  • user_id (foreign key, required, indexed)
  • token (string, required, unique, indexed)
  • name (string, optional) - e.g., "Mobile App", "Third Party Integration"
  • last_used_at (datetime, optional)
  • expires_at (datetime, optional)
  • timestamps

Game

  • user_id (foreign key, required, indexed)
  • title (string, required, indexed)
  • platform_id (foreign key, required, indexed)
  • format (enum: physical/digital, required)
  • date_added (date, required, default: today)
  • completion_status (enum: backlog/currently_playing/completed/on_hold/not_playing, optional)
  • user_rating (integer 1-5, optional) - 5-star system
  • notes (text, optional)
  • Physical fields:
    • condition (enum: cib/loose/sealed/good/fair, optional)
    • price_paid (decimal, optional)
    • location (string, optional)
  • Digital fields:
    • digital_store (string, optional) - e.g., "Steam", "PlayStation Store"
  • custom_entry (boolean, default: false) - true if user-created
  • igdb_id (integer, optional, indexed) - for future IGDB integration
  • timestamps

Platform

  • name (string, required, unique) - e.g., "Nintendo 64", "PlayStation 5"
  • abbreviation (string, optional) - e.g., "N64", "PS5"
  • manufacturer (string, optional) - e.g., "Nintendo", "Sony"
  • timestamps

Genre

  • name (string, required, unique) - e.g., "RPG", "Action", "Puzzle"
  • timestamps

GameGenre (Join Table)

  • game_id (foreign key, required, indexed)
  • genre_id (foreign key, required, indexed)

Collection

  • user_id (foreign key, required, indexed)
  • parent_collection_id (foreign key, optional, indexed) - for subcollections
  • name (string, required)
  • description (text, optional)
  • timestamps

CollectionGame (Join Table)

  • collection_id (foreign key, required, indexed)
  • game_id (foreign key, required, indexed)
  • position (integer, optional) - for manual ordering

Item (Nice to Have - Phase 1)

  • user_id (foreign key, required, indexed)
  • name (string, required)
  • item_type (enum: console/controller/accessory/other, required)
  • platform_id (foreign key, optional)
  • condition (string, optional)
  • price_paid (decimal, optional)
  • location (string, optional)
  • date_added (date, required, default: today)
  • notes (text, optional)
  • igdb_id (integer, optional, indexed) - for future integration
  • timestamps

Relationships:

  • User has_many :games
  • User has_many :collections
  • User has_many :items
  • User has_many :api_tokens
  • ApiToken belongs_to :user
  • Game belongs_to :user
  • Game belongs_to :platform
  • Game has_many :genres, through: :game_genres
  • Game has_many :collections, through: :collection_games
  • Collection belongs_to :user
  • Collection belongs_to :parent_collection (optional, self-referential)
  • Collection has_many :subcollections (self-referential)
  • Collection has_many :games, through: :collection_games
  • Platform has_many :games
  • Genre has_many :games, through: :game_genres

Phase 2: Future Features

Images

  • Game cover art
  • Item photos
  • User avatars

Wishlist

  • Games user wants to buy
  • Price tracking for wishlisted games
  • Notifications when price drops

Digital Library Integration

  • Auto-import from Steam, PlayStation, Xbox, Nintendo
  • Auto-update when new games purchased
  • Sync digital library periodically

SSO (Single Sign-On)

  • OAuth with Google, GitHub, etc.
  • Keep email/password as fallback

IGDB Integration

  • Search IGDB when adding games
  • Auto-populate game metadata (title, genres, release date, cover art)
  • Sync game data periodically

Market Value Tracking

  • Integration with PriceCharting API or similar
  • Show estimated current market value
  • Track value over time

Enhanced Features

  • Game history/timeline
  • Play session tracking
  • Achievement/trophy tracking
  • Social features (friends, sharing collections)
  • Collection import/export (CSV, JSON)

UI/UX Guidelines

Design Style

  • Clean, modern interface
  • Focus on readability and quick data entry
  • Mobile-responsive (mobile-first approach)

Styling Framework

  • Recommendation: Tailwind CSS (modern, utility-first, great with Hotwire)
  • Alternative: Bootstrap or custom CSS

Key Pages/Views

  1. Homepage/Landing - Public landing page with login/signup
  2. Dashboard - Main view after login, shows stats and recent activity
  3. Game Library - Full game list with filters, search, sort
  4. Game Detail - Individual game view/edit page
  5. Add Game - Form to add new game (with search/create flow)
  6. Bulk Import - Upload CSV or multi-row form to add multiple games
  7. Collections - List of user's collections
  8. Collection Detail - Games within a specific collection
  9. Platform View - All games for a specific platform
  10. Genre View - All games of a specific genre
  11. Settings - User profile, privacy settings, and API token management
  12. Public Profile - View-only profile page (when public)

UX Considerations

  • Quick add game flow (minimal clicks)
  • Bulk actions (add multiple games to collection, etc.)
  • Keyboard shortcuts for power users
  • Auto-save forms where possible
  • Clear visual distinction between physical and digital games
  • Empty states with helpful CTAs

Security & Performance

Security

  • CSRF protection (Rails default)
  • XSS prevention (Rails default)
  • SQL injection prevention (use parameterized queries)
  • Secure password storage (bcrypt)
  • HTTPS only in production
  • Rate limiting on API endpoints
  • User data isolation (users can only access their own data)
  • PostgreSQL Row Level Security (RLS):
    • Enable RLS on all user-scoped tables (games, collections, items, api_tokens)
    • Create policies to ensure users can only access their own data
    • Defense in depth - even if application logic fails, database enforces isolation
    • Example: CREATE POLICY user_games ON games FOR ALL TO app_user USING (user_id = current_setting('app.current_user_id')::bigint);

Performance

  • Database indexing on foreign keys and commonly queried fields
  • Pagination for large game lists (25-50 per page)
  • Eager loading to avoid N+1 queries
  • Consider caching for stats and public profiles

Testing Strategy

  • Unit tests: Models and business logic
  • Integration tests: Controllers and API endpoints
  • System tests: Key user flows (add game, create collection, etc.)
  • Target coverage: 80%+
  • Framework: Minitest (Rails default)

Critical flows to test:

  1. User registration and authentication
  2. Add game to collection
  3. Bulk import games (CSV)
  4. Create and manage collections
  5. Search and filter games
  6. Update game details
  7. API endpoints
  8. RLS policies (ensure users can't access other users' data)

Deployment

  • Hosting: Kamal (already configured) or Railway/Render for simplicity
  • Database: PostgreSQL (all environments - dev, test, production)
  • Storage: Local filesystem initially, S3 for Phase 2 (images)
  • Email: Postmark or Sendgrid
  • Monitoring: Sentry or Honeybadger for errors

Database Setup Notes:

  • Use Docker Compose for PostgreSQL (see docker-compose.yml in project root)
  • Run docker compose up -d to start PostgreSQL container
  • Enable and configure Row Level Security (RLS) policies during initial migration
  • Set up database user with appropriate permissions for RLS

CI/CD

  • Gitea Actions (run tests on push, deploy on merge to main)

Seed Data

Initial Platforms (Examples)

  • Nintendo: NES, SNES, N64, GameCube, Wii, Wii U, Switch
  • Sony: PlayStation, PS2, PS3, PS4, PS5, PSP, PS Vita
  • Microsoft: Xbox, Xbox 360, Xbox One, Xbox Series X/S
  • Sega: Genesis, Saturn, Dreamcast, Game Gear
  • PC, Mobile (iOS/Android), Arcade

Initial Genres (Examples)

  • Action, Adventure, RPG, JRPG, Strategy, Simulation
  • Platformer, Fighting, Racing, Sports, Puzzle
  • Horror, Stealth, Shooter (FPS/TPS), Rhythm, Visual Novel

Sample Games (for testing)

  • Seed 20-30 popular games across different platforms for testing

Success Metrics

  • User can add their first game in < 2 minutes
  • Search returns results in < 500ms
  • Mobile-responsive on all major screen sizes
  • API response time < 200ms for standard queries
  • Zero data leaks between users

Decisions Made

  1. Completion status values: Backlog, Currently Playing, Completed, On Hold, Not Playing
  2. Rating scale: 5-star system (1-5 integer)
  3. Subcollections: One level deep only
  4. API authentication: Session-based for web users, API token-based for external integrations
  5. Game list source: Manually seeded for now, IGDB integration in Phase 2. Add igdb_id field for future linking
  6. API token permissions: Same permissions as the user who created them (scoped to own collection)
  7. Database: PostgreSQL with Row Level Security (RLS) for all environments

Out of Scope (Phase 1)

  • Images/cover art
  • Wishlist functionality
  • Digital library auto-import
  • SSO/OAuth
  • IGDB API integration (will be manual entry only)
  • Market value tracking/price alerts
  • Social features (following, sharing)
  • Mobile native apps
  • Game recommendations

Timeline Suggestion

Week 1-2: Setup (Docker, PostgreSQL, models, migrations, authentication) Week 3-4: Core game CRUD, bulk import, collections, API Week 5-6: Search/filter, stats, UI polish Week 7-8: Testing, RLS policies, bug fixes, deployment

Getting Started

Prerequisites

  • Nix with direnv
  • All dependencies (Ruby, Task, Docker, PostgreSQL client) are automatically available via Nix shell environment

Environment Setup

When you cd into the project directory, direnv will automatically load the Nix environment:

cd turbovault-web
# direnv loads automatically, making Ruby, Task, Docker, etc. available

If this is your first time, allow direnv:

direnv allow

Quick Setup

Option 1: One Command Setup

task setup

This runs: PostgreSQL startup, dependency installation, and database setup.

Option 2: Step by Step

# 1. Start PostgreSQL container
task docker:up

# 2. Install dependencies
task install

# 3. Setup database (create, migrate, seed)
task db:setup

# 4. Start Rails server
task server

Common Development Tasks

task                    # List all available tasks
task server             # Start Rails server
task console            # Rails console
task test               # Run tests
task lint               # Run RuboCop
task security           # Run security checks
task db:migrate         # Run migrations
task db:reset           # Reset database
task docker:logs        # View PostgreSQL logs
task docker:down        # Stop PostgreSQL

See Taskfile.yml for complete list of tasks.


Notes

  • Keep API-first approach in mind - all web features should be available via API
  • Design database with future IGDB integration in mind (igdb_id fields added)
  • Consider adding soft deletes for games/collections (paranoia gem)
  • Make sure to handle timezones properly for date_added fields
  • Nix + direnv manages all development dependencies (Ruby, Task, Docker, PostgreSQL)
  • Docker Compose is used for PostgreSQL - makes setup consistent across environments
  • Taskfile is used for development tasks - run task to see all available commands (provided via Nix)
  • Default dev credentials: postgres/postgres (configure via ENV vars for production)