Dress to Impress, a big fancy Neopets customization tool!
Find a file
Emi Matchu 629090a88c docs: clarify Impress 2020 database dependencies
Added critical information about database consolidation blocker:

- Impress 2020 directly accesses BOTH openneo_impress and openneo_id databases
- Any database consolidation must wait until Impress 2020 is retired
- Database migration is ready on feature/consolidate-auth-database branch
  but is blocked on this dependency

This ensures we don't accidentally deploy the database consolidation
before addressing the Impress 2020 dependency, which would break
authentication for users accessing the site through Impress 2020.

Updated sections:
- Deployment Architecture: Clarified both databases are accessed by I2020
- After Full Migration: Noted database consolidation is ready but blocked
- Added new "Database Consolidation Blocker" section with details

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 07:09:11 +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 Add support summary UI to alt styles page 2025-11-02 06:12:36 +00:00
bin Update devcontainer 2025-10-30 02:16:54 +00:00
config Update devcontainer 2025-10-30 02:16:54 +00:00
db Add configurable full name field to alt styles 2025-02-15 21:52:47 -08:00
deploy Add more importing to cron 2025-11-02 06:00:50 +00:00
docs docs: clarify Impress 2020 database dependencies 2025-11-02 07:09:11 +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 Add high-level documentation 2025-10-30 07:31:36 +11: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 databases: Primary database (openneo_impress) + legacy auth database (openneo_id)
  • 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                    # Multi-database setup (main + openneo_id)
└── 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 (two databases: openneo_impress, openneo_id)
  • 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

OpenNeo ID Database

The openneo_id database is a legacy from when authentication was a separate service ("OpenNeo ID") meant to unify auth across multiple OpenNeo projects. DTI was the only project that succeeded, so the apps were merged—but the database split remains for now.

Implication: Rails is configured for multi-database mode. User auth models live in auth_user.rb and connect to openneo_id.

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