alex shapalov Profile picture
Dec 3 9 tweets 4 min read Read on X
37signals open-sourced Fizzy, their Kanban tracker for issues & ideas. @dhh

I went through the code and stole 10 patterns you can reuse in your own Rails / SaaS app 👇

github.com/basecamp/fizzy
1️⃣ Account slug multi-tenancy (no namespaced controllers)

Fizzy uses a rack middleware (AccountSlug::Extractor) that:

Pulls the numeric account id from the URL
Rewrites SCRIPT_NAME / PATH_INFO
Wraps the request in Current.with_account

Result: the whole app is effectively mounted at /{account_id} and controllers stay clean & non-multi-tenant-aware.Image
2️⃣ Base36 UUIDv7 primary keys

They store UUIDv7 in binary columns but expose them as 25-char base36 strings:

Ordered by time
Short enough to copy/paste
Still globally unique

It’s a great pattern if you want “nice” IDs without giving up UUID semantics. Image
3️⃣ Account-aware background jobs

Fizzy extends Active Job so that every job:

Captures Current.account when enqueued
Serializes it into the payload
Restores it and runs inside Current.with_account on perform

No more “oops this job ran for the wrong tenant” in Sidekiq. Image
4️⃣ Sharded full-text search per account

They define 16 Search::Record::Trilogy shard classes (search_records_0…15).

Shard chosen by CRC32(account_id)
Data is stemmed before save
Queries use boolean MATCH ... AGAINST scoped with an account_key

That’s a cheap way to keep search fast as data grows.Image
5️⃣ Bundled email notifications with time windows

Notification::Bundle keeps a rolling window per user (starts_at..ends_at):

Collects unread notifications in that window
Sends a single digest when the window closes
Marks bundle as delivered

You get “less spammy” notifications without complex logic in each notifier.Image
6️⃣ Entropy-driven auto-postponing of stale cards

Boards + accounts have “entropy” settings.

Card::Entropic looks at last_active_at and can:
Find cards “postponing soon”
Auto-move overdue ones into a Not now column with auto_postpone_all_due Image
7️⃣ Activity spike & stall detection

Each card has an ActivitySpike record.

When last_active_at changes, Fizzy queues detection jobs and uses a stalled scope for cards that stayed quiet for 14+ days.

Great pattern if you want to highlight “truly stuck” work automatically. Image
8️⃣ Access revocation that actually scrubs data

Board::Accessible doesn’t just remove “access”.

When a user loses access, it scrubs:
Mentions
Notifications

Watches

via raw SQL joins so nothing leaks from other cards. An underrated privacy & UX pattern. Image

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with alex shapalov

alex shapalov Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(