From 91622e10d112e1ad422d93549d720f2abb6fff59 Mon Sep 17 00:00:00 2001 From: Pama-Lee Date: Sun, 26 Apr 2026 02:18:20 +0800 Subject: [PATCH] docs: add platform track covering governance, releases, studio --- ordo-editor/apps/docs/en/platform/catalog.md | 63 ++++++++++++ .../apps/docs/en/platform/contracts.md | 55 +++++++++++ ordo-editor/apps/docs/en/platform/drafts.md | 78 +++++++++++++++ ordo-editor/apps/docs/en/platform/github.md | 59 +++++++++++ .../apps/docs/en/platform/organizations.md | 77 +++++++++++++++ ordo-editor/apps/docs/en/platform/overview.md | 67 +++++++++++++ ordo-editor/apps/docs/en/platform/releases.md | 99 +++++++++++++++++++ .../apps/docs/en/platform/server-registry.md | 93 +++++++++++++++++ ordo-editor/apps/docs/en/platform/studio.md | 57 +++++++++++ .../apps/docs/en/platform/sub-rules.md | 71 +++++++++++++ ordo-editor/apps/docs/en/platform/testing.md | 63 ++++++++++++ ordo-editor/apps/docs/zh/platform/catalog.md | 63 ++++++++++++ .../apps/docs/zh/platform/contracts.md | 55 +++++++++++ ordo-editor/apps/docs/zh/platform/drafts.md | 78 +++++++++++++++ ordo-editor/apps/docs/zh/platform/github.md | 59 +++++++++++ .../apps/docs/zh/platform/organizations.md | 77 +++++++++++++++ ordo-editor/apps/docs/zh/platform/overview.md | 67 +++++++++++++ ordo-editor/apps/docs/zh/platform/releases.md | 99 +++++++++++++++++++ .../apps/docs/zh/platform/server-registry.md | 93 +++++++++++++++++ ordo-editor/apps/docs/zh/platform/studio.md | 57 +++++++++++ .../apps/docs/zh/platform/sub-rules.md | 71 +++++++++++++ ordo-editor/apps/docs/zh/platform/testing.md | 64 ++++++++++++ 22 files changed, 1565 insertions(+) create mode 100644 ordo-editor/apps/docs/en/platform/catalog.md create mode 100644 ordo-editor/apps/docs/en/platform/contracts.md create mode 100644 ordo-editor/apps/docs/en/platform/drafts.md create mode 100644 ordo-editor/apps/docs/en/platform/github.md create mode 100644 ordo-editor/apps/docs/en/platform/organizations.md create mode 100644 ordo-editor/apps/docs/en/platform/overview.md create mode 100644 ordo-editor/apps/docs/en/platform/releases.md create mode 100644 ordo-editor/apps/docs/en/platform/server-registry.md create mode 100644 ordo-editor/apps/docs/en/platform/studio.md create mode 100644 ordo-editor/apps/docs/en/platform/sub-rules.md create mode 100644 ordo-editor/apps/docs/en/platform/testing.md create mode 100644 ordo-editor/apps/docs/zh/platform/catalog.md create mode 100644 ordo-editor/apps/docs/zh/platform/contracts.md create mode 100644 ordo-editor/apps/docs/zh/platform/drafts.md create mode 100644 ordo-editor/apps/docs/zh/platform/github.md create mode 100644 ordo-editor/apps/docs/zh/platform/organizations.md create mode 100644 ordo-editor/apps/docs/zh/platform/overview.md create mode 100644 ordo-editor/apps/docs/zh/platform/releases.md create mode 100644 ordo-editor/apps/docs/zh/platform/server-registry.md create mode 100644 ordo-editor/apps/docs/zh/platform/studio.md create mode 100644 ordo-editor/apps/docs/zh/platform/sub-rules.md create mode 100644 ordo-editor/apps/docs/zh/platform/testing.md diff --git a/ordo-editor/apps/docs/en/platform/catalog.md b/ordo-editor/apps/docs/en/platform/catalog.md new file mode 100644 index 00000000..3cb45905 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/catalog.md @@ -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` · `object` · `concept:`. + +## 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. diff --git a/ordo-editor/apps/docs/en/platform/contracts.md b/ordo-editor/apps/docs/en/platform/contracts.md new file mode 100644 index 00000000..34b1eef9 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/contracts.md @@ -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. diff --git a/ordo-editor/apps/docs/en/platform/drafts.md b/ordo-editor/apps/docs/en/platform/drafts.md new file mode 100644 index 00000000..98fd8cbb --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/drafts.md @@ -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
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` | diff --git a/ordo-editor/apps/docs/en/platform/github.md b/ordo-editor/apps/docs/en/platform/github.md new file mode 100644 index 00000000..00b4e10e --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/github.md @@ -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)). diff --git a/ordo-editor/apps/docs/en/platform/organizations.md b/ordo-editor/apps/docs/en/platform/organizations.md new file mode 100644 index 00000000..d27e4e42 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/organizations.md @@ -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` diff --git a/ordo-editor/apps/docs/en/platform/overview.md b/ordo-editor/apps/docs/en/platform/overview.md new file mode 100644 index 00000000..4a5db20a --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/overview.md @@ -0,0 +1,67 @@ +# Platform Overview + +Ordo Platform is the governance and collaboration layer of Ordo's decision infrastructure. It wraps the execution engine into a team-facing product: organization modeling, contract definitions, change review, multi-environment release, test management, and audit. + +## Platform vs. Engine + +The Ordo repository ships two independently-running binaries: + +| Component | Binary | Role | +| ----------------- | --------------- | --------------------------------------------------------------------------------- | +| **ordo-platform** | `ordo-platform` | Control plane: orgs, projects, members, contracts, drafts, releases, tests, audit | +| **ordo-server** | `ordo-server` | Data plane: actually executes rules over HTTP / gRPC / UDS | +| **ordo-core** | crate (library) | Engine core: parser, bytecode VM, JIT, trace — embeddable in any Rust app | + +> The platform never executes rules. Rule delivery and execution happen on the `ordo-server` cluster; the platform only governs and coordinates. + +## Data Model + +```mermaid +flowchart LR + Org["Organization"] + Org --> SubOrg["Sub-Organization"] + Org --> Members["Members + roles"] + Org --> Roles["Roles (RBAC)"] + Org --> Notif["Notifications"] + Org --> Project["Project"] + + Project --> Envs["Environments
dev · staging · prod · custom"] + Project --> Facts["Fact Catalog"] + Project --> Concepts["Concepts"] + Project --> Contracts["Decision Contracts"] + Project --> RuleSets["RuleSets"] + Project --> SubRules["Sub-Rule Assets"] + Project --> Policies["Release Policies"] + Project --> Releases["Releases · review · canary · rollback"] + Project --> Server["Bound execution cluster"] + + RuleSets --> Drafts["Drafts"] + RuleSets --> History["History"] + RuleSets --> Tests["Test suites"] + RuleSets --> Deployments["Deployments"] +``` + +## Core Workflow + +1. **Model** — define the fact catalog → register concepts → write typed decision contracts. +2. **Author** — write rulesets in Studio against the contract; drop in Sub-Rule assets to reuse logic. +3. **Test** — attach test cases to the ruleset (YAML format, ordo-cli compatible); run on save. +4. **Review** — open a release request → tests + diff run automatically → policy decides reviewers → approval. +5. **Release** — platform syncs rules to the target environment's ordo-servers; canary / pause / rollback are first-class. +6. **Execute** — apps connect directly to ordo-server (or via the platform `/api/v1/engine/:project_id/*path` proxy) for millisecond-level rule eval. +7. **Audit** — every action (draft edit, approval, release, rollback) lands in the audit log. + +## Deployment Shapes + +- **All-in-one** — single host, platform plus one local ordo-server. Good for small teams or evaluation. +- **Multi-region** — central platform plus regional ordo-server clusters (NA, EU, APAC, …) with [server registry](./server-registry) and execution proxy. +- **Embedded** — skip platform & server, embed `ordo-core` directly in a Rust app for ultra-low-latency inline use. + +## Next + +- [Organizations & Projects](./organizations) — team modeling and RBAC +- [Fact Catalog](./catalog) — typed inputs and shared concepts +- [Decision Contracts](./contracts) — input/output constraints +- [Studio Editor](./studio) — three modes, real-time sync +- [Release Pipeline](./releases) — draft → review → canary → rollback +- [Test Management](./testing) — cases, suites, CI integration diff --git a/ordo-editor/apps/docs/en/platform/releases.md b/ordo-editor/apps/docs/en/platform/releases.md new file mode 100644 index 00000000..c98ec528 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/releases.md @@ -0,0 +1,99 @@ +# Release Pipeline + +The release pipeline ties drafts, approvals, environments, and rollback together. Every action that pushes rules to a production ordo-server goes through it. + +## Flow Overview + +```mermaid +stateDiagram-v2 + [*] --> Pending: create_release_request + Pending --> AwaitingReview: policy evaluation + AwaitingReview --> Approved: approve + AwaitingReview --> Rejected: reject + Approved --> Executing: execute + Executing --> Executing: canary / pause / resume + Executing --> Released: done + Executing --> Failed: failed + Released --> RolledBack: rollback + Released --> [*] + Rejected --> [*] + Failed --> [*] + RolledBack --> [*] +``` + +## Release Request + +```http +POST /api/v1/orgs/:oid/projects/:pid/releases +{ + "rulesets": [ + { "name": "discount-check", "from_seq": 17 } + ], + "environments": ["staging", "prod"], + "title": "v1.4 — add VIP tiering", + "description": "..." +} +``` + +The platform will: + +1. Run any test suites attached to the ruleset — failures block creation. +2. Generate a [diff](https://github.com/Ordo-Engine/Ordo) against the current active version in each target environment (step add/remove, branch deltas, contract diff). +3. Evaluate [release policies](#release-policy) to determine required reviewers. + +## Release Policy + +A project can define multiple policies, matched by priority: + +```jsonc +{ + "name": "prod-strict", + "match": { "environments": ["prod"] }, + "approvers": { + "min_count": 2, + "roles": ["admin"], + "exclude_authors": true + }, + "auto_run_tests": true, + "freeze_window": { "cron": "0 0 * * 5-6", "duration": "48h" } +} +``` + +API: `/api/v1/orgs/:oid/projects/:pid/release-policies`. + +## Approvals + +- `POST .../releases/:rid/approve` — approve +- `POST .../releases/:rid/reject` — reject (with reason) +- `GET /api/v1/orgs/:oid/releases/pending-for-me` — list pending for me + +## Execution & Canary + +```http +POST .../releases/:rid/execute +``` + +On execute, the platform syncs rules to the target ordo-server cluster. Canary is first-class: + +| Operation | Endpoint | +| ---------------- | ----------------------------------------------------- | +| Pause | `POST .../releases/:rid/pause` | +| Resume | `POST .../releases/:rid/resume` | +| Rollback | `POST .../releases/:rid/rollback` | +| Current snapshot | `GET .../releases/:rid/execution` | +| History | `GET .../releases/:rid/history` | +| Event stream | `GET .../releases/:rid/executions/:eid/events` (SSE) | + +Per-environment canary config: `PUT /api/v1/orgs/:oid/projects/:pid/environments/:eid/canary`. + +## Rollback + +Any released release can be rolled back in one click: the platform finds the last stable version from history and **creates a new** rollback release that is auto-approved (preserving the audit trail) — never a silent overwrite. + +## Preview + +```http +POST .../releases/preview +``` + +See diffs and policy evaluation without creating a release — handy for a final pre-release check. diff --git a/ordo-editor/apps/docs/en/platform/server-registry.md b/ordo-editor/apps/docs/en/platform/server-registry.md new file mode 100644 index 00000000..dd1ceba5 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/server-registry.md @@ -0,0 +1,93 @@ +# Server Registry & Multi-Region + +Platform and execution nodes are loosely coupled — `ordo-server` instances **register themselves** with the platform on startup, and the platform maintains a directory used for release delivery and proxy routing. + +## Registration Flow + +```mermaid +sequenceDiagram + participant Server as ordo-server + participant Platform as ordo-platform + + Server->>Platform: POST /api/v1/internal/register
{region, capabilities, version} + Platform-->>Server: server_id + token + loop every N seconds + Server->>Platform: POST /api/v1/internal/heartbeat
{metrics, healthy} + end +``` + +> `/api/v1/internal/*` are machine-to-machine endpoints authenticated by server tokens — never exposed to browsers or SDKs. + +## Server Directory + +| Operation | Endpoint | +| ---------- | --------------------------------- | +| List | `GET /api/v1/servers` | +| Get | `GET /api/v1/servers/:id` | +| Health | `GET /api/v1/servers/:id/health` | +| Metrics | `GET /api/v1/servers/:id/metrics` | +| Deregister | `DELETE /api/v1/servers/:id` | + +Server record fields: + +- `region` — deployment region tag +- `capabilities` — enabled features (e.g. `jit`, `signature`) +- `healthy` / `last_heartbeat` +- `current_rulesets` — ruleset digests held now + +## Project Binding + +Each project binds one or more servers (optionally per-environment). The binding controls: + +1. Which ordo-servers receive a release. +2. Where business requests are routed when going through the platform proxy. + +```http +PUT /api/v1/orgs/:oid/projects/:pid/server +{ "environment": "prod", "server_ids": ["s_eu", "s_us"] } +``` + +## Execution Proxy + +Apps may not be able to reach regional ordo-servers directly. The platform offers a transparent proxy: + +```http +POST /api/v1/engine/:project_id/execute +``` + +Requests are routed to the ordo-server bound for the project's current environment, preserving original latency metrics (the platform forwards but does not parse). + +When to use it: + +- Apps can only reach the public platform domain. +- Multi-region failover — health-aware routing falls back to a backup server. +- Canary traffic split — during canary releases, the platform splits traffic by ratio between old and new servers. + +## Multi-Region Example + +```mermaid +flowchart LR + subgraph Central["Central Governance"] + P[ordo-platform] + DB[(Postgres)] + P --- DB + end + subgraph NorthAmerica + S1[ordo-server US-East] + S2[ordo-server US-West] + end + subgraph Europe + S3[ordo-server EU-West] + end + subgraph Asia + S4[ordo-server AP-East] + end + + S1 -- register/heartbeat --> P + S2 -- register/heartbeat --> P + S3 -- register/heartbeat --> P + S4 -- register/heartbeat --> P + + Biz["Business app"] -- direct or via platform proxy --> S1 + Biz -- direct or via platform proxy --> S3 +``` diff --git a/ordo-editor/apps/docs/en/platform/studio.md b/ordo-editor/apps/docs/en/platform/studio.md new file mode 100644 index 00000000..755fdb5c --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/studio.md @@ -0,0 +1,57 @@ +# Studio Editor + +Studio is Ordo Platform's visual editor — a browser-native app. It offers three equivalent views over the same ruleset, kept in sync in real time. + +## Three Authoring Modes + +### Flow + +- Blueprint-style canvas built on Vue Flow. +- Node types: **Decision** (branching), **Action** (assignments + external calls), **Terminal** (output), **SubRule** (sub-rule call). +- Pin shapes: triangles for execution flow, circles for data flow. +- Multi-incoming: multiple upstream nodes can land on the same target input pin; duplicates are auto-deduped. +- Compatible target pins highlight while dragging; trace replay colorizes nodes. + +### Form + +- Tree-shaped editor for users uncomfortable with flow-graph thinking. +- Each step is its own card; sub-rules and decision branches nest naturally. + +### JSON + +- Direct edit of the RuleSet JSON. +- Schema validation and expression highlighting built in. +- Useful for Git/CI imports or bulk find-and-replace. + +> All three modes synchronize through a shared [editor-store](/en/guide/editor-store) (Pinia / framework-agnostic). Any change is reflected in the other views immediately and pushed onto the undo stack. + +## Trace Panel + +Before releasing, paste a JSON context into Studio and click "Try run" → the platform calls ordo-server's trace API → for each step you get: + +- Input/output snapshots +- Which branch matched +- Expression evaluation steps +- Sub-rule call stack +- Total + per-step timing + +Trace results overlay each flow node via [ExecutionAnnotation](https://github.com/Ordo-Engine/Ordo) tooltips. + +## Test Integration + +Each test case can be edited, run individually, or run as a batch — all from inside Studio. Color-coded results: + +- Green: actual matches expected +- Red: mismatch, with an inline diff +- Gray: not run yet + +See [Test Management](./testing). + +## Templates & Sub-Rules + +- **Templates** — clone a complete project (rules + contracts + facts + tests) from Marketplace or the built-in template library in one click. +- **Sub-Rule assets** — extract common snippets (KYC, risk scoring) at the project level and reuse them across rulesets; updating once propagates everywhere. + +## i18n + +Studio and the docs are fully translated into English, Simplified Chinese, and Traditional Chinese. Switch language from the top-right corner. diff --git a/ordo-editor/apps/docs/en/platform/sub-rules.md b/ordo-editor/apps/docs/en/platform/sub-rules.md new file mode 100644 index 00000000..5eda384b --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/sub-rules.md @@ -0,0 +1,71 @@ +# Sub-Rule Assets + +Sub-rules let you extract reusable logic snippets as project-scoped or org-scoped assets. Multiple rulesets can call the same asset through a `SubRule` step. + +## Use Cases + +- **KYC verification** — different business lines (loans, credit cards, insurance) all need the same identity check. +- **Risk scoring** — a customer-risk algorithm reused by many decisions. +- **Blacklist check** — every user-facing ruleset starts with this. + +## Data Model + +```jsonc +// POST /api/v1/orgs/:oid/projects/:pid/sub-rules +{ + "name": "kyc-check", + "version": "1.2.0", + "graph": { + "startStepId": "verify", + "steps": [ + { "id": "verify", "type": "decision", "branches": [...] }, + { "id": "pass", "type": "terminal", "code": "OK" }, + { "id": "fail", "type": "terminal", "code": "REJECT" } + ] + }, + "bindings": [ + { "name": "id_number", "type": "string", "required": true } + ], + "outputs": [ + { "name": "score", "type": "number" } + ] +} +``` + +- `bindings` — parameters the caller must pass. +- `outputs` — fields written back to the parent context after the sub-rule ends. + +## Reference From a Ruleset + +In Studio, drop a `SubRule` node, pick a ref name and version, and configure binding expressions and output mapping: + +```jsonc +{ + "id": "step_kyc", + "type": "sub_rule", + "refName": "kyc-check", + "bindings": [{ "name": "id_number", "value": { "type": "variable", "path": "$.user.idn" } }], + "outputs": [{ "name": "score", "to": "kyc_score" }], + "nextStepId": "step_decide" +} +``` + +## Inline Snapshot at Publish + +When a ruleset is published, the platform **deep-inlines** every referenced sub-rule's current version (BFS resolution) into a self-contained flat RuleSet before delivering it to ordo-server: + +- Later edits or deletions of the sub-rule do not affect already-published rulesets. +- Engine execution needs zero extra lookups — no overhead. +- Default call depth limit is 10 (preventing recursion); the platform also runs DFS cycle detection. + +## Versioning & Diff + +Each sub-rule update creates a new version snapshot: + +| Operation | Endpoint | +| ---------- | --------------------------------------------------------- | +| List | `GET /api/v1/orgs/:oid/projects/:pid/sub-rules` | +| Get/update | `GET/PUT /api/v1/orgs/:oid/projects/:pid/sub-rules/:name` | +| Org-level | `/api/v1/orgs/:oid/sub-rules` (cross-project sharing) | + +After updating a sub-rule, the platform lists **every ruleset that references it** — those rulesets need to be republished to pick up the new logic. diff --git a/ordo-editor/apps/docs/en/platform/testing.md b/ordo-editor/apps/docs/en/platform/testing.md new file mode 100644 index 00000000..f9c652f5 --- /dev/null +++ b/ordo-editor/apps/docs/en/platform/testing.md @@ -0,0 +1,63 @@ +# Test Management + +The platform gives every ruleset its own test suite — same YAML format as ordo-cli, with a single source of truth across Studio, CLI, and CI. + +## Case Structure + +```yaml +ruleset: discount-check +cases: + - name: vip user gets 20% discount + input: + user: { id: u1, vip: true, age: 28 } + order: { amount: 200 } + expect: + code: VIP + output: { discount: 0.2 } + + - name: minors are denied + input: + user: { id: u2, vip: false, age: 16 } + order: { amount: 50 } + expect: + code: DENY + output: { reason: 'underage' } +``` + +## API + +| Operation | Endpoint | +| ---------------- | ------------------------------------------------------------ | +| List | `GET /api/v1/projects/:pid/rulesets/:name/tests` | +| Create/update | `POST/PUT /api/v1/projects/:pid/rulesets/:name/tests[/:tid]` | +| Run one | `POST /api/v1/projects/:pid/rulesets/:name/tests/:tid/run` | +| Run all | `POST /api/v1/projects/:pid/rulesets/:name/tests/run` | +| Project-wide run | `POST /api/v1/projects/:pid/tests/run` | +| Export YAML | `GET /api/v1/projects/:pid/rulesets/:name/tests/export` | + +## Coupling with Releases + +When a [release request](./releases) is created, the platform automatically runs all test cases for the affected rulesets. **Any failure blocks creation of the release request.** + +You can disable `auto_run_tests` in a release policy to skip this gate, but production usually shouldn't. + +## CI Integration + +- Export YAML from the platform and commit it to your code repository. +- Run via ordo-cli during PR checks: + +```bash +ordo test --rules ./rulesets --tests ./tests --reporter junit > junit.xml +``` + +Output formats: JUnit XML, JSON, TAP — all directly consumable by GitHub Actions / GitLab CI. + +## Trace & Failure Diagnosis + +When a test fails, the platform returns the full execution trace. Click the result in Studio to see: + +- Expected vs actual output code +- The last branch that matched before the divergence +- Each action node's assignment trail + +See [Studio Editor — Trace Panel](./studio#trace-panel). diff --git a/ordo-editor/apps/docs/zh/platform/catalog.md b/ordo-editor/apps/docs/zh/platform/catalog.md new file mode 100644 index 00000000..5d4a25eb --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/catalog.md @@ -0,0 +1,63 @@ +# 事实目录与概念 + +事实目录(Fact Catalog)是项目对「规则可以读到哪些字段」的统一描述。Studio 编辑器、契约校验、测试用例的智能提示都基于它工作。 + +## 为什么需要目录 + +业务规则常见痛点: + +- 不同规则集对同一字段命名不一致(`user.id` / `customer_id` / `uid`) +- 类型漂移(曾经是数字的字段在某次发布后变成字符串) +- 字段含义只存在于工程师脑里 + +事实目录把这些约束**显式化**:每个字段都有名称、类型、描述、示例值,作为项目级 single source of truth。 + +## 事实(Fact) + +一个事实是一个原子字段定义。 + +```jsonc +// POST /api/v1/projects/:pid/facts +{ + "name": "user.age", + "type": "number", + "description": "用户年龄(周岁)", + "example": 28, + "tags": ["user", "demographic"] +} +``` + +支持的类型:`string` · `number` · `boolean` · `array` · `object` · `concept:`。 + +## 概念(Concept) + +复合结构。当多个规则集都需要引用同一个对象(比如「用户」「订单」),用概念定义一次,事实目录里通过 `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 + +| 操作 | 端点 | +| --------- | ------------------------------------------------- | +| 列出事实 | `GET /api/v1/projects/:pid/facts` | +| 创建事实 | `POST /api/v1/projects/:pid/facts` | +| 更新/删除 | `PUT/DELETE /api/v1/projects/:pid/facts/:name` | +| 列出概念 | `GET /api/v1/projects/:pid/concepts` | +| 创建概念 | `POST /api/v1/projects/:pid/concepts` | +| 更新/删除 | `PUT/DELETE /api/v1/projects/:pid/concepts/:name` | + +## 与契约、Studio 的协作 + +- **契约**([决策契约](./contracts))通过事实/概念约束 RuleSet 的输入与输出。 +- **Studio** 编写表达式时下拉提示 / 类型校验都来自目录。 +- **测试用例** 的输入字段提示也来自目录——Catalog 是项目所有「类型信息」的汇聚点。 diff --git a/ordo-editor/apps/docs/zh/platform/contracts.md b/ordo-editor/apps/docs/zh/platform/contracts.md new file mode 100644 index 00000000..0f5a180d --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/contracts.md @@ -0,0 +1,55 @@ +# 决策契约 + +决策契约(Decision Contract)是规则集的「类型签名」:声明这个规则期望读哪些字段、必定输出哪些结果代码、每个结果带什么字段。 + +契约让规则与调用方解耦——业务方按契约调用,规则作者按契约编写,发布前平台校验两端一致。 + +## 契约结构 + +```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" }] } + ] +} +``` + +## 校验时机 + +| 时机 | 校验内容 | +| ------------------- | ------------------------------------------------------------- | +| Studio 编辑实时反馈 | 表达式引用的字段是否在契约的 `input` 中 | +| 草稿保存 | RuleSet 的 Terminal 步骤的 `code` 是否在契约 `outputs` 列表中 | +| 测试运行 | 测试用例输入是否符合契约 `input.required` | +| 发布前 | 与契约 diff,破坏性变更需高级别审批 | + +## 与事实目录的关系 + +契约的 `input.fields` 引用 [事实目录](./catalog) 中的字段名与类型。改了目录中字段的类型,依赖该字段的契约会被标记为"待迁移"。 + +## API + +| 操作 | 端点 | +| --------- | -------------------------------------------------- | +| 列出契约 | `GET /api/v1/projects/:pid/contracts` | +| 创建契约 | `POST /api/v1/projects/:pid/contracts` | +| 更新/删除 | `PUT/DELETE /api/v1/projects/:pid/contracts/:name` | + +## 版本与破坏性变更 + +契约本身有 `version` 字段,遵循 SemVer: + +- **patch / minor**:新增可选字段、新增 `output.code`、放宽校验——非破坏。 +- **major**:删除字段、改类型、删除 output code——破坏性,发布请求会要求显式 ack。 diff --git a/ordo-editor/apps/docs/zh/platform/drafts.md b/ordo-editor/apps/docs/zh/platform/drafts.md new file mode 100644 index 00000000..e9010c54 --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/drafts.md @@ -0,0 +1,78 @@ +# 规则草稿 + +平台对规则集的修改不会立即下发到执行集群,而是先写入一份**草稿**(draft)。草稿是 Studio 协同与发布流程的基础。 + +## 生命周期 + +```mermaid +flowchart TD + Studio["Studio (新建 / 编辑)"] + Draft["Draft 草稿"] + Trace["trace_draft
ordo-server 试运行"] + Reviewing["Reviewing 审批中"] + Server["ordo-server 集群"] + + Studio -- "save_draft (expected_seq 乐观锁)" --> Draft + Draft --> Trace + Draft -- "create_release_request" --> Reviewing + Reviewing -- "approve → publish" --> Server +``` + +## 数据形态 + +草稿在 DB 中以 Studio 自然格式(camelCase、`steps` 数组、结构化 `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 */ } } +} +``` + +发布时由 `ordo-protocol`(Rust crate)转换为引擎格式后再下发。前端不再需要维护 adapter 转换逻辑。 + +## 乐观并发控制 + +草稿带 `seq` 序列号,多人协作时通过 `expected_seq` 提交避免覆盖: + +```http +POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name +{ "ruleset": { ... }, "expected_seq": 42 } +``` + +服务器返回最新 `seq` 与 `updated_at`。版本不匹配会返回 `409 Conflict`,前端提示用户合并。 + +## 草稿试运行(Trace) + +```http +POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/trace +{ "ruleset": { /* 草稿格式 */ }, "input": { "user": { "age": 28 } } } +``` + +平台内部完成 Studio → 引擎格式转换,调用 ordo-server,返回完整 trace。 + +## 历史版本 + +每次发布都会快照一份只读历史: + +```http +GET /api/v1/projects/:pid/rulesets/:name/history +``` + +可在 Studio 中预览任意历史版本的 diff,并一键回滚(实际通过新建发布请求实现,保留审计链)。 + +## 相关 API + +| 操作 | 端点 | +| --------- | ----------------------------------------------------------------- | +| 列规则集 | `GET /api/v1/orgs/:oid/projects/:pid/rulesets` | +| 取/存草稿 | `GET/POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name` | +| 试运行 | `POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/trace` | +| 发布 | `POST /api/v1/orgs/:oid/projects/:pid/rulesets/:name/publish` | +| 历史版本 | `GET /api/v1/projects/:pid/rulesets/:name/history` | +| 部署记录 | `GET /api/v1/orgs/:oid/projects/:pid/rulesets/:name/deployments` | diff --git a/ordo-editor/apps/docs/zh/platform/github.md b/ordo-editor/apps/docs/zh/platform/github.md new file mode 100644 index 00000000..d475b892 --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/github.md @@ -0,0 +1,59 @@ +# GitHub 集成 + +平台支持把项目与 GitHub 仓库连接,用于: + +- 从公开 marketplace 仓库一键安装规则模板。 +- 把规则集 / 测试用例双向同步到代码仓库(GitOps 风格)。 +- 用 GitHub OAuth 登录 Studio。 + +## OAuth 登录 + +```mermaid +sequenceDiagram + participant U as 用户 + participant Studio + participant Platform as ordo-platform + participant GH as GitHub + + U->>Studio: 点击"用 GitHub 登录" + Studio->>Platform: GET /api/v1/github/connect + Platform-->>Studio: redirect_url + Studio->>GH: 跳转授权 + GH->>Platform: GET /api/v1/github/callback?code=... + Platform->>GH: exchange code → access_token + Platform-->>Studio: set session cookie +``` + +## 账户连接 + +已有平台账户可绑定 GitHub: + +| 操作 | 端点 | +| ---- | ---------------------------------- | +| 状态 | `GET /api/v1/github/status` | +| 连接 | `GET /api/v1/github/connect` | +| 回调 | `GET /api/v1/github/callback` | +| 解绑 | `DELETE /api/v1/github/disconnect` | + +## Marketplace + +平台维护一份精选的规则模板仓库列表(也支持搜索任意公开仓库)。 + +| 操作 | 端点 | +| ---- | ----------------------------------------------- | +| 搜索 | `GET /api/v1/marketplace/search?q=loan` | +| 详情 | `GET /api/v1/marketplace/repos/:owner/:repo` | +| 安装 | `POST /api/v1/marketplace/install/:owner/:repo` | + +安装流程会克隆仓库内容(规则集、契约、测试用例)到当前项目,作为新草稿等待审批发布——**不会绕过审批流程**。 + +## 模板入口 + +除了从 Marketplace 安装,平台也内置了一份本地模板: + +| 操作 | 端点 | +| ---- | --------------------------- | +| 列出 | `GET /api/v1/templates` | +| 详情 | `GET /api/v1/templates/:id` | + +> 创建项目时直接传 `template_id`,可一键完成项目 + 模板内容的初始化(参见 [组织与项目](./organizations))。 diff --git a/ordo-editor/apps/docs/zh/platform/organizations.md b/ordo-editor/apps/docs/zh/platform/organizations.md new file mode 100644 index 00000000..bfa3a07f --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/organizations.md @@ -0,0 +1,77 @@ +# 组织与项目 + +Ordo Platform 的所有资源都挂在「组织 → 项目」两层结构下。组织是计费与治理边界,项目是规则、契约、测试套件的聚合点。 + +## 组织(Organization) + +- 用户注册后可创建任意数量的组织。 +- 组织拥有独立的成员列表、角色定义、通知与项目。 +- 支持 **子组织**(sub-organization),用于按业务线/部门进一步隔离。 +- 组织级 API:`/api/v1/orgs`、`/api/v1/orgs/:id`、`/api/v1/orgs/:id/sub-orgs`。 + +## 成员与角色(RBAC) + +平台内置一套 RBAC,支持自定义角色: + +| 内置角色 | 权限范围 | +| -------- | -------------------------------- | +| `owner` | 组织全部权限,包括成员管理与计费 | +| `admin` | 项目级管理、审批、发布 | +| `editor` | 草稿创作与发起发布,无审批权 | +| `viewer` | 只读 | + +自定义角色:`POST /api/v1/orgs/:oid/roles`,可精细到 `release.approve`、`ruleset.publish` 等动作粒度。 + +成员管理: + +- `POST /api/v1/orgs/:id/members` —— 邀请成员 +- `PUT /api/v1/orgs/:oid/members/:uid/roles` —— 调整角色 +- 子组织成员:`/api/v1/orgs/:parent_id/sub-orgs/:sub_id/members` + +## 项目(Project) + +项目是真正持有规则集与契约的容器。 + +- 创建:`POST /api/v1/orgs/:oid/projects` +- 模板创建:`POST /api/v1/orgs/:oid/projects/from-template` —— 从内置模板(电商优惠券、贷款审批等)一键实例化 +- 项目结构: + - **环境**(environments):默认 `dev` / `staging` / `prod`,可自定义 + - **事实目录**(facts):项目级类型化字段定义 + - **概念**(concepts):跨规则集复用的复合类型 + - **契约**(contracts):输入/输出 Schema + - **规则集**(rulesets):业务决策逻辑 + - **子规则资产**(sub-rules):跨规则集复用的逻辑片段 + - **测试套件**(tests) + - **发布策略**(release policies) + - **绑定的服务器**(server):执行集群 + +## 项目级 API 速查 + +| 资源 | 端点 | +| -------- | ---------------------------------------------- | +| 项目 | `/api/v1/orgs/:oid/projects/:pid` | +| 环境 | `/api/v1/orgs/:oid/projects/:pid/environments` | +| 事实 | `/api/v1/projects/:pid/facts` | +| 概念 | `/api/v1/projects/:pid/concepts` | +| 契约 | `/api/v1/projects/:pid/contracts` | +| 规则集 | `/api/v1/orgs/:oid/projects/:pid/rulesets` | +| 子规则 | `/api/v1/orgs/:oid/projects/:pid/sub-rules` | +| 测试套件 | `/api/v1/projects/:pid/rulesets/:name/tests` | +| 发布请求 | `/api/v1/orgs/:oid/projects/:pid/releases` | +| 引擎代理 | `/api/v1/engine/:project_id/*path` | + +## 通知 + +每个组织都有自己的通知队列,覆盖: + +- 待审批的发布请求 +- 发布失败 / 灰度异常 +- 测试套件失败 +- 成员邀请与权限变更 + +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` diff --git a/ordo-editor/apps/docs/zh/platform/overview.md b/ordo-editor/apps/docs/zh/platform/overview.md new file mode 100644 index 00000000..a03106ca --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/overview.md @@ -0,0 +1,67 @@ +# 平台概览 + +Ordo Platform 是 Ordo 决策基础设施的治理与协作层。它把执行引擎包装成一个面向团队的产品:组织建模、契约定义、变更审批、多环境发布、测试管理与审计。 + +## 平台 vs 引擎 + +Ordo 仓库内同时维护两套独立运行的二进制: + +| 组件 | 二进制 | 作用 | +| ----------------- | --------------- | -------------------------------------------------------------- | +| **ordo-platform** | `ordo-platform` | 治理面:组织/项目/成员、契约、草稿、审批、发布、测试套件、审计 | +| **ordo-server** | `ordo-server` | 数据面:实际执行规则(HTTP / gRPC / UDS) | +| **ordo-core** | crate(库) | 引擎核心:解析、字节码、JIT、追踪——可嵌入任意 Rust 应用 | + +> 平台不会执行规则。规则的下发与执行都在 `ordo-server` 集群完成,平台只负责治理与协调。 + +## 数据模型 + +```mermaid +flowchart LR + Org["Organization 组织"] + Org --> SubOrg["Sub-Organization 子组织"] + Org --> Members["Members 用户 + 角色"] + Org --> Roles["Roles RBAC 自定义角色"] + Org --> Notif["Notifications"] + Org --> Project["Project 项目"] + + Project --> Envs["Environments
dev · staging · prod · 自定义"] + Project --> Facts["Fact Catalog 事实目录"] + Project --> Concepts["Concepts 复用类型"] + Project --> Contracts["Decision Contracts 契约"] + Project --> RuleSets["RuleSets 规则集"] + Project --> SubRules["Sub-Rule Assets 子规则资产"] + Project --> Policies["Release Policies 发布策略"] + Project --> Releases["Releases 发布 / 审批 / 灰度 / 回滚"] + Project --> Server["Server 绑定的执行集群"] + + RuleSets --> Drafts["Drafts 草稿"] + RuleSets --> History["History 历史版本"] + RuleSets --> Tests["Tests 测试套件"] + RuleSets --> Deployments["Deployments 部署记录"] +``` + +## 核心流程 + +1. **建模**:在项目中定义事实目录 → 注册概念 → 编写带类型的决策契约。 +2. **创作**:在 Studio 编辑器里基于契约编写规则集,可拖入 Sub-Rule 资产复用逻辑。 +3. **测试**:为规则集挂载测试用例(YAML 格式,与 ordo-cli 兼容),保存时即可一键运行。 +4. **审批**:发起发布请求 → 自动跑测试 + 生成 diff → 触发审批策略 → 审批人通过。 +5. **发布**:平台向目标环境对应的 ordo-server 同步规则;支持灰度、暂停、回滚。 +6. **执行**:业务系统直连 ordo-server(或经平台 `/api/v1/engine/:project_id/*path` 代理)执行规则,毫秒级响应。 +7. **审计**:所有动作(草稿编辑、审批、发布、回滚)写入审计日志。 + +## 部署形态 + +- **All-in-one**:单机部署,平台 + 一个本地 ordo-server,适合小团队或评估。 +- **多区域**:中央平台 + 多个区域的 ordo-server 集群(北美、欧洲、亚洲等),通过 [服务器注册](./server-registry) 与执行代理统一调度。 +- **嵌入式**:跳过平台与服务器,直接在 Rust 应用中使用 `ordo-core`,适合超低延迟内联场景。 + +## 下一步 + +- [组织与项目](./organizations) — 团队建模与 RBAC +- [事实目录](./catalog) — 类型化输入与共享概念 +- [决策契约](./contracts) — 规则的输入/输出约束 +- [Studio 编辑器](./studio) — 三种模式与协同 +- [发布流程](./releases) — 草稿 → 审批 → 灰度 → 回滚 +- [测试管理](./testing) — 用例、套件、CI 集成 diff --git a/ordo-editor/apps/docs/zh/platform/releases.md b/ordo-editor/apps/docs/zh/platform/releases.md new file mode 100644 index 00000000..896682e7 --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/releases.md @@ -0,0 +1,99 @@ +# 发布流程 + +发布流程串联草稿、审批、环境与回滚。所有把规则下发到生产 ordo-server 的动作都必须经过这条流水线。 + +## 流程总览 + +```mermaid +stateDiagram-v2 + [*] --> Pending: create_release_request + Pending --> AwaitingReview: 策略评估 + AwaitingReview --> Approved: approve + AwaitingReview --> Rejected: reject + Approved --> Executing: execute + Executing --> Executing: canary / pause / resume + Executing --> Released: done + Executing --> Failed: failed + Released --> RolledBack: rollback + Released --> [*] + Rejected --> [*] + Failed --> [*] + RolledBack --> [*] +``` + +## 发布请求(Release Request) + +```http +POST /api/v1/orgs/:oid/projects/:pid/releases +{ + "rulesets": [ + { "name": "discount-check", "from_seq": 17 } + ], + "environments": ["staging", "prod"], + "title": "v1.4 — 增加 VIP 阶梯", + "description": "..." +} +``` + +平台会: + +1. 自动跑挂在 ruleset 上的测试套件——失败则阻断创建。 +2. 生成与目标环境当前活跃版本的 [diff](https://github.com/Ordo-Engine/Ordo)(步骤增删、分支变化、契约对比)。 +3. 评估 [发布策略](#发布策略) 决定需要的审批人。 + +## 审批策略(Release Policy) + +每个项目可定义多条策略,按优先级匹配: + +```jsonc +{ + "name": "prod-strict", + "match": { "environments": ["prod"] }, + "approvers": { + "min_count": 2, + "roles": ["admin"], + "exclude_authors": true + }, + "auto_run_tests": true, + "freeze_window": { "cron": "0 0 * * 5-6", "duration": "48h" } +} +``` + +API:`/api/v1/orgs/:oid/projects/:pid/release-policies`。 + +## 审批 + +- `POST .../releases/:rid/approve` —— 同意 +- `POST .../releases/:rid/reject` —— 拒绝并附原因 +- `GET /api/v1/orgs/:oid/releases/pending-for-me` —— 列出待我审批 + +## 执行与灰度 + +```http +POST .../releases/:rid/execute +``` + +执行时平台向目标 ordo-server 集群同步规则,可选灰度: + +| 操作 | 端点 | +| -------- | ----------------------------------------------------- | +| 暂停 | `POST .../releases/:rid/pause` | +| 继续 | `POST .../releases/:rid/resume` | +| 回滚 | `POST .../releases/:rid/rollback` | +| 当前快照 | `GET .../releases/:rid/execution` | +| 历史 | `GET .../releases/:rid/history` | +| 事件流 | `GET .../releases/:rid/executions/:eid/events` (SSE) | + +环境的灰度配置:`PUT /api/v1/orgs/:oid/projects/:pid/environments/:eid/canary`。 + +## 回滚 + +任何已发布的 release 都可一键回滚:平台从历史中找到上一个稳定版本,**新建一条** rollback release 并自动通过审批(保留审计链),不直接覆写。 + +## 预览 + +```http +POST .../releases/preview +``` + +无需创建 release 即可看到 diff 与策略评估结果,方便发布前的最终确认。 diff --git a/ordo-editor/apps/docs/zh/platform/server-registry.md b/ordo-editor/apps/docs/zh/platform/server-registry.md new file mode 100644 index 00000000..e350439a --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/server-registry.md @@ -0,0 +1,93 @@ +# 服务器注册与多区域 + +平台和执行节点之间是松耦合的——`ordo-server` 实例运行后**主动**向平台注册自己,平台维护一份服务器目录用于发布与代理。 + +## 注册流程 + +```mermaid +sequenceDiagram + participant Server as ordo-server + participant Platform as ordo-platform + + Server->>Platform: POST /api/v1/internal/register
{region, capabilities, version} + Platform-->>Server: server_id + token + loop 每 N 秒 + Server->>Platform: POST /api/v1/internal/heartbeat
{metrics, healthy} + end +``` + +> `/api/v1/internal/*` 是机器对机器端点,使用 server token 鉴权,不暴露给浏览器或 SDK。 + +## 服务器目录 + +| 操作 | 端点 | +| ---- | --------------------------------- | +| 列出 | `GET /api/v1/servers` | +| 详情 | `GET /api/v1/servers/:id` | +| 健康 | `GET /api/v1/servers/:id/health` | +| 指标 | `GET /api/v1/servers/:id/metrics` | +| 注销 | `DELETE /api/v1/servers/:id` | + +服务器记录字段: + +- `region` —— 部署区域标签 +- `capabilities` —— 启用的能力(如 `jit`、`signature`) +- `healthy` / `last_heartbeat` +- `current_rulesets` —— 当前持有的规则集摘要 + +## 项目绑定 + +每个项目可绑定一个或多个服务器(可按环境分别绑定)。绑定决定: + +1. 发布时把规则推到哪些 ordo-server。 +2. 业务请求经过平台代理时路由到哪个集群。 + +```http +PUT /api/v1/orgs/:oid/projects/:pid/server +{ "environment": "prod", "server_ids": ["s_eu", "s_us"] } +``` + +## 执行代理 + +业务系统不一定能直连区域 ordo-server;平台暴露一个透传代理: + +```http +POST /api/v1/engine/:project_id/execute +``` + +请求会被路由到该项目当前环境绑定的 ordo-server,并保留原始 latency 指标(平台只做转发,不做解析)。 + +适用场景: + +- 业务方只能访问公网平台域名。 +- 多区域容灾——平台层做健康路由,故障时切到备份服务器。 +- 灰度切流——发布灰度阶段平台按比例分发到新旧版本服务器。 + +## 多区域部署示例 + +```mermaid +flowchart LR + subgraph 中央["中央治理"] + P[ordo-platform] + DB[(Postgres)] + P --- DB + end + subgraph 北美 + S1[ordo-server US-East] + S2[ordo-server US-West] + end + subgraph 欧洲 + S3[ordo-server EU-West] + end + subgraph 亚洲 + S4[ordo-server AP-East] + end + + S1 -- 注册/心跳 --> P + S2 -- 注册/心跳 --> P + S3 -- 注册/心跳 --> P + S4 -- 注册/心跳 --> P + + Biz["业务系统"] -- 直连或经平台代理 --> S1 + Biz -- 直连或经平台代理 --> S3 +``` diff --git a/ordo-editor/apps/docs/zh/platform/studio.md b/ordo-editor/apps/docs/zh/platform/studio.md new file mode 100644 index 00000000..95cfeb8c --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/studio.md @@ -0,0 +1,57 @@ +# Studio 编辑器 + +Studio 是 Ordo Platform 的可视化编辑器,浏览器原生应用。它在同一份规则集上提供三种等价视图,互相实时同步。 + +## 三种编辑模式 + +### 流程图(Flow) + +- 基于 Vue Flow 的蓝图风格画布。 +- 节点类型:**Decision**(决策分支)、**Action**(赋值与外部调用)、**Terminal**(终结输出)、**SubRule**(子规则调用)。 +- Pin 风格:三角形为执行流,圆形为数据流。 +- 支持多入度:多个上游节点可同时连入同一节点的输入端,自动避免重复连线。 +- 拖拽连线时实时高亮兼容的目标 Pin;执行轨迹回放时节点会被着色标注。 + +### 表单(Form) + +- 树形结构编辑器,适合不熟悉流程图思维的业务用户。 +- 每个步骤独立卡片,子规则与决策分支自动嵌套。 + +### JSON + +- 直接编辑 RuleSet JSON。 +- 内置 schema 校验与表达式高亮。 +- 适合从 Git/CI 导入或做批量替换。 + +> 三种模式的状态同步基于一个共享的 [editor-store](/zh/guide/editor-store)(Pinia / 框架无关)。任意修改都会立即在其他视图反映,并入栈撤销历史。 + +## 执行追踪面板 + +发布前可在 Studio 中输入一段 JSON 上下文 → "试运行" → 平台调用 ordo-server 的 trace API → 返回每一步的: + +- 入口/出口快照 +- 命中的分支条件 +- 表达式求值过程 +- 子规则调用堆栈 +- 总耗时与每步耗时 + +追踪结果会以 [ExecutionAnnotation](https://github.com/Ordo-Engine/Ordo) 浮窗叠在流程图节点上方。 + +## 测试用例集成 + +每条测试用例可直接在 Studio 内编辑、单独运行、批量运行。结果以颜色编码显示: + +- 绿:实际输出与期望一致 +- 红:mismatch,会展开 diff +- 灰:尚未运行 + +详见 [测试管理](./testing)。 + +## 模板与子规则 + +- **模板**:从 `Marketplace` 或内置模板库一键克隆出含规则、契约、事实、测试用例的完整项目。 +- **子规则资产**:在项目级抽取常用片段(如「KYC 审核」「风险评分」),跨规则集复用,更新一次处处生效。 + +## 国际化 + +Studio 与文档全套支持英文 / 简体中文 / 繁体中文,UI 语言可在右上角切换。 diff --git a/ordo-editor/apps/docs/zh/platform/sub-rules.md b/ordo-editor/apps/docs/zh/platform/sub-rules.md new file mode 100644 index 00000000..7b53de16 --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/sub-rules.md @@ -0,0 +1,71 @@ +# 子规则资产 + +子规则(Sub-Rule)让你把跨规则集复用的逻辑片段抽取成项目级或组织级资产,多个规则集通过 `SubRule` 步骤引用同一份资产。 + +## 应用场景 + +- **KYC 审核**:不同业务线(贷款、信用卡、保险)都需要相同的身份核验逻辑。 +- **风险评分**:客户风险分数算法在多个决策中复用。 +- **黑名单检查**:所有面向用户的规则集开头都要走一遍。 + +## 数据模型 + +```jsonc +// POST /api/v1/orgs/:oid/projects/:pid/sub-rules +{ + "name": "kyc-check", + "version": "1.2.0", + "graph": { + "startStepId": "verify", + "steps": [ + { "id": "verify", "type": "decision", "branches": [...] }, + { "id": "pass", "type": "terminal", "code": "OK" }, + { "id": "fail", "type": "terminal", "code": "REJECT" } + ] + }, + "bindings": [ + { "name": "id_number", "type": "string", "required": true } + ], + "outputs": [ + { "name": "score", "type": "number" } + ] +} +``` + +- `bindings`:调用方必须传入的参数。 +- `outputs`:子规则结束后回写到父级上下文的字段。 + +## 在规则集中引用 + +Studio 中放置一个 `SubRule` 节点,选择 ref name 与版本,配置 binding 表达式与 output 映射: + +```jsonc +{ + "id": "step_kyc", + "type": "sub_rule", + "refName": "kyc-check", + "bindings": [{ "name": "id_number", "value": { "type": "variable", "path": "$.user.idn" } }], + "outputs": [{ "name": "score", "to": "kyc_score" }], + "nextStepId": "step_decide" +} +``` + +## 发布时的内联快照 + +发布规则集时,平台会**深度内联**所有引用的子规则当前版本(BFS 解析),生成一个无外部依赖的扁平 RuleSet 再下发到 ordo-server: + +- 子规则后续被修改、删除,已发布的规则集行为完全不变。 +- 引擎执行时不再需要回头查询子规则,零额外开销。 +- 默认调用深度上限 10(避免循环递归),平台同时做 DFS 环检测。 + +## 版本与 diff + +每次更新子规则会形成新版本快照: + +| 操作 | 端点 | +| ------ | --------------------------------------------------------- | +| 列出 | `GET /api/v1/orgs/:oid/projects/:pid/sub-rules` | +| 取/改 | `GET/PUT /api/v1/orgs/:oid/projects/:pid/sub-rules/:name` | +| 组织级 | `/api/v1/orgs/:oid/sub-rules`(跨项目共享) | + +修改子规则后,平台会列出**所有引用它的规则集**——这些规则集需要重新发布才能拿到新版子规则的逻辑。 diff --git a/ordo-editor/apps/docs/zh/platform/testing.md b/ordo-editor/apps/docs/zh/platform/testing.md new file mode 100644 index 00000000..3a1f095d --- /dev/null +++ b/ordo-editor/apps/docs/zh/platform/testing.md @@ -0,0 +1,64 @@ +# 测试管理 + +平台为每个规则集提供独立的测试套件——和 ordo-cli 用同一份 YAML 格式,覆盖 Studio、CLI、CI 三处入口。 + +## 用例结构 + +```yaml +# project-level testset +ruleset: discount-check +cases: + - name: vip 用户走 20% 折扣 + input: + user: { id: u1, vip: true, age: 28 } + order: { amount: 200 } + expect: + code: VIP + output: { discount: 0.2 } + + - name: 未成年拒单 + input: + user: { id: u2, vip: false, age: 16 } + order: { amount: 50 } + expect: + code: DENY + output: { reason: 'underage' } +``` + +## API + +| 操作 | 端点 | +| ---------- | ------------------------------------------------------------ | +| 列出测试 | `GET /api/v1/projects/:pid/rulesets/:name/tests` | +| 创建/更新 | `POST/PUT /api/v1/projects/:pid/rulesets/:name/tests[/:tid]` | +| 单个运行 | `POST /api/v1/projects/:pid/rulesets/:name/tests/:tid/run` | +| 全部运行 | `POST /api/v1/projects/:pid/rulesets/:name/tests/run` | +| 项目级运行 | `POST /api/v1/projects/:pid/tests/run` | +| 导出 YAML | `GET /api/v1/projects/:pid/rulesets/:name/tests/export` | + +## 与发布的联动 + +发布请求创建时([发布流程](./releases)),平台会自动跑被涉及规则集的全部测试用例。**任何用例失败都会阻断发布请求的创建**。 + +可在发布策略里关闭 `auto_run_tests` 跳过校验,但生产环境通常不建议这么做。 + +## CI 集成 + +- 平台导出 YAML 文件直接 commit 到代码仓库。 +- ordo-cli 在 PR 阶段运行: + +```bash +ordo test --rules ./rulesets --tests ./tests --reporter junit > junit.xml +``` + +输出格式:JUnit XML、JSON、TAP,可直接喂给 GitHub Actions / GitLab CI。 + +## Trace 与失败诊断 + +测试用例运行失败时,平台返回完整的执行 trace,Studio 中点开测试结果即可看到: + +- 期望的 output code 与实际命中的 code +- 失败前命中的最后一条分支 +- 每个 action 节点的赋值过程 + +详见 [Studio 编辑器 - 执行追踪](./studio#执行追踪面板)。