216 lines
5.4 KiB
Markdown
216 lines
5.4 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
git clone https://github.com/oc-xiaoju/ograph.git
|
|
cd ograph
|
|
npm install
|
|
```
|
|
|
|
UI has its own dependencies:
|
|
```bash
|
|
cd packages/engine/ui
|
|
npm install
|
|
```
|
|
|
|
## Development Workflow
|
|
|
|
### Engine (API + Core Logic)
|
|
|
|
```bash
|
|
cd packages/engine
|
|
npm run dev # Local dev server (wrangler dev)
|
|
npm test # Run tests (vitest, 105+ tests)
|
|
```
|
|
|
|
### UI (React SPA)
|
|
|
|
```bash
|
|
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:
|
|
```bash
|
|
cp packages/engine/ui/dist/index.html packages/engine/src/ui.html
|
|
```
|
|
|
|
### CLI
|
|
|
|
```bash
|
|
cd packages/cli
|
|
npm run build # TypeScript compile
|
|
npm test # Run tests (vitest, 31+ tests)
|
|
npm run dev # Watch mode
|
|
```
|
|
|
|
### Run All Tests
|
|
|
|
```bash
|
|
npm test # Runs tests across all workspaces
|
|
```
|
|
|
|
## CI/CD
|
|
|
|
**Pipeline:** `.github/workflows/ci.yml`
|
|
|
|
On every push to `main`:
|
|
1. **Test** — `npm install` → `npm test` (all workspaces)
|
|
2. **Deploy** — Build UI → copy `ui.html` → `wrangler 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:
|
|
```bash
|
|
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` suffix** — `task_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)
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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*
|