Projects
AI moderation and community tooling for IRL streamers

IRLBox

Multi-tenant SaaS giving each streamer a branded space, OBS-ready widgets, and an AI pipeline that transcribes, titles and emotionally scores every message that comes in.

Role
Solo — architecture, AI pipeline, interface
Period
2025 — Present
Type
Platforms
Status
production
140k
Lines of TypeScript
149
API routes
151
Test files
55
DB migrations
01

Showcase

2 videos
Loading showcase
33sIRLBox — The message queue before and after the AI pipeline scores it. Rendered live with Remotion, not a video file.
02

Walkthrough

Recorded in the product
The feed itself: chronological, everyone sees the same order. No ranking model decides what gets reach.
Where a voice message lands after the pipeline: transcribed, tagged (Consulta, Opinión, Historia…) and queued — read by a person before it airs.
A browser source URL, copied once and pasted into OBS — no install, no plugin, just a live widget the show can drop into any scene.
Moderation as a button anyone can reach, not just an admin queue — reporting a listing here is a first-class action, not a workaround.
A member profile as a real history — messages, listings and contributions — because the audience is people, not a subscriber count.
03

Overview

IRL streamers get sent a firehose of messages and audio from their audience, and the interesting problem is not filtering slurs — it is triage. Which of these hundreds of submissions is worth reading on stream right now?

IRLBox answers that by processing every submission through an AI pipeline: audio is transcribed with Whisper, a title and summary are generated so the streamer can scan instead of read, and an emotion and intensity score is attached so the genuinely heavy messages surface instead of drowning. The streamer moderates from a queue; the audience sees a public feed.

Each streamer runs on their own branded space with OBS-embeddable widgets, on shared infrastructure isolated by Postgres row-level security. Around that core sit classifieds, surveys, connections, a marketplace and a documentation portal — 149 API routes and roughly 140,000 lines of TypeScript.

04

Architecture

3 diagrams
01

System architecture

OutInViewertext, voiceMiddlewaretenant from domainRedis rate limitStreamer console149 routeswithTenant, withAuthAI pipelinePostgresrow-level securityRealtimesubscriptionsOBS sourceand public feed

Scroll to pan

Tenant resolution happens before anything else runs, and each of the 149 routes is wrapped rather than trusted. The OBS widget is a read path with unusual constraints, not a separate product.
02

What happens to a submission

TriageIngestread on streamrejectSubmissiontext or audioWhispertranscriptionTitle andsummaryEmotion andintensityQueueranked, scannableStreamerPublic feedand OBS widgetArchive andaudit trailPer-tenant toggles

Scroll to pan

The obvious build is a toxicity filter; the useful build is ranking. Titling, summarising and scoring every message is what turns three hundred pending submissions into a queue a streamer can read.
03

One deployment, many brands

Enforce, twiceResolvestreamer.irlbox.appMiddlewarecustom domainTenant contextwithAuth, withTenantwithAdminRoute handlerRow-levelsecurityShared PostgresPer-tenant themeand configuration

Scroll to pan

Isolation is structural, and asserted twice. Context is resolved once from the domain, re-asserted by a wrapper on every route, then enforced again by row-level security underneath — a route that forgets the tenant does not fit the pattern.
05

Screens

6 captures
IRLBox moderation queue listing incoming messages with tags and emotion columns
01Moderation queue — every submission titled, tagged and scored
IRLBox AI configuration panel with toggles for transcription, titles and emotional analysis
02The AI pipeline, exposed as switches the streamer controls
IRLBox message detail view showing emotional analysis output
03Message detail with the emotional readout
IRLBox OBS message widget overlay
04OBS widget — messages on stream
IRLBox public viewer feed
05The public feed viewers see
IRLBox audio message submission interface
06Voice submission — the input that feeds Whisper
06

Modules

7 units
01

Submissions & feed

The core loop: a viewer sends text or audio, the streamer triages it, and the public feed reflects what got through.

  • Text and voice submissions from viewers
  • Public feed with replies and threading
  • Viewer profiles with their own message history
  • Per-message detail with the full AI readout
02

AI pipeline

Every submission passes through transcription, summarisation and emotional analysis before it reaches a human.

  • Whisper transcription for audio messages
  • Generated titles and summaries so a queue is scannable
  • Emotion and intensity detection to surface what matters
  • Per-tenant toggles for each stage of the pipeline
03

OBS widgets

Embeddable browser sources that put the community on screen without the streamer alt-tabbing.

  • Message widget for reading submissions live
  • Now-playing widget
  • Links and announcement overlays
  • Built against the constraints of streaming software, not a normal browser
04

Moderation & admin

The streamer-facing console: the queue, the users, and every switch that changes how the pipeline behaves.

  • Moderation queue with search, filters and tags
  • User management and per-user history
  • Configuration for AI, forms and links
  • Audit trail on moderation actions
05

Community surfaces

The features that make a stream a community rather than a broadcast.

  • Classifieds and a marketplace
  • Surveys and polls
  • Connections and guest management
  • Announcements and editorial posts
06

Multi-tenancy

Every streamer is a tenant with their own branding and their own data, on one deployment.

  • Domain and subdomain tenant resolution in middleware
  • Row-level security as the isolation boundary
  • withTenant / withAuth / withAdmin wrappers on every API route
  • Per-tenant theming and configuration
07

Platform services

The unglamorous layer that keeps a live product from falling over.

  • Upstash Redis rate limiting
  • Sentry monitoring and error tracking
  • Realtime subscriptions for live updates
  • Subscriptions, payments and email
07

Engineering

What was hard
01

Triage, not filtering

The obvious build is a toxicity filter. The useful build is a ranking problem: a streamer with three hundred pending messages needs the two that matter to rise. Generating a title, a summary and an emotional intensity score for every submission turns an unreadable queue into a scannable one.

02

Widgets that survive OBS

A browser source inside streaming software is not a normal browser: constrained rendering, no user interaction, and a hard requirement never to flicker on stream. The widget system is built against those limits rather than assuming a page nobody is watching in 1080p.

03

One deployment, many brands

Tenant context is resolved in middleware from the domain and enforced by row-level security, then re-asserted by middleware wrappers on all 149 API routes. Isolation is structural — a route that forgets the tenant does not compile into the pattern.

04

Spanish product, English codebase

The product speaks Rioplatense Spanish to its users; the code is entirely English. That split is written down as a glossary — clasificados becomes listings, encuestas becomes surveys — so contributors and agents stop inventing a third dialect halfway through.

08

AI harness

7 pieces

IRLBox is driven from a 284-line operating manual that encodes the destructive-command rails, the API contract and the naming law, plus a Spec Kit pipeline for features big enough to deserve a written spec before code.

01Context

CLAUDE.md as an operating manual

Not a README. It opens with a table of database commands that must never run against production and their safe alternatives, then defines the stack, the directory map, the file-naming rules, the API middleware contract, response and cache-header standards, and a hard 150-line ceiling per component file. An agent that reads it writes code that looks like the rest of the codebase.

  • CLAUDE.md
02Guardrails

A naming law with a glossary

All identifiers in English, all user-facing copy in Spanish, and a translation table pinning the ambiguous ones — clasificados to listings, encuestas to surveys, envios to submissions. Without it every contributor invents their own half-translation and the codebase drifts into Spanglish.

  • CLAUDE.md
03Agents

Role-specific worker briefs

The documentation worker carries its own voice specification: Rioplatense Spanish, vos rather than tú, an avoid/prefer table, and a product glossary defining what a Box, a widget and an encuesta are. Documentation written by an agent reads like the product instead of like a manual.

  • .claude/workers/docs-user-guide.md
04Skills

Spec Kit for the large features

Features worth planning get the full pipeline: spec, plan, research, data model, API contracts, task breakdown and a requirements checklist, all committed. The editorial layer went through it end to end. Small changes skip it — the point is proportionality, not ceremony.

  • .specify/
  • specs/001-editorial-layer/
05Guardrails

An explicit tool allowlist

Settings enumerate exactly which commands an agent may run unattended. Everything outside the list prompts. It is the difference between an assistant that can run the test suite and one that can drop a table.

  • .claude/settings.local.json
06CI

Worktrees for parallel work

Separate git worktrees let several agent sessions work on different features at once without fighting over one checkout, each on its own branch against the same local Supabase.

  • irlbox-worktrees/
07CI

Tests as the acceptance gate

151 test files across Vitest and Playwright, plus a CI workflow. When agents write the code, the test suite is what decides whether the work is done — so the suite is the part worth being strict about.

  • tests/
  • .github/_workflows/ci.yml
09

Stack

10 entries
  • 01Next.js 16
  • 02React 19
  • 03TypeScript
  • 04Supabase
  • 05OpenAI
  • 06Remotion
  • 07Upstash Redis
  • 08Sentry
  • 09Vitest
  • 10Playwright