docs: add CONTRIBUTING.md — dev workflow, CI/CD, architecture, conventions
小橘 🍊(NEKO Team)
This commit is contained in:
parent
5d2ece9f80
commit
8e0f1e3a28
215
CONTRIBUTING.md
Normal file
215
CONTRIBUTING.md
Normal file
@ -0,0 +1,215 @@
|
||||
# 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*
|
||||
Loading…
x
Reference in New Issue
Block a user