Dress to Impress, a big fancy Neopets customization tool!
Find a file
Emi Matchu f311c92dbb docs: add deployment checklist for database consolidation
IMPORTANT: This migration is BLOCKED until Impress 2020 is retired.

Created comprehensive deployment guide documenting:
- Why this migration is blocked (Impress 2020 uses openneo_id directly)
- Two paths forward: retire Impress 2020 (recommended) or coordinated update
- Complete step-by-step deployment checklist for when ready
- Rollback procedures
- Risk assessment and mitigations
- Success criteria and timeline estimates

This ensures we don't accidentally deploy this change before addressing
the Impress 2020 dependency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 07:07:57 +00:00
.devcontainer Set up deployment inside devcontainer 2025-11-02 04:02:06 +00:00
.husky Add RSpec to the commit hook 2024-10-24 15:22:39 -07:00
app feat: migrate AuthUser to main database 2025-11-02 06:55:11 +00:00
bin Update devcontainer 2025-10-30 02:16:54 +00:00
config feat: migrate AuthUser to main database 2025-11-02 06:55:11 +00:00
db chore: document legacy openneo_id migrations and update references 2025-11-02 07:02:43 +00:00
deploy chore: document legacy openneo_id migrations and update references 2025-11-02 07:02:43 +00:00
docs docs: add deployment checklist for database consolidation 2025-11-02 07:07:57 +00:00
lib Add more importing to cron 2025-11-02 06:00:50 +00:00
public Run rails app:update to update config files 2025-01-12 12:36:18 -08:00
spec Add logging for alt style changes 2025-11-02 04:18:33 +00:00
test Add assets to modeling tests, and also uhh some other fixes 2024-10-21 16:46:10 -07:00
vendor Moderize RocketAMF C types to fix build error 2025-10-30 02:45:56 +00:00
.eslintrc.json Set up eslint for wardrobe-2020 2023-11-02 18:11:07 -07:00
.gitignore Improve Solargraph LSP in our spec files 2024-11-19 11:28:36 -08:00
.rspec Move modeling tests to RSpec 2024-10-21 16:03:58 -07:00
.ruby-version Upgrade to Ruby 3.4.5, Rails 8.0.2 2025-07-23 20:39:27 -07:00
.solargraph.yml Add Solargraph autocomplete while in development 2024-07-01 15:35:39 -07:00
.yarnrc.yml Upgrade to Yarn 4.0.2 2024-01-14 23:05:53 -08:00
config.ru Upgrade to Rails 6.1.7.4 2023-10-23 19:05:07 -07:00
falcon.rb Remove supervisor from the Falcon process? 2024-01-24 00:20:23 -08:00
Gemfile Moderize RocketAMF C types to fix build error 2025-10-30 02:45:56 +00:00
Gemfile.lock Moderize RocketAMF C types to fix build error 2025-10-30 02:45:56 +00:00
LICENSE.md Update GitHub links to point to our self-hosted OpenNeo Code 2024-02-29 11:24:21 -08:00
package.json Upgrade esbuild to 0.25.3 2025-04-27 12:23:12 -07:00
Procfile.dev Update devcontainer 2025-10-30 02:16:54 +00:00
Rakefile Uninstall resque 2023-10-23 19:05:04 -07:00
README.md chore: document legacy openneo_id migrations and update references 2025-11-02 07:02:43 +00:00
yarn.lock Upgrade esbuild to 0.25.3 2025-04-27 12:23:12 -07:00

Dress to Impress beach logo

Dress to Impress

Dress to Impress (DTI) is a tool for designing Neopets outfits. Load your pet, browse items, and see how they look together—all with a mobile-friendly interface!

Architecture Overview

DTI is a Rails application with a React-based outfit editor, backed by MySQL databases and a crowdsourced data collection system.

Core Components

  • Rails backend (Ruby 3.4, Rails 8.0): Serves web pages, API endpoints, and manages data
  • MySQL database: Single database (openneo_impress) containing all application and authentication data
  • React outfit editor: Embedded in app/javascript/wardrobe-2020/, provides the main customization UI
  • Modeling system: Crowdsources pet/item appearance data by fetching from Neopets APIs when users load their pets

The Impress 2020 Complication

In 2020, we started a NextJS rewrite ("Impress 2020") to modernize the frontend. We've since consolidated back into Rails, but Impress 2020 still provides essential services:

  • GraphQL API: Some outfit appearance data still loads via GraphQL (being migrated to Rails REST APIs)
  • Image generation: Runs a headless browser to render outfit thumbnails and convert HTML5 assets to PNGs

See docs/impress-2020-dependencies.md for migration status.

Key Concepts

Customization Data Model

The core data model powers outfit rendering and item compatibility. See docs/customization-architecture.md for details.

Quick summary:

  • body_id is the key compatibility constraint (not species or color directly)
  • Items have different swf_assets (visual layers) for different bodies
  • Restrictions are subtractive: start with all layers, hide some based on zone restrictions
  • Data is crowdsourced through "modeling" (users loading pets to contribute appearance data)

Modeling (Crowdsourced Data)

DTI doesn't pre-populate item/pet data. Instead:

  1. User loads a pet (via pet name lookup)
  2. DTI fetches appearance data from Neopets APIs (legacy Flash/AMF protocol)
  3. New SwfAsset records and relationships are created
  4. Over time, the database learns which items fit which pet bodies

This "self-sustaining" approach means the site stays up-to-date as Neopets releases new content, without manual data entry.

Directory Map

Key Application Files

app/
├── controllers/
│   ├── outfits_controller.rb       # Outfit editor + CRUD
│   ├── items_controller.rb         # Item search, pages, and JSON APIs
│   ├── pets_controller.rb          # Pet loading (triggers modeling)
│   └── closet_hangers_controller.rb # User item lists ("closets")
│
├── models/
│   ├── item.rb                     # Items + compatibility prediction logic
│   ├── pet_type.rb                 # Species+Color combinations (has body_id)
│   ├── pet_state.rb                # Visual variants (pose/gender/mood)
│   ├── swf_asset.rb                # Visual layers (biology/object)
│   ├── outfit.rb                   # Saved outfits + rendering logic (visible_layers)
│   ├── alt_style.rb                # Alternative pet appearances (Nostalgic, etc.)
│   └── pet/
│       └── modeling_snapshot.rb    # Processes Neopets API data into models
│
├── services/
│   ├── neopets/
│   │   ├── custom_pets.rb          # Neopets AMF/Flash API client (pet data)
│   │   ├── nc_mall.rb              # NC Mall item scraping
│   │   └── neopass.rb              # NeoPass OAuth integration
│   ├── neopets_media_archive.rb    # Local mirror of images.neopets.com
│   └── lebron_nc_values.rb         # NC item trading values (external API)
│
├── javascript/
│   ├── wardrobe-2020/              # React outfit editor (extracted from Impress 2020)
│   │   ├── loaders/                # REST API calls (migrated from GraphQL)
│   │   ├── WardrobePage/           # Main editor UI
│   │   └── components/             # Shared React components
│   └── application.js              # Rails asset pipeline entrypoint
│
└── views/
    ├── outfits/
    │   └── edit.html.haml          # Outfit editor page (loads React app)
    ├── items/
    │   └── show.html.haml          # Item detail page
    └── closet_hangers/
        └── index.html.haml         # User closet/item lists

Configuration & Docs

config/
├── routes.rb                       # All Rails routes
├── database.yml                    # Database configuration
└── environments/
    └── *.rb                        # Env-specific config (incl. impress_2020_origin)

Documentation:

Tests:

  • test/ - Test::Unit tests (privacy features)
  • spec/ - RSpec tests (models, services, integrations)
    • Coverage is focused on key areas: modeling, prediction logic, external APIs
    • Not comprehensive, but thorough for critical behaviors

Tech Stack

  • Backend: Ruby on Rails (Ruby 3.4, Rails 8.0)
  • Frontend: Mix of Rails views (Turbo/HAML) and React (for outfit editor)
  • Database: MySQL (openneo_impress)
  • Styling: CSS, Sass (moving toward modern Rails conventions)
  • External Integrations:
    • Neopets.com: Legacy Flash/AMF protocol for pet appearance data (modeling)
    • Neopets NC Mall: Web scraping for NC item availability/pricing
    • NeoPass: OAuth integration for Neopets account linking
    • Neopets Media Archive: Local filesystem mirror of images.neopets.com (never discards old files)
    • Lebron's NC Values: Third-party API for NC item trading values (lebron-values.netlify.app)
    • Impress 2020: GraphQL for some outfit data, image generation service (being phased out)

Development Notes

Authentication Architecture

Authentication data lives in the auth_users table (managed by the AuthUser model). This was historically in a separate openneo_id database (a legacy from when "OpenNeo ID" was envisioned as a service to unify auth across multiple OpenNeo projects). As of November 2025, the databases have been consolidated into a single database for simplicity.

User accounts are split across two related tables:

  • auth_users - Authentication data (passwords, email, OAuth connections) via Devise
  • users - Application data (points, closet settings, etc.)

These are linked via User.remote_idAuthUser.id. See db/openneo_id_migrate/README.md for the historical context.

Rails/React Hybrid

Most pages are traditional Rails views using Turbo for interactivity. The outfit editor (/outfits/new) is a full React app that:

  • Loads into a #wardrobe-2020-root div
  • Uses React Query for data fetching
  • Calls both Rails REST APIs (in loaders/) and Impress 2020 GraphQL (being migrated)

The goal is to simplify this over time—either consolidate into Rails+Turbo, or commit fully to React. For now, we're in a hybrid state.

Deployment

  • Main app: VPS running Rails (Puma, MySQL)
  • Impress 2020: Separate VPS in same datacenter (NextJS, GraphQL, headless browser for images)
  • Both services share the same MySQL database (Impress 2020 makes SQL calls over the network)

Project maintained by @matchuOpenNeo.net