{
  "markdown": "# Showcase\n\nIn between updates to [Agile Web Development with Rails\n8](https://pragprog.com/titles/rails8/agile-web-development-with-rails-8/), I\nkeep my Rails skills sharp by developing small applications.\n\nI also take ballroom dance lessons with my wife, and we have competed\ninternationally and at smaller local competitions.  For larger events there is commercial\nsoftware for scheduling \"heats\" where dancers go on the floor and be judged.\nSmaller competitions use spreadsheets to track this.\n\nScheduling is deceptively hard, particularly if you have last minute changes\nsuch as an instructor not being able to make the competition for any reason.\nManually making last minute changes can lead to scheduling mishaps, such as\nhaving the same person being scheduled twice with different partners for the\nsame heat.\n\nThis application manages showcase events, from data entry to scheduling, to\ngenerating of printed reports.  It can also be accessed by participants\non the day of the event to see the list of heats, and by judges to enter\nscores.\n\n# Getting up and running - bare metal, one event\n\nPrerequisites:\n[git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and\n[ruby](https://www.ruby-lang.org/en/documentation/installation/).\n\n```\ngit clone https://github.com/rubys/showcase.git\ncd Showcase\nbundle install\nbin/rails db:prepare\nbin/rails test\nbin/rails test:system\nbin/dev\n```\n\nVisit http://localhost:3000/ to see the event.\n\n# Getting up and running - docker image, multiple events\n\nPrerequisites:\n[git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git),\n[ruby](https://www.ruby-lang.org/en/documentation/installation/), and\n[docker](https://docs.docker.com/get-docker/).\n\n```\ngit clone https://github.com/rubys/showcase.git\ncd Showcase\nbundle install\nrm config/credentials.yml.enc\nbin/rails credentials:edit\ndocker compose build\ndocker compose up\ndocker compose exec web bin/bootstrap\n```\n\nNote: Showcase configuration is managed via the admin interface at `/admin`, which stores data in `db/index.sqlite3` and generates `db/showcases.yml` automatically.\n\nVisit http://localhost:9999/showcase/ to see the list of events.\n\n# Implementation overview\n\nThis is pretty much a standard\n[CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) Rails 8.0.2\napplication using import maps for JavaScript and\n[TailwindCSS](https://tailwindcss.com/) for CSS. The application uses Rails 8.0\nconfiguration defaults and has been fully migrated to be compatible with SQL\nreserved word quoting requirements. \n\nModels are split into two categories:\n\n**Base models** support ballroom dance event management:\n- Core competition: Event (singleton config), Person (all participants, STI disabled),\n  Studio (with pairs), Dance (with scrutineering), Category (with extensions),\n  Age, Level\n- Heat & performance: Heat (numbered sessions), Entry (connects lead/follow/instructor),\n  Solo (routines with optional formations), Formation (individual participants),\n  Multi, MultiLevel\n- **Heats are numbered** - all Heat records with the same number are on the floor\n  simultaneously. Heats with `number >= 1` are scheduled; `number < 0` indicates\n  scratched (withdrawn) heats that can be restored or permanently deleted\n- **Split dances** - when a dance appears in multiple categories, there are multiple\n  Dance records with the same name: one with positive order (canonical), others with\n  `order < 0` that sync properties from the canonical dance\n- Judging & scoring: Judge, Score (live updates via ActionCable), Recording\n- Financial: Billable (packages/options, STI disabled), PackageInclude, PersonOption,\n  Payment\n- Seating: Table (grid positioning), StudioPair\n- Music & questionnaires: Song, Question, Answer, Feedback\n\n**Admin models** support system administration and multi-tenancy: Locale (service class),\nLocation, Showcase, User, Region, ApplicationRecord (base class with Tigris storage\nintegration).\n\nThe heat scheduler in\n[app/controllers/concerns/heat_scheduler.rb](./app/controllers/concerns/heat_scheduler.rb)\nuses a two-pass algorithm: first minimizing heat count, then balancing heat \nsizes. It interleaves different dance types within agenda categories and \nappends manually-ordered solos.\n\nThe table assignment system in\n[app/controllers/concerns/table_assigner.rb](./app/controllers/concerns/table_assigner.rb)\nand [app/controllers/tables_controller.rb](./app/controllers/tables_controller.rb)\noffers two algorithms: **Regular Assignment** prioritizes keeping studios\ntogether, while **Pack Assignment** maximizes table utilization. Both use a\ntwo-phase algorithm (Phase 1 groups people into tables, Phase 2 places tables\non grid) and achieve 100% success rate for large studios (>10 people) and studio\npairs. Key features include:\n- Event Staff isolation (studio_id = 0 never mixed with other studios)\n- Studio Pair Handling (paired studios share tables or are placed adjacent)\n- Optimal table utilization (fits small studios into existing tables first)\n- Global position reservation with priority system (0-3)\n- Contiguous block placement for large studios\n- Smart consolidation to minimize total table count\n- Sequential numbering following physical grid layout (row-major order)\n- Drag-and-drop grid interface for manual arrangement\n- Handles option tables via person_options join table\n\nThe application is designed to scale from single events to hundreds of simultaneous events across multiple regions using a shared-nothing architecture. See [ARCHITECTURE.md](./ARCHITECTURE.md) for details on the production deployment architecture using Navigator, Fly.io, and Tigris storage.\n",
  "bytes": 5639,
  "sha": "67500e844c8cbbccfc46977596bb285aecc9b65600f35d7acb5fdee539df0080",
  "repo_slug": "rubys/showcase",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/skl_rubys_showcase_claude_skills_fly_ssh_mai_5137885b/readme"
}