mattrguerra/meridian-ops-boardmainPrivate on GitHub, published here in full

README.md

Language Markdown3.6 KB79 lines

README.md

  1. # Meridian Ops Board
  2. An operations dashboard and daily AI briefing for a small print and display
  3. shop. It pulls orders, CRM leads and tasks, EOS to-dos, a content tracker,
  4. meeting action items and the shared inboxes into one page per person, and has
  5. a language model write each person a morning briefing from the same data.
  6. **Everything about the company is fictional.** Meridian Display Co., its staff,
  7. its clients, its orders and every piece of data in this repository are
  8. invented. The system itself is real: it was designed and built with
  9. AI-assisted development and ran in daily use, and this is a rebuild of it with
  10. sample data.
  11. ## What it shows
  12. - **The people board.** Who is loaded and who is not, per person, across every
  13. source. A person no source covers reads "not tracked", never zero.
  14. - **My Day.** Each person's own orders, tasks, to-dos and meeting commitments,
  15. with a private task list only they can read.
  16. - **The shared inbox.** Every role mailbox in one view, with role-gated reply
  17. and send, a confirmation step and an audit record.
  18. - **The morning briefing.** A distilled payload goes to a language model, which
  19. writes a company briefing and a personal day plan for each person, tiered by
  20. role.
  21. - **Onboarding.** A training plan and an end-of-day note for a new hire, visible
  22. only to the people who should see it.
  23. - **Data health.** Which sources answered, which failed, and what nothing covers.
  24. ## How it is built
  25. A pnpm monorepo in TypeScript, with one Python script for the briefing.
  26. | Part | Where |
  27. |---|---|
  28. | API clients for Plinth, Bitrix24, Ninety, Google Sheets, Fathom and Gmail | `packages/` |
  29. | Collect, view model and page rendering | `apps/dashboard/` |
  30. | Cloudflare Worker: cron sync, Access-verified pages, the inbox, D1 | `apps/worker/` |
  31. | Rosters, stage taxonomies, grants and other human-edited config | `config/` |
  32. | The briefing, the only place a model is called | `analysis/brief.py` |
  33. The design rules the code follows, starting with "zero, null and broken must
  34. never look the same", are in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
  35. ## Running it
  36. Node 22.5 or later and pnpm 9. The D1 store tests run on `node:sqlite`, which
  37. older Node does not have; below 22.5 they skip with a warning rather than fail.
  38. ```bash
  39. pnpm install
  40. pnpm test # 1,168 TypeScript and 49 Python cases, offline
  41. pnpm typecheck
  42. pnpm dashboard --fixtures # writes dashboard.html from sample data
  43. ```
  44. CI (`.github/workflows/ci.yml`) runs install, typecheck and test on Node 22.
  45. Live runs need credentials in the process environment; see
  46. `credentials.example.sh`. There is deliberately no `.env` reader. The
  47. briefing (`analysis/brief.py`) calls a local OpenAI-compatible server at
  48. `http://127.0.0.1:1234/v1` by default. Pointing `ANTHROPIC_BASE_URL` at the
  49. Anthropic API switches it to that API, which needs `ANTHROPIC_API_KEY`.
  50. ## Deploying the Worker
  51. ```bash
  52. cd apps/worker # once per account
  53. wrangler kv namespace create DASHBOARD # and again with --preview
  54. wrangler d1 create meridian-checkins
  55. wrangler d1 migrations apply meridian-checkins --remote
  56. wrangler secret put NINETY_TOKEN # also BITRIX_WEBHOOK_URL, PLINTH_API_KEY
  57. wrangler deploy
  58. ```
  59. Paste the printed KV and D1 ids into `wrangler.jsonc`. Gmail credentials are
  60. Worker secrets too (`pnpm inbox:auth` mints and stores a mailbox's token).
  61. Put a Cloudflare Access application in front of the `workers.dev` URL and its
  62. preview URLs, then set `ACCESS_TEAM_DOMAIN` and `ACCESS_AUD` in
  63. `wrangler.jsonc`: until both are set the Worker refuses every request.
  64. `pnpm morning` syncs, writes the briefings and pushes the pages to the Worker.