This file provides guidance to AI coding agents working with this repository.
Fizzy is a collaborative project management and issue tracking application built by 37signals/Basecamp. It's a kanban-style tool for teams to create and manage cards (tasks/issues) across boards, organize work into columns representing workflow stages, and collaborate via comments, mentions, and assignments.
bin/setup # Initial setup (installs gems, creates DB, loads schema)
bin/dev # Start development server (runs on port 3006)Development URL: http://fizzy.localhost:3006 Login with: david@example.com (development fixtures), password will appear in the browser console
bin/rails test # Run unit tests (fast)
bin/rails test test/path/file_test.rb # Run single test file
bin/rails test:system # Run system tests (Capybara + Selenium)
bin/ci # Run full CI suite (style, security, tests)
# For parallel test execution issues, use:
PARALLEL_WORKERS=1 bin/rails testCI pipeline (bin/ci) runs:
- Rubocop (style)
- Bundler audit (gem security)
- Importmap audit
- Brakeman (security scan)
- Application tests
- System tests
bin/rails db:fixtures:load # Load fixture data
bin/rails db:migrate # Run migrations
bin/rails db:reset # Drop, create, and load schemabin/rails dev:email # Toggle letter_opener for email preview
bin/jobs # Manage Solid Queue jobs
bin/kamal deploy # Deploy (requires 1Password CLI for secrets)Fizzy uses URL path-based multi-tenancy:
- Each Account (tenant) has a unique
external_account_id(7+ digits) - URLs are prefixed:
/{account_id}/boards/... - Middleware (
AccountSlug::Extractor) extracts the account ID from the URL and setsCurrent.account - The slug is moved from
PATH_INFOtoSCRIPT_NAME, making Rails think it's "mounted" at that path - All models include
account_idfor data isolation - Background jobs automatically serialize and restore account context
Key insight: This architecture allows multi-tenancy without subdomains or separate databases, making local development and testing simpler.
Passwordless magic link authentication:
- Global
Identity(email-based) can haveUsersin multiple Accounts - Users belong to an Account and have roles: owner, admin, member, system
- Sessions managed via signed cookies
- Board-level access control via
Accessrecords
Account → The tenant/organization
- Has users, boards, cards, tags, webhooks
- Has entropy configuration for auto-postponement
Identity → Global user (email)
- Can have Users in multiple Accounts
- Session management tied to Identity
User → Account membership
- Belongs to Account and Identity
- Has role (owner/admin/member/system)
- Board access via explicit
Accessrecords
Board → Primary organizational unit
- Has columns for workflow stages
- Can be "all access" or selective
- Can be published publicly with shareable key
Card → Main work item (task/issue)
- Sequential number within each Account
- Rich text description and attachments
- Lifecycle: triage → columns → closed/not_now
- Automatically postpones after inactivity ("entropy")
Event → Records all significant actions
- Polymorphic association to changed object
- Drives activity timeline, notifications, webhooks
- Has JSON
particularsfor action-specific data
Cards automatically "postpone" (move to "not now") after inactivity:
- Account-level default entropy period
- Board-level entropy override
- Prevents endless todo lists from accumulating
- Configurable via Account/Board settings
All tables use UUIDs (UUIDv7 format, base36-encoded as 25-char strings):
- Custom fixture UUID generation maintains deterministic ordering for tests
- Fixtures are always "older" than runtime records
.first/.lastwork correctly in tests
Database-backed job queue (no Redis):
- Custom
FizzyActiveJobExtensionsprepended to ActiveJob - Jobs automatically capture/restore
Current.account - Mission Control::Jobs for monitoring
Key recurring tasks (via config/recurring.yml):
- Deliver bundled notifications (every 30 min)
- Auto-postpone stale cards (hourly)
- Cleanup jobs for expired links, deliveries
16-shard MySQL full-text search instead of Elasticsearch:
- Shards determined by account ID hash (CRC32)
- Search records denormalized for performance
- Models in
app/models/search/
URL: http://fizzy.localhost:3006
Login: david@example.com (passwordless magic link auth - check rails console for link)
Use Chrome MCP tools to interact with the running dev app for UI testing and debugging.
@STYLE.md