Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions ordo-editor/apps/docs/en/platform/catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Fact Catalog & Concepts

The fact catalog is the project's unified description of "which fields rules can read." Studio autocomplete, contract validation, and test-case suggestions are all driven by it.

## Why a Catalog

Common pain points without one:

- Rulesets disagree on field names (`user.id` / `customer_id` / `uid`)
- Type drift (a numeric field becomes a string after one release)
- Field semantics live only in engineers' heads

The fact catalog makes these constraints **explicit**: every field has a name, type, description, and example, serving as the project's single source of truth.

## Fact

An atomic field definition.

```jsonc
// POST /api/v1/projects/:pid/facts
{
"name": "user.age",
"type": "number",
"description": "User age in years",
"example": 28,
"tags": ["user", "demographic"]
}
```

Supported types: `string` · `number` · `boolean` · `array<T>` · `object` · `concept:<name>`.

## Concept

A composite structure. When multiple rulesets need to refer to the same object (e.g. "User", "Order"), define the concept once and reference it from facts as `concept:User`.

```jsonc
// POST /api/v1/projects/:pid/concepts
{
"name": "User",
"fields": [
{ "name": "id", "type": "string" },
{ "name": "age", "type": "number" },
{ "name": "vip", "type": "boolean" }
]
}
```

## API

| Operation | Endpoint |
| -------------- | ------------------------------------------------- |
| List facts | `GET /api/v1/projects/:pid/facts` |
| Create fact | `POST /api/v1/projects/:pid/facts` |
| Update/delete | `PUT/DELETE /api/v1/projects/:pid/facts/:name` |
| List concepts | `GET /api/v1/projects/:pid/concepts` |
| Create concept | `POST /api/v1/projects/:pid/concepts` |
| Update/delete | `PUT/DELETE /api/v1/projects/:pid/concepts/:name` |

## Coupling with Contracts & Studio

- [Contracts](./contracts) constrain a ruleset's input and output by referencing facts/concepts.
- Studio expression autocomplete and type checks come from the catalog.
- Test cases use the catalog to suggest input fields — the catalog is where all "type info" for a project converges.
55 changes: 55 additions & 0 deletions ordo-editor/apps/docs/en/platform/contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Decision Contracts

A decision contract is a ruleset's "type signature": it declares which fields the rule expects to read, which result codes it must emit, and which fields each result carries.

Contracts decouple rules from callers — apps call against the contract, authors write against it, and the platform validates both ends agree before each release.

## Contract Shape

```jsonc
// POST /api/v1/projects/:pid/contracts
{
"name": "discount-check",
"version": "1.0.0",
"input": {
"fields": [
{ "name": "user.age", "type": "number", "required": true },
{ "name": "user.vip", "type": "boolean", "required": false, "default": false },
{ "name": "order.amount", "type": "number", "required": true }
]
},
"outputs": [
{ "code": "VIP", "fields": [{ "name": "discount", "type": "number" }] },
{ "code": "NORMAL", "fields": [{ "name": "discount", "type": "number" }] },
{ "code": "DENY", "fields": [{ "name": "reason", "type": "string" }] }
]
}
```

## When Validation Runs

| Trigger | Checks |
| ------------------- | -------------------------------------------------------------------------------------- |
| Studio live editing | Expressions reference fields declared in the contract `input` |
| Draft save | Each Terminal's `code` is in the contract's `outputs` list |
| Test run | Test inputs satisfy the contract's `input.required` |
| Pre-release | Contract diff against the previous release; breaking changes need higher-tier approval |

## Relationship with the Fact Catalog

The contract's `input.fields` reference names and types from the [fact catalog](./catalog). If a field's type changes in the catalog, contracts that depend on it are flagged as "needs migration."

## API

| Operation | Endpoint |
| ------------- | -------------------------------------------------- |
| List | `GET /api/v1/projects/:pid/contracts` |
| Create | `POST /api/v1/projects/:pid/contracts` |
| Update/delete | `PUT/DELETE /api/v1/projects/:pid/contracts/:name` |

## Versioning & Breaking Changes

Contracts carry a `version` field that follows SemVer:

- **patch / minor** — adding optional fields, adding `output.code`, relaxing validation: non-breaking.
- **major** — removing fields, type changes, removing output codes: breaking. Release requests will require an explicit ack.
78 changes: 78 additions & 0 deletions ordo-editor/apps/docs/en/platform/drafts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Rule Drafts

The platform never pushes ruleset edits straight to the execution cluster — they go into a **draft** first. Drafts are the foundation of Studio collaboration and the release pipeline.

## Lifecycle

```mermaid
flowchart TD
Studio["Studio (create / edit)"]
Draft["Draft"]
Trace["trace_draft<br/>ordo-server try-run"]
Reviewing["Awaiting review"]
Server["ordo-server cluster"]

Studio -- "save_draft (expected_seq optimistic lock)" --> Draft
Draft --> Trace
Draft -- "create_release_request" --> Reviewing
Reviewing -- "approve → publish" --> Server
```

## Storage Format

Drafts are stored in Studio's natural format (camelCase, `steps` array, structured `Condition` / `Expr`):

```jsonc
{
"config": { "name": "...", "version": "...", "enableTrace": true },
"startStepId": "step_a",
"steps": [
{ "id": "step_a", "type": "decision", "name": "...", "branches": [...] },
{ "id": "step_b", "type": "action", "name": "...", "assignments": [...], "nextStepId": "step_c" }
],
"subRules": { "kyc": { /* sub-rule graph */ } }
}
```

At publish time, `ordo-protocol` (a Rust crate) converts to engine format before delivery. The frontend no longer maintains adapter conversion logic.

## Optimistic Concurrency

Drafts carry a `seq` number. Concurrent edits use `expected_seq` to avoid clobbering:

```http
POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name
{ "ruleset": { ... }, "expected_seq": 42 }
```

The server returns the latest `seq` and `updated_at`. A mismatch yields `409 Conflict` so the UI can prompt for merge.

## Draft Try-Run (Trace)

```http
POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/trace
{ "ruleset": { /* draft format */ }, "input": { "user": { "age": 28 } } }
```

The platform handles Studio → engine conversion internally and returns a full trace.

## History

Each release snapshots a read-only history entry:

```http
GET /api/v1/projects/:pid/rulesets/:name/history
```

You can preview any version's diff in Studio and roll back with one click (which actually creates a new release for full audit, never a silent overwrite).

## Related API

| Operation | Endpoint |
| -------------- | ----------------------------------------------------------------- |
| List rulesets | `GET /api/v1/orgs/:oid/projects/:pid/rulesets` |
| Get/save draft | `GET/POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name` |
| Try-run | `POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/trace` |
| Publish | `POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/publish` |
| History | `GET /api/v1/projects/:pid/rulesets/:name/history` |
| Deployments | `GET /api/v1/orgs/:oid/projects/:pid/rulesets/:name/deployments` |
59 changes: 59 additions & 0 deletions ordo-editor/apps/docs/en/platform/github.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# GitHub Integration

The platform can connect projects to GitHub repositories to:

- Install rule templates from public marketplace repos in one click.
- Sync rulesets / test cases bidirectionally with code repositories (GitOps style).
- Sign in to Studio via GitHub OAuth.

## OAuth Login

```mermaid
sequenceDiagram
participant U as User
participant Studio
participant Platform as ordo-platform
participant GH as GitHub

U->>Studio: click "Sign in with GitHub"
Studio->>Platform: GET /api/v1/github/connect
Platform-->>Studio: redirect_url
Studio->>GH: redirect for authorization
GH->>Platform: GET /api/v1/github/callback?code=...
Platform->>GH: exchange code → access_token
Platform-->>Studio: set session cookie
```

## Account Linking

Existing platform accounts can link a GitHub identity:

| Operation | Endpoint |
| ---------- | ---------------------------------- |
| Status | `GET /api/v1/github/status` |
| Connect | `GET /api/v1/github/connect` |
| Callback | `GET /api/v1/github/callback` |
| Disconnect | `DELETE /api/v1/github/disconnect` |

## Marketplace

The platform curates a list of rule-template repos (and supports searching arbitrary public repos).

| Operation | Endpoint |
| --------- | ----------------------------------------------- |
| Search | `GET /api/v1/marketplace/search?q=loan` |
| Get | `GET /api/v1/marketplace/repos/:owner/:repo` |
| Install | `POST /api/v1/marketplace/install/:owner/:repo` |

Installation clones the repo content (rulesets, contracts, tests) into the current project as a fresh draft awaiting review/release — **never bypassing the approval flow**.

## Templates

Beyond Marketplace, the platform also ships built-in templates:

| Operation | Endpoint |
| --------- | --------------------------- |
| List | `GET /api/v1/templates` |
| Get | `GET /api/v1/templates/:id` |

> Pass a `template_id` when creating a project to bootstrap project + template content in one shot (see [Organizations & Projects](./organizations)).
77 changes: 77 additions & 0 deletions ordo-editor/apps/docs/en/platform/organizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Organizations & Projects

Every resource in Ordo Platform lives under a two-level hierarchy: organization → project. Organizations are the billing and governance boundary; projects aggregate rulesets, contracts, and test suites.

## Organization

- Any registered user can create organizations.
- An organization owns its members, roles, notifications, and projects.
- **Sub-organizations** allow further isolation by business line or department.
- Org-level API: `/api/v1/orgs`, `/api/v1/orgs/:id`, `/api/v1/orgs/:id/sub-orgs`.

## Members & Roles (RBAC)

Built-in roles:

| Role | Scope |
| -------- | ------------------------------------------------------------- |
| `owner` | Full org control, including member management & billing |
| `admin` | Project administration, approval, release |
| `editor` | Author drafts and create release requests, no approval rights |
| `viewer` | Read-only |

Custom roles via `POST /api/v1/orgs/:oid/roles`, with action-level granularity (e.g. `release.approve`, `ruleset.publish`).

Member management:

- `POST /api/v1/orgs/:id/members` — invite
- `PUT /api/v1/orgs/:oid/members/:uid/roles` — adjust roles
- Sub-org members: `/api/v1/orgs/:parent_id/sub-orgs/:sub_id/members`

## Project

Projects are where rulesets and contracts actually live.

- Create: `POST /api/v1/orgs/:oid/projects`
- From template: `POST /api/v1/orgs/:oid/projects/from-template` — instantiate a built-in template (e-commerce coupon, loan approval, …) in one click
- Project structure:
- **Environments** — defaults `dev` / `staging` / `prod`, customizable
- **Facts** — project-scoped typed field definitions
- **Concepts** — composite types reused across rulesets
- **Contracts** — input/output schemas
- **RuleSets** — business decision logic
- **Sub-Rule assets** — logic snippets reusable across rulesets
- **Test suites**
- **Release policies**
- **Bound server** — execution cluster

## Project API Cheatsheet

| Resource | Endpoint |
| ------------ | ---------------------------------------------- |
| Project | `/api/v1/orgs/:oid/projects/:pid` |
| Environments | `/api/v1/orgs/:oid/projects/:pid/environments` |
| Facts | `/api/v1/projects/:pid/facts` |
| Concepts | `/api/v1/projects/:pid/concepts` |
| Contracts | `/api/v1/projects/:pid/contracts` |
| RuleSets | `/api/v1/orgs/:oid/projects/:pid/rulesets` |
| Sub-rules | `/api/v1/orgs/:oid/projects/:pid/sub-rules` |
| Tests | `/api/v1/projects/:pid/rulesets/:name/tests` |
| Releases | `/api/v1/orgs/:oid/projects/:pid/releases` |
| Engine proxy | `/api/v1/engine/:project_id/*path` |

## Notifications

Each org has a notification queue covering:

- Pending release approvals
- Failed releases / canary anomalies
- Failed test suites
- Member invitations and role changes

API:

- `GET /api/v1/orgs/:oid/notifications`
- `GET /api/v1/orgs/:oid/notifications/count`
- `POST /api/v1/orgs/:oid/notifications/:nid/read`
- `POST /api/v1/orgs/:oid/notifications/read-all`
Loading
Loading