The AGENTS.md file from the Fizzy.do project
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://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:
1. Rubocop (style)
2. Bundler audit (gem security)
3. Importmap audit
4. Brakeman (security scan)
5. Application tests
6. 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)
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 sets Current.account
- The slug is moved from PATH_INFO to SCRIPT_NAME, making Rails think it's "mounted" at that path
- All models include account_id for 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 have Users in multiple Accounts
- Users belong to an Account and have roles: owner, admin, member, system
- Sessions managed via signed cookies
- Board-level access control via Access records
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 Access records
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 particulars for 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/.last work correctly in tests
Background Jobs (Solid Queue)
Database-backed job queue (no Redis):
- Custom FizzyActiveJobExtensions prepended 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/
Tools
Chrome MCP (Local Dev)
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.
Coding style
@STYLE.md
# 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
```bash
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
### Testing
```bash
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:
1. Rubocop (style)
2. Bundler audit (gem security)
3. Importmap audit
4. Brakeman (security scan)
5. Application tests
6. System tests
### Database
```bash
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
```bash
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)
```
## 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 sets `Current.account`
- The slug is moved from `PATH_INFO` to `SCRIPT_NAME`, making Rails think it's "mounted" at that path
- All models include `account_id` for 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 have `Users` in multiple Accounts
- Users belong to an Account and have roles: owner, admin, member, system
- Sessions managed via signed cookies
- Board-level access control via `Access` records
### 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 `Access` records
**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 `particulars` for 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`/`.last` work correctly in tests
### Background Jobs (Solid Queue)
Database-backed job queue (no Redis):
- Custom `FizzyActiveJobExtensions` prepended 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/`
## Tools
### Chrome MCP (Local Dev)
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.
## Coding style
@STYLE.md