# Event Tracking

Builds event tracking, activity feeds, and webhook systems following 37signals patterns...

- Repository: https://github.com/ThibautBaissac/rails_ai_agents (671 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-06-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add ThibautBaissac/rails_ai_agents --skill event-tracking -g -a claude-code -y`
Codex: `npx skills add ThibautBaissac/rails_ai_agents --skill event-tracking -g -a codex -y`
Cursor: `npx skills add ThibautBaissac/rails_ai_agents --skill event-tracking -g -a cursor -y`
Gemini CLI: `npx skills add ThibautBaissac/rails_ai_agents --skill event-tracking -g -a gemini-cli -y`

## Description

Builds event tracking, activity feeds, and webhook systems following 37signals patterns with a generic Event model and Eventable concern. Use when implementing audit trails, activity feeds, event recording, webhooks, or when user mentions events, tracking, webhooks, or activity logs. WHEN NOT: For state changes as records (use state-records), for background job patterns (use job-patterns), for mailer delivery (use mailer-patterns).

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Event Tracking

## Philosophy: Generic Event Model + Eventable Concern

- One `Event` model with `action` string and `eventable` polymorphic association
- An `Eventable` concern mixed into models that need tracking
- Models call `track_event("closed", particulars: {...})` in their domain methods
- `particulars` JSON field stores action-specific metadata
- Events drive activity feeds, notifications, and webhook deliveries
- Everything is database-backed (Solid Queue for webhooks, no Redis/Kafka)

## Project Knowledge

**Stack:** Solid Queue for background jobs, Turbo Streams for real-time activity
feed updates, UUIDs for all primary keys, MySQL (SaaS) / SQLite (OSS).

**Multi-tenancy:** All events scoped to account via `account_id`. Events also
scoped to board via `board_id`.

**Commands:**
```bash
# Generate Event model
rails generate model Event action:string eventable:references{polymorphic} \
  board:references creator:references account:references particulars:json

# Generate Webhook models
rails generate model Webhook url:text name:string board:references \
  account:references subscribed_actions:text signing_secret:string active:boolean
rails generate model Webhook::Delivery webhook:references event:references \
  account:references state:string request:text response:text
rails generate model Webhook::DelinquencyTracker webhook:references \
  account:references consecutive_failures_count:integer first_failure_at:datetime
```

## Pattern 1: Event Model

See @references/domain-events.md for full implementation details.

A single generic `Event` model records all business events:

```ruby
# app/models/event.rb
class Event < ApplicationRecord
  include Notifiable, Particulars

  belongs_to :account, default: -> { board.account }
  belongs_to :board
  belongs_to :creator, class_name: "User"
  belongs_to :eventable, polymorphic: true

  has_many :webhook_deliveries, class_name: "Webhook::Delivery", dependent: :delete_all

The rest: https://github.com/ThibautBaissac/rails_ai_agents/blob/HEAD/.claude_37signals/skills/event-tracking/SKILL.md
