Skip to content

Latest commit

 

History

History
151 lines (112 loc) · 5.04 KB

File metadata and controls

151 lines (112 loc) · 5.04 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

@STYLE.md