Skip to content

Commit c757c47

Browse files
authored
Merge pull request #101 from AdaWorldAPI/claude/medcare-bridge-lance-graph-wmx76z
docs(README): epiphany-first bilingual rewrite (EN + DE) with design-guard links
2 parents 26ae4e9 + bccf099 commit c757c47

4 files changed

Lines changed: 562 additions & 110 deletions

File tree

README.de.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# OGAR — Open Graph of Active Record
2+
3+
> [English](README.md) · **Deutsch** · [Philosophie](docs/PHILOSOPHIE.md)
4+
5+
Das [Active-Record-Muster](https://martinfowler.com/eaaCatalog/activeRecord.html)
6+
(Martin Fowler, 2003) als kanonische 32-Bit-`classid`. Ein Codebook;
7+
jeder Consumer zieht, prägt niemals neu.
8+
9+
```rust
10+
let cid: u16 = HealthcarePort::class_id("Patient"); // 0x0901
11+
let render = HealthcarePort::APP_PREFIX | (cid as u32); // 0x0005_0901
12+
authorize(actor, cid, Op::Read); // geteilter Grant auf lo u16
13+
// // lokal anreichern — deins
14+
```
15+
16+
```
17+
classid : u32 = 0xAAAA ‖ 0xDDCC beide Hälften sind ADRESSE
18+
│ │
19+
│ └─ lo u16 — WELCHES KONZEPT (geteilte Identität)
20+
└─────────── hi u16 — WESSEN RENDER (App-eigene Haut)
21+
22+
──────► löst auf zu ──────►
23+
├─ ClassView die HAUT (pro App)
24+
├─ Class die FORM (kanonisch)
25+
└─ ActionDef + KausalSpec die MAGIE (Verhalten — im Core,
26+
nie in der Adresse)
27+
```
28+
29+
## Active-Record-Querverweis
30+
31+
| OGAR-Vokabular | Rails ActiveRecord | Odoo `models.Model` |
32+
|-------------------------------|------------------------------------------|------------------------------------------------------|
33+
| `ogar/Class` | `class WorkPackage < ApplicationRecord` | `class sale_order(models.Model): _name='sale.order'` |
34+
| `ogar/Association(BelongsTo)` | `belongs_to :project` | `fields.Many2one('res.partner')` |
35+
| `ogar/Association(HasMany)` | `has_many :line_items` | `fields.One2many('sale.order.line', 'order_id')` |
36+
| `ogar/Association(HabTm)` | `has_and_belongs_to_many :tags` | `fields.Many2many('res.partner.category')` |
37+
| `ogar/Mixin` | `include Mentionable` | `_inherit = 'mail.thread'` |
38+
| `ogar/Enum` | `enum status: { open: 0, closed: 1 }` | `fields.Selection([('draft','Draft'), ...])` |
39+
| `ogar/Field` | `t.string :subject` (in Migration) | `subject = fields.Char(required=True)` |
40+
| `ogar/Validation` ¹ | `validates :subject, presence: true` | `@api.constrains('subject')` |
41+
| `ogar/Callback` ¹ | `before_save :touch_parent` | `@api.depends('field_x')` / `@api.onchange` |
42+
| `ogar/Scope` | `scope :open, -> { where(state:'open')}` | Such-Domain `[('state','=','open')]` |
43+
44+
¹ Validation/Callback sind **Verhalten**`ActionDef` + `KausalSpec`,
45+
erreicht *über* die classid, nie in ihr. Rails, Odoo, Sequel, Django,
46+
Prisma — gleiches Vokabular, ein IR.
47+
48+
## Render-Linse — ein Konzept, viele Apps
49+
50+
| classid | Konzept (lo u16) | Render (hi u16) | App |
51+
|---------------|-----------------------------|--------------------------|----------------------|
52+
| `0x0001_0102` | `0x0102` project_work_item | `0x0001` OpenProject | openproject-nexgen-rs |
53+
| `0x0007_0102` | `0x0102` project_work_item | `0x0007` Redmine | (Consumer TBD) |
54+
| `0x0005_0901` | `0x0901` patient | `0x0005` Medcare | medcare-rs |
55+
| `0x0003_0103` | `0x0103` billable_work_entry | `0x0003` WoA | woa-rs |
56+
| `0x0004_0103` | `0x0103` billable_work_entry | `0x0004` SMB | smb-office-rs |
57+
| `0x0001_0103` | `0x0103` billable_work_entry | `0x0001` OpenProject | openproject-nexgen-rs |
58+
| `0x0007_0103` | `0x0103` billable_work_entry | `0x0007` Redmine | (Consumer TBD) |
59+
| `0x0002_0103` | `0x0103` billable_work_entry | `0x0002` Odoo | odoo-rs |
60+
61+
Gleiche `0x0103` → gleicher RBAC-Grant, gleiche Ontologie, gleiche
62+
Cross-Fork-Identität. Fünf Apps rendern *abrechenbare Zeit* auf fünf
63+
Arten; Planer-Stunden stimmen mit der Abrechnung per Codebook-Lookup
64+
überein, nicht per Übersetzung.
65+
66+
## Consumer-Muster — vier Züge, nur einer ist deiner
67+
68+
| Zug | Aufruf | Deiner? |
69+
|-----------|--------------------------------------------|-----------|
70+
| pull | `Port::class_id(name) -> Option<u16>` | nein — reine Funktion |
71+
| render | `Port::APP_PREFIX \| (cid as u32)` | nein — typisierter Helfer |
72+
| authorize | `authorize(actor, cid, op)` ² | nein — geteiltes Grant-Gitter |
73+
| enrich | deine Domänen-Logik, an `cid` verschlüsselt | **ja** |
74+
75+
² `lance-graph-rbac::authorize` ist `[H]`, gegated auf
76+
`PROBE-OGAR-RBAC-AUTHORIZE`. Bis es ausliefert, behalte die bestehende
77+
Auth — führe KEINE `*Bridge` als Notlösung wieder ein.
78+
79+
## Design-Wächter
80+
81+
| Wächter | Lesen vor |
82+
|---|---|
83+
| [Consumer Best Practices](docs/OGAR-CONSUMER-BEST-PRACTICES.md) | jeder Consumer-Aufrufstelle (classid · `APP_PREFIX` · `ClassView` · `*Bridge`) |
84+
| [SurrealQL-AST-Fallen-Pre-Flight](docs/SURREAL-AST-TRAP-PREFLIGHT.md) | Producer→IR · Transcode · Codegen · `.surql`-Authoring |
85+
| [SurrealQL-AST als Adapter](docs/SURREAL-AST-AS-ADAPTER.md) | Entscheidung Rückgrat vs. Adapter |
86+
| [Die Firewall](docs/THE-FIREWALL.md) | jeder Hot-Path-Serialisierung (ADR-022/023) |
87+
| [APP‖class-Codebook-Layout](docs/APP-CLASS-CODEBOOK-LAYOUT.md) | Prägen einer classid oder eines App-Präfix |
88+
| [classid-RBAC-Keystone](docs/CLASSID-RBAC-KEYSTONE-SPEC.md) | Verdrahten der Autorisierung |
89+
| [Consumer-Migrations-Anleitung](docs/CONSUMER-MIGRATION-HOWTO.md) | Umzug eines Consumers weg von einer `*Bridge` |
90+
91+
Der Fallen-Pre-Flight (Producer-seitig) und der Best-Practices-Leitfaden
92+
(Consumer-seitig) sind die zwei Arme einer Grenze: der Pre-Flight hält
93+
einen *Producer* davon ab, DDL für den Core einzusetzen; der Best-
94+
Practices-Leitfaden hält einen *Consumer* davon ab, den Core lokal neu
95+
zu implementieren.
96+
97+
## Architektur
98+
99+
```
100+
─── Quell-ASTs (Producer) ─────────────────────────────────────
101+
Ruby AR Python Odoo SQL DDL ...
102+
lib-ruby-parser libcst / ast sqlparser-rs
103+
│ │ │
104+
└──────────┬─────────┴──────────┬─────────┘
105+
▼ ▼
106+
OGAR IR (kanonisch) ⟷ ogar-extensions/*
107+
│ Class · ActionDef · Identity · KausalSpec
108+
109+
│ validiert von lance-graph-ontology (+ Cache)
110+
│ geplant von lance-graph-planner
111+
│ gespeichert als SoA-spaltenförmig (Arrow IPC, append-only Lance)
112+
113+
lance-graph-Tripel
114+
115+
├─ Projektionen (Consumer — gleiches IR, andere Ziele): ← ADAPTER
116+
│ • SurrealQL DDL AST (DEFINE TABLE / FIELD) nur struktureller Arm;
117+
│ • PostgreSQL DDL (CREATE TABLE / Migration) Verhaltens-Arm
118+
│ • OpenAPI / JSON-Schema (API-Verträge) lebt im Core
119+
│ • TypeScript-Typen (Frontend-Interfaces) (Verhaltens-Arm: nur Core)
120+
│ • Prisma / Drizzle (andere ORMs)
121+
122+
└─ Laufzeit (Aktor-Schicht — Pragmatik):
123+
lance-graph-callcenter (BEAM-Äquivalent über OGAR)
124+
```
125+
126+
### Voller Schlüssel (16-Byte-Zoom)
127+
128+
```
129+
key = classid(4) │ HEEL · HIP · TWIG (6) │ family(3) │ identity(3)
130+
▲ ▲ ▲ ▲
131+
Klassen- HHTL-Kaskaden-Tiers Basin- Instanz
132+
Adresse (256×256 Zentroid- Gruppierung im Basin
133+
(dieses Doc) Kacheln, O(1)-Distanz)
134+
```
135+
136+
## Repository-Layout
137+
138+
```
139+
OGAR/
140+
├── crates/
141+
│ ├── ogar-vocab/ — Rust-Typen: kanonisches IR + Codebook (class_ids, ports, APP_PREFIX)
142+
│ └── ogar-ontology/ — Präfix-Konventionen, NiblePath-kompatible Identität
143+
├── vocab/
144+
│ ├── ogar.ttl — Turtle/RDF-Kanonform
145+
│ ├── ogar.json-ld — JSON-LD-Kanonform (geplant)
146+
│ └── ogar.surql — SurrealQL-DDL-Projektion (nur struktureller Arm)
147+
└── docs/ — die sieben Wächter oben + das Discovery- / Integration- / ADR-Ledger
148+
```
149+
150+
## Producer / Consumer
151+
152+
**Producer** (Quell-AST → OGAR IR): `ruff_ruby_spo` (Ruby AR, liefert in
153+
[`openproject-nexgen-rs`](https://github.com/AdaWorldAPI/openproject-nexgen-rs)
154+
aus) · `ogar-python` (Django + Odoo, geplant) · `ogar-sql-ddl` (geplant)
155+
· `ogar-typescript` (geplant).
156+
157+
**Consumer** (OGAR IR → Ziel): `op-codegen-pipeline` (liefert aus) ·
158+
`ogar-to-postgres` · `ogar-to-surrealql` · `ogar-to-openapi` ·
159+
`ogar-to-typescript` (alle geplant). Alle folgen dem Consumer-Muster:
160+
**pull · render · authorize · enrich**.
161+
162+
## Laufzeit — lance-graph-callcenter
163+
164+
OGIT ↔ HIRO ↔ OTP/BEAM ist *Ontologie ↔ Laufzeit ↔ Aktor-Substrat*. Das
165+
OGAR-Analogon ist der Vier-Crate-`lance-graph`-Stack:
166+
167+
| Schicht | OGIT-Welt | OGAR-Welt |
168+
|---------------------------|-------------------------|--------------------------------------------------------------------|
169+
| Substrat-Primitive | (roher Graph) | **lance-graph-contract** — NiblePath, Identität, Versionen, Codebook |
170+
| Ontologie-Schicht + Cache | OGIT-Vokabular + Ext. | **lance-graph-ontology** — OGAR registriert; schnelle Typ-Auflösung |
171+
| Query / Plan | HIRO-Query-Planner | **lance-graph-planner** — ontologie-bewusste Traversierungs-Optimierung |
172+
| Aktor-Laufzeit | HIRO-Automation + BEAM | **lance-graph-callcenter** — Dispatch an `ogar/Class`-Aktoren |
173+
174+
`subClassOf` ist der Supervisions-Baum; Ontologie-Updates sind
175+
Hot-Code-Reload. Die Klasse ist die Aktor-Spezifikation; der Aktor ist
176+
die laufende Klasse.
177+
178+
## Status
179+
180+
**v0 — auslieferndes Codebook.** [`crates/ogar-vocab`](crates/ogar-vocab)
181+
ist der sprachneutrale Lift der stabilen C17a–c-Form aus
182+
`ruff_ruby_spo`. `class_ids`, `ports::*Port`, `APP_PREFIX` sind live;
183+
die TTL- / SurrealQL-Projektionen in [`vocab/`](vocab) sind generierte
184+
Artefakte (stabiles URI-Präfix `ogar/`). Vokabular-Repo zuerst,
185+
Code-Crate zweitens — wie FOAF oder SKOS.
186+
187+
## Lizenz
188+
189+
MIT — siehe [`LICENSE`](LICENSE).

0 commit comments

Comments
 (0)