Source

Meridian Ops Board

An operations dashboard and daily AI briefing for a print and display shop: orders, CRM, to-dos, meetings and shared inboxes in one page per person. The company and its data are fictional.

  • TypeScript
  • Cloudflare Workers
  • D1
  • Python
Repository
mattrguerra/meridian-ops-board
Branch
main
Files
188 files · 40 folders
Languages
TypeScript 96% · Python 3% · SQL 1%
Visibility
Private on GitHub, published here in full

Meridian Ops Board

An operations dashboard and daily AI briefing for a small print and display shop. It pulls orders, CRM leads and tasks, EOS to-dos, a content tracker, meeting action items and the shared inboxes into one page per person, and has a language model write each person a morning briefing from the same data.

Everything about the company is fictional. Meridian Display Co., its staff, its clients, its orders and every piece of data in this repository are invented. The system itself is real: it was designed and built with AI-assisted development and ran in daily use, and this is a rebuild of it with sample data.

What it shows

  • The people board. Who is loaded and who is not, per person, across every source. A person no source covers reads "not tracked", never zero.
  • My Day. Each person's own orders, tasks, to-dos and meeting commitments, with a private task list only they can read.
  • The shared inbox. Every role mailbox in one view, with role-gated reply and send, a confirmation step and an audit record.
  • The morning briefing. A distilled payload goes to a language model, which writes a company briefing and a personal day plan for each person, tiered by role.
  • Onboarding. A training plan and an end-of-day note for a new hire, visible only to the people who should see it.
  • Data health. Which sources answered, which failed, and what nothing covers.

How it is built

A pnpm monorepo in TypeScript, with one Python script for the briefing.

Part Where
API clients for Plinth, Bitrix24, Ninety, Google Sheets, Fathom and Gmail packages/
Collect, view model and page rendering apps/dashboard/
Cloudflare Worker: cron sync, Access-verified pages, the inbox, D1 apps/worker/
Rosters, stage taxonomies, grants and other human-edited config config/
The briefing, the only place a model is called analysis/brief.py

The design rules the code follows, starting with "zero, null and broken must never look the same", are in docs/ARCHITECTURE.md.

Running it

Node 22.5 or later and pnpm 9. The D1 store tests run on node:sqlite, which older Node does not have; below 22.5 they skip with a warning rather than fail.

pnpm install
pnpm test                   # 1,168 TypeScript and 49 Python cases, offline
pnpm typecheck
pnpm dashboard --fixtures   # writes dashboard.html from sample data

CI (.github/workflows/ci.yml) runs install, typecheck and test on Node 22. Live runs need credentials in the process environment; see credentials.example.sh. There is deliberately no .env reader. The briefing (analysis/brief.py) calls a local OpenAI-compatible server at http://127.0.0.1:1234/v1 by default. Pointing ANTHROPIC_BASE_URL at the Anthropic API switches it to that API, which needs ANTHROPIC_API_KEY.

Deploying the Worker

cd apps/worker                                     # once per account
wrangler kv namespace create DASHBOARD             # and again with --preview
wrangler d1 create meridian-checkins
wrangler d1 migrations apply meridian-checkins --remote
wrangler secret put NINETY_TOKEN                   # also BITRIX_WEBHOOK_URL, PLINTH_API_KEY
wrangler deploy

Paste the printed KV and D1 ids into wrangler.jsonc. Gmail credentials are Worker secrets too (pnpm inbox:auth mints and stores a mailbox's token). Put a Cloudflare Access application in front of the workers.dev URL and its preview URLs, then set ACCESS_TEAM_DOMAIN and ACCESS_AUD in wrangler.jsonc: until both are set the Worker refuses every request. pnpm morning syncs, writes the briefings and pushes the pages to the Worker.