Skip to content
Own productWeb

Own SaaS · early development

Pactroom

Private project workspace with a project-aware AI

A private, multi-person workspace for each project: chat, files, tasks and decisions in one place, with an AI assistant that answers only from the project's own messages and files and cites its sources.

The problem

Project work gets scattered across chat apps, email threads and shared drives. Decisions are hard to find later, files lose their context, and action items discussed in conversation never make it onto a task list. General-purpose AI chat doesn't help much either, because it doesn't know the project and can't show where an answer came from.

What I built

I designed and built Pactroom end to end as a TypeScript monorepo. Every project gets a private room with members and invitations, real-time chat (replies, attachments, search), tasks with assignees and due dates, and file sharing. Messages and uploaded files are indexed with pgvector embeddings, so the project AI can retrieve the relevant pieces, answer with citations back to the source message or file, and suggest tasks straight from the conversation. Access control is enforced in the API, not just the UI, and the whole thing ships through a tested CI/CD pipeline.

Outcome

Pactroom is live at pactroom.app and in early development. The backend has around 175 Vitest tests, and changes ship through GitHub Actions (tests, build, deploy, database migrations and a health check). It's the project where I've gone deepest on retrieval-augmented AI, real-time systems and production operations.

Key features

  • Projects with members and invitations by email or link
  • Real-time chat with replies, attachments, search and live updates
  • Tasks with status, priority, due dates and assignees
  • Task import from CSV, Excel or pasted text
  • Direct-to-storage file uploads, indexed for the AI
  • Project AI with retrieval over messages and files
  • Cited answers that use only the project's own content
  • Task suggestions generated from chat
  • Activity timeline for every project
  • Notification emails with opt-outs, plus a weekly digest

Engineering highlights

  • Retrieval-augmented AI: messages and file contents are embedded with pgvector, the most relevant chunks are retrieved per question, and answers cite the exact message or file they came from. The assistant is restricted to the project's own content.
  • Access control lives in the API, not just the UI: project access is checked server-side, and Supabase JWTs are verified against the published JWKS (ES256) instead of being trusted from the client.
  • Real-time collaboration with Socket.IO 4, so new messages, replies and updates appear live for everyone in the room.
  • Safe file handling: the browser uploads directly to storage using signed URLs, and PDFs and spreadsheets are parsed for indexing with zip-bomb checks.
  • Abuse protection with per-user fixed-window rate limits (in memory or on Redis) and Zod validation of request input.
  • Streaming AI responses rendered with the Vercel AI SDK and Streamdown, including code blocks, maths and Mermaid diagrams.
  • Production pipeline: GitHub Actions runs the test suite and build, deploys over SSH, applies Prisma migrations and verifies a health check; a scheduled job sends the weekly digest.

Architecture

nginx sits in front of the web app and the API, which run as separate services on a Google Cloud VM. The API owns all data access and talks to managed Postgres, object storage, the LLM provider, email and Redis.

  1. Client

    • Browser
  2. Edge

    • nginx (TLS + reverse proxy)
  3. App

    • Web app: TanStack Start (SSR)
    • API: Fastify + Socket.IO
  4. Services

    • PostgreSQL + pgvector
    • Object storage
    • LLM & embeddings
    • Email
    • Redis (rate limits)
  • Auth: Supabase Auth in the browser; JWTs verified by the API via JWKS.
  • Files go straight from the browser to storage through signed URLs, and the API then indexes them for retrieval.
  • Deploys run on GitHub Actions: tests, build, SSH deploy, migrations and a health check.

Tech stack

Frontend
  • TanStack Start (React, file-based TanStack Router)
  • Vite + Nitro
  • TanStack Query
  • Tailwind CSS 4
  • Radix UI / shadcn-style components
  • lucide icons
  • React Hook Form
  • sonner toasts
  • Supabase Auth (supabase-js)
  • Vercel AI SDK + Streamdown (code, math, Mermaid)
Backend
  • Node.js 22
  • Fastify 5
  • TypeScript
  • Zod 4 validation
  • Socket.IO 4 real-time chat
  • Supabase JWT verification via JWKS (jose, ES256)
  • Per-user fixed-window rate limits (in-memory or Redis)
  • Resend email
Data & AI
  • PostgreSQL 17 on Supabase
  • Prisma 7 (adapter-pg)
  • pgvector embeddings for retrieval
  • OpenRouter LLM + embeddings
  • Supabase Storage (signed upload/download URLs)
  • unpdf + spreadsheet parsing with zip-bomb checks
Testing & DevOps
  • Vitest + Testing Library
  • ~175 backend tests
  • GitHub Actions CI/CD
  • Google Cloud VM, nginx, systemd
  • Automated Prisma migrations + health checks
  • Smoke tests and provisioning scripts