Skip to content

blueshed/typed

Repository files navigation

Typed

A real-time CQRS document system where TypeScript types are the single source of truth. Define entity shapes in one file, derive everything else — tables, CRUD functions, change triggers, WebSocket subscriptions.

Built with Bun, PostgreSQL, and zero frameworks.

How it works

domain.ts (types) --> SQL tables + functions + triggers --> WebSocket broadcasts

You define entities and their relationships as TypeScript types in domain.ts. The SQL layer is derived from those types — save_* functions handle insert/update, delete_* functions remove rows, and open_* functions compose documents as JSON. PostgreSQL triggers detect changes and broadcast via LISTEN/NOTIFY. A Bun WebSocket server picks up notifications and pushes them to subscribed clients in real time.

There is no ORM, no REST layer, no build step. The server is ~200 lines and doesn't change when the domain grows.

The domain

The system models venues that belong to organisations, with areas and sites within each venue, and bookings made by sponsor organisations. Users authenticate and act on behalf of organisations via an acts_for relationship.

Documents are composed views scoped by a key — a venue document includes its areas and sites, a booking document includes joined organisation and contact details. Clients subscribe to a document channel and receive updates whenever any participating table changes.

Document Criteria What it contains
venue venueId Venue with areas and sites
venueBookings venueId Bookings with org/contact details
orgVenues organisationId Venue list for an organisation
profile userId User profile with org memberships

Getting started

Prerequisites: Bun, Docker.

bun create blueshed/typed my-project
cd my-project
bun run db          # start PostgreSQL in Docker
bun run dev         # start the WebSocket server with --watch

Seed the database and interact via the CLI:

bun cli.ts register alice@example.com password123 "My Org"
bun cli.ts call save_venue '{"name":"My Venue","ownerId":1}'
bun cli.ts open venue 1 open_venue 1
bun cli.ts batch basic-data.jsonl

Stack

  • Runtime: Bun — server, tests, CLI
  • Database: PostgreSQL 16 — tables, functions, triggers, LISTEN/NOTIFY
  • Auth: JWT (via jose) — register, login, token refresh
  • Protocol: WebSocket — openDoc subscribes, call mutates, doc_changed pushes updates

Tests

bun test

Tests run against an isolated PostgreSQL instance on port 5433 (see compose.test.yml).

Work with Claude

This project includes Claude Code skills that automate the type-to-SQL derivation. You describe what you want — Claude writes the types, tables, functions, and triggers following the project's patterns.

/init-domain — Replace the example domain

Strip the example entities (venues, bookings, etc.) and keep only user auth. Claude will ask you to choose an auth route:

Route What you get
password Email/password register + login via WebSocket
oauth GitHub (or other provider) login via HTTP callback
both Password auth + OAuth with automatic account linking

/new-doc — Add a document

Describe a domain concept and Claude derives the full stack — types, tables, functions, and triggers. server.ts and types.ts never change.

Typical workflow

> /init-domain

  Claude asks which auth route you want, strips the example domain,
  and leaves you with a clean slate: users + auth + profile document.

> /new-doc

  Describe your domain — "I need projects with tasks, assigned to users"
  — and Claude will agree on the types in domain.ts with you, then
  derive the SQL. Run `bun run db` to apply, and it's live.

  Repeat for each document in your model.

Project structure

domain.ts           TypeScript types — the source of truth
types.ts            WebSocket message protocol
server.ts           Bun WebSocket server
cli.ts              CLI for interacting with the live system
init_db/
  000_sys.sql       Infrastructure (RPC dispatcher, safe notify)
  001_tables.sql    Domain tables
  002_functions.sql save/delete/open functions
  003_triggers.sql  Change notification triggers
basic-data.jsonl    Seed data for development

About

Type-driven CQRS document system

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors