Self-hosted personal operations platform. Finance, media tracking, home inventory, and AI operations — all in one monorepo, deployed to a home server behind Cloudflare Tunnel.
SQLite is the source of truth. Claude API handles categorization and entity matching. Everything deploys via Ansible + Docker Compose.
Interfaces
iPhone (PWA) | Telegram (Moltbot) | Metabase dashboards
│
Cloudflare Tunnel + Zero Trust
│
Server (Docker Compose)
pops-shell ──── React PWA (Vite + nginx)
pops-api ────── tRPC API (Express + Drizzle ORM + SQLite)
metabase ────── Dashboards & analytics
moltbot ─────── Telegram AI assistant
paperless-ngx ─ Document archive + OCR
│
Data Layer
SQLite ─── All domains (finance, media, inventory, AI)
Claude API ─ Categorization, entity matching, NL queries
│
External APIs
Finance: Up Bank (webhooks) | ANZ/Amex/ING (CSV import)
Media: Plex (local + Discover) | TMDB | TheTVDB | Radarr | Sonarr
| Network | Services | Purpose |
|---|---|---|
pops-frontend |
cloudflared, pops-shell, pops-api, metabase | Public-facing |
pops-backend |
pops-api, moltbot, tools | Internal + SQLite access |
pops-documents |
cloudflared, paperless-ngx, paperless-redis | Isolated document processing |
| Domain | Package | What it does |
|---|---|---|
| Finance | app-finance |
Transactions, budgets, wishlists, entities, CSV import wizard with 6-stage entity matching + AI fallback, learned corrections |
| Media | app-media |
Movies & TV library, watchlist, watch history, ELO comparison arena, discovery, Plex/Radarr/Sonarr sync |
| Inventory | app-inventory |
Items, hierarchical locations, connections graph, warranties, insurance reports, Paperless-ngx document linking |
| AI Operations | app-ai |
Usage tracking, model config, rules browser, prompt viewer, cache management |
| Layer | Technology |
|---|---|
| Runtime | Node.js 24, pnpm 10 workspaces, Turborepo |
| Database | SQLite via Drizzle ORM |
| API | tRPC (type-safe end-to-end) |
| Frontend | React, Vite, React Router, Tailwind v4, shadcn/ui (47 components) |
| State | React Query (server), Zustand (client) |
| Validation | Zod |
| AI | Claude API (Haiku for categorization, entity matching) |
| Testing | Vitest (unit), Playwright (E2E), Storybook |
| Infra | Docker Compose, Ansible, Cloudflare Tunnel + Access |
| CI | GitHub Actions (lint, typecheck, format, test, E2E, security) |
See docs/roadmap.md for the full implementation tracker.
| Phase | Status |
|---|---|
| 0 — Infrastructure | Done |
| 1 — Foundation | Done |
| 2 — Core Apps (Finance, Media, Inventory, AI Ops) | In progress |
| 3 — AI Layer | Not started |
| 4 — Expansion Apps | Not started |
| 5 — Mobile & Hardware | Not started |
| 6 — Long Tail | Not started |
# Prerequisites: mise (https://mise.jdx.dev)
mise setup # Install dependencies + tools
mise db:init # Initialize SQLite database
mise db:seed # Seed with test data
mise dev # Start API + shell dev serversThe shell runs at localhost:5568, the API at localhost:3000.
See AGENTS.md for the full command reference, repo structure, data flows, and coding standards.
mise dev # All dev servers
mise test # All tests
mise typecheck # Type check all packages
mise lint # Lint all packages
mise build # Build all packagesmise db:init # Initialize empty database
mise db:seed # Seed with test data
mise db:clear # Clear all data (preserves schema)mise lint && mise typecheck # Must pass before every pushPlaywright with two modes: mocked (fast, no real DB) and integration (real SQLite via named env system). Named envs auto-skip external API calls — safe to run in CI without credentials.
cd apps/pops-shell && pnpm test:e2e./deploy.sh # Full deploy via Ansible
./deploy.sh --dry-run # Preview changes
./deploy.sh --skip-checks # Skip quality gates (faster)Requires: Ansible (brew install ansible), SSH key (configured via POPS_SSH_KEY in .env), vault password (~/.ansible/pops-vault-password). See docs/DEPLOYMENT_SETUP.md for setup.
apps/
├── pops-api/ # tRPC API (Express + Drizzle ORM + SQLite)
├── pops-shell/ # React shell (Vite + nginx)
└── moltbot/ # Telegram bot config + finance skill
packages/
├── app-finance/ # Finance domain UI
├── app-media/ # Media domain UI
├── app-inventory/ # Inventory domain UI
├── app-ai/ # AI operations UI
├── ui/ # Shared component library (shadcn-based)
├── db-types/ # Drizzle schema + TypeScript types
├── api-client/ # tRPC client setup
├── auth/ # Authentication utilities
├── navigation/ # App navigation config
├── widgets/ # Dashboard widgets
├── types/ # Cross-package type definitions
├── test-utils/ # Test helpers
└── import-tools/ # Bank import scripts (standalone)
infra/
├── ansible/ # Provisioning + deployment playbooks
└── docker-compose.yml # Production service definitions
docs/
├── roadmap.md # Implementation tracker
└── themes/ # PRDs, epics, user stories