Skip to content

Latest commit

 

History

History
151 lines (112 loc) · 5.1 KB

File metadata and controls

151 lines (112 loc) · 5.1 KB

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

Please read the separate file STYLE.md for some guidance on coding style.