Cross-Module Integration
EcosystemEntityLinks table
EcosystemEntityLinks table — documentation pending.
Complete
The `ecosystem_entity_links` table is the typed source of truth for every cross-module connection. Phase 1 ships this as a versioned JSON manifest in repo (`mock-ecosystem-links.ts`). Phase 2 migrates to a live database table when manual link volume exceeds ~200 entries.
Schema
- id · uuid
- Stable identifier per link.
- source_entity_type / source_entity_id
- The entity the link starts FROM. Type is one of the 7 module enum values.
- target_entity_type / target_entity_id
- The entity the link points TO. Same enum.
- relation_type · enum
- One of the 14 types (see Relation Types topic). Drives reason-template selection.
- relation_strength · 0-100
- Stable score. Manual T2 defaults to 90. T3 ranges 30-70 based on taxonomy matching.
- is_manual / is_auto_suggested
- Provenance flags. Manual takes priority over auto for the same (source, target, relation_type) tuple.
- is_featured / is_hidden
- Editorial controls. `is_featured = true` ranks first within its tier. `is_hidden = true` suppresses an auto-suggestion the editor rejected.
- display_order · smallint
- Tie-breaker for sort order. Lower = appears first.
- editorial_reason / editorial_reason_ar
- 160-char bilingual reason text. Used when present; otherwise the template generator fills in.
- created_at / updated_at / created_by / updated_by
- Audit columns. `created_by` is NULL for auto-suggested rows; populated with editor user_id for manual links.
Why a single table vs per-module tables
- One query path for the shared component — the resolver fetches with one indexed lookup.
- Bidirectional traversal — "what links TO entity X?" works without a separate table.
- Cheap to add new relation types — no migrations.
- Indexing strategy is straightforward (idx on source, idx on target, unique on the (source, target, relation_type) tuple).
