Using fizzy.localhost causes CORS errors when using minio for Active Storage because the minio endpoint is at minio.fizzy.localhost — a sibling subdomain, not a subdomain of the app host. Switching to app.fizzy.localhost makes both hosts subdomains of fizzy.localhost, resolving the CORS issue. See #2814 for the related minio CORS fix. fizzy.localhost will continue to work if people want to use it, but all docs and scripts have been updated to point to app.fizzy.localhost.
5.7 KiB
Fizzy
This file provides guidance to AI coding agents working with this repository.
What is Fizzy?
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.
Development Commands
Setup and Server
bin/setup # Initial setup (installs gems, creates DB, loads schema)
bin/dev # Start development server (runs on port 3006)
Development URL: http://app.fizzy.localhost:3006 Login with: david@example.com (development fixtures), password will appear in the browser console
Testing
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 test
CI pipeline (bin/ci) runs:
- Rubocop (style)
- Bundler audit (gem security)
- Importmap audit
- Brakeman (security scan)
- Application tests
- System tests
Database
bin/rails db:fixtures:load # Load fixture data
bin/rails db:migrate # Run migrations
bin/rails db:reset # Drop, create, and load schema
Other Utilities
bin/rails dev:email # Toggle letter_opener for email preview
bin/jobs # Manage Solid Queue jobs
bin/kamal deploy # Deploy (requires 1Password CLI for secrets)
Deploy
Default branch: main
Pre-deploy: bin/rails saas:enable
Deploy: bin/kamal deploy -d <destination>
Destinations: production, staging, beta, beta1, beta2, beta3, beta4
Note: beta is a template requiring BETA_NUMBER env var; typical targets are beta1-beta4.
Architecture Overview
Multi-Tenancy (URL-Based)
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.
Authentication & Authorization
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
Core Domain Models
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
Entropy System
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
UUID Primary Keys
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
Background Jobs (Solid Queue)
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
Sharded Full-Text Search
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/
Imports and exports
Allow people to move between OSS and SAAS Fizzy instances:
- Exports/Imports can be written to/read from local or S3 storage depending on the config of the instance (both must be supported)
- Must be able to handle very large ZIP files (500+GB)
- Models in
app/models/account/data_transfer/,app/models/zip_file
Tools
Chrome MCP (Local Dev)
URL: http://app.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.
Coding style
@STYLE.md