ograph/CONTRIBUTING.md

5.4 KiB

Contributing to OGraph

Project Structure

packages/
  engine/        # CF Worker — API + Engine logic + UI
    src/
      index.ts     # Hono routes + middleware
      engine.ts    # Core engine functions (CRUD, projections, reactions)
      types.ts     # TypeScript interfaces
      ui.html      # Built UI (committed, auto-generated)
    ui/            # React SPA (Vite + Tailwind + headless-ui)
      src/
        App.tsx
        api.ts
        components/
    wrangler.toml
  cli/           # CLI client (@uncaged/ograph-cli)
    src/
      client.ts    # HTTP client for OGraph API
      commands/    # CLI commands (events, projections, reactions, etc.)
  dispatcher/    # Local daemon — polls projections, notifies Agent
  board/         # (experimental) Kanban board UI

Prerequisites

  • Node.js 22+
  • npm (workspaces)
  • Cloudflare account (for deployment)
  • wrangler CLI (installed via npm)

Setup

git clone https://github.com/oc-xiaoju/ograph.git
cd ograph
npm install

UI has its own dependencies:

cd packages/engine/ui
npm install

Development Workflow

Engine (API + Core Logic)

cd packages/engine
npm run dev        # Local dev server (wrangler dev)
npm test           # Run tests (vitest, 105+ tests)

UI (React SPA)

cd packages/engine/ui
npm run dev        # Vite dev server (hot reload)
npm run build      # Build → dist/index.html (single-file)

After building UI, copy to engine:

cp packages/engine/ui/dist/index.html packages/engine/src/ui.html

CLI

cd packages/cli
npm run build      # TypeScript compile
npm test           # Run tests (vitest, 31+ tests)
npm run dev        # Watch mode

Run All Tests

npm test           # Runs tests across all workspaces

CI/CD

Pipeline: .github/workflows/ci.yml

On every push to main:

  1. Testnpm installnpm test (all workspaces)
  2. Deploy — Build UI → copy ui.htmlwrangler deploy to Cloudflare Workers

On pull requests:

  1. Test only (no deploy)

Secrets (GitHub Actions)

Secret Description
CLOUDFLARE_API_TOKEN Wrangler deploy auth
CLOUDFLARE_ACCOUNT_ID CF account

Production URL

  • API: https://ograph.shazhou.workers.dev
  • UI: https://ograph.shazhou.workers.dev/ui

Commit Conventions

Format: type(scope): description

Types: feat, fix, refactor, ci, docs, test, chore

Scopes: engine, cli, ui, dispatcher, board

Examples:

feat(engine): add incremental event query with ?after=N
fix(ui): Projection ref params now filter objects by matching type
ci: add CD — auto deploy to Cloudflare Workers on push to main

Sign commits:

小橘 🍊(NEKO Team)
小墨 🖊️(KUMA Team)

Git config:

git config user.name "小橘"
git config user.email "xiaoju@shazhou.work"

Architecture Notes

Engine (Cloudflare Worker)

  • Runtime: Cloudflare Workers (D1 database, Hono framework)
  • Auth: API Key in Authorization: Bearer ogk_xxx header
  • UI: Single HTML file served at /ui, built with Vite singlefile plugin
  • Logs: Request logs auto-cleaned (7-day retention via waitUntil)

Key Design Decisions

  • Snake_case everywhere — API, DB, event names (task_created, not taskCreated)
  • Event names: {object}_{past_participle} (e.g. task_created, comment_added)
  • Params use _id suffixtask_id, agent_id
  • Content-addressed hashing — defs are immutable versions identified by hash
  • Projection health: expression errors → errored status, returns stale value, no reaction triggered
  • Lazy computation: projections compute on query, not on event emit

UI Routing

Hash-based routing (#/events, #/reaction-logs). No react-router dependency — hand-rolled.

Pages:

Route Page
#/health Health dashboard
#/object-defs Object type definitions
#/objects Object instances
#/event-defs Event type definitions
#/events Event log
#/projection-defs Projection definitions
#/projections Query projections
#/reactions Reaction definitions
#/reaction-logs Reaction execution logs
#/request-logs API request logs
#/api-keys API key management

D1 Storage

  • Free tier: 500 MB storage, 5M reads/writes per month
  • TEXT fields: no length limit (SQLite underneath, ~1 MB per row)
  • Logs: auto-pruned after 7 days
  • Events: append-only, never deleted

Testing

Engine tests use miniflare (local D1). Tests cover:

  • CRUD for all entity types (object defs, event defs, projection defs, etc.)
  • Projection computation + incremental reduce
  • Reaction execution + handler sandboxing
  • API key auth + permissions
  • Error handling + edge cases

To add a test, edit packages/engine/src/index.test.ts.

Manual Deploy (if needed)

cd packages/engine
# Build UI first
cd ui && npm run build && cp dist/index.html ../src/ui.html && cd ..
# Deploy
npx wrangler deploy

Requires CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID env vars.

D1 Database Access

# Query production D1
npx wrangler d1 execute ograph --remote --command "SELECT COUNT(*) FROM events"

# Time Travel (point-in-time recovery)
npx wrangler d1 time-travel ograph --before <timestamp>

Built by 小橘 🍊 & 小墨 🖊️ — NEKO + KUMA Teams