アーキテクチャ
コンポーネント
- コアウェアハウス (
backend/) —/api/v1/配下のNode.js/TypeScript + Express REST APIです。 リレーショナルメタデータ (Prisma経由のPostgreSQL) を保持し、ライフサイクルイベント (RabbitMQ) を 発行・購読し、ステップのディスパッチ、リトライ/バックオフの処理、ステップタイムアウトの監視を行う Pipeline Routerをホストします。 - プラグインワーカー (
plugins/*/) — プラグインごとに独立したDockerコンテナが1つ。各プラグインは 自分専用のルーティングキーでイベントブローカーを購読し、単一の内部HTTPコールバックで結果を報告します。 - Web UI (
frontend/) — React + Vite + TailwindのSPAで、3つの主要セクション (リソース、 パイプライン、プラグイン) とグローバル検索を持ち、/apiと/registryをそれぞれのバックエンド サービスへリバースプロキシするnginx経由で配信されます。 - プラグインレジストリ (
registry/+community-site/) —registryは独立したサービス (独自のSQLiteバックエンドAPI、ユーザーアカウント付き) で、どのDataCoreデプロイメントのフロントエンド からも閲覧・投稿できます。community-siteは同じAPIをフロントエンドとする独立したウェブサイトで、 それ自体が独立した到達先であり、スタックの他の部分とは無関係です。2種類の公開掲載をホストします: プラグイン掲載 (メタデータとプラグイン自身のリポジトリ/Dockerイメージへのリンク — コードホスティング や自動デプロイシステムではありません) と DataCoreバンドル (リソース定義の一覧とそれらを処理した パイプラインを共有可能にしたもの — 名前とリポジトリリンクで相互参照される、他の場所での再処理用。 詳細はバンドルの共有とインポートを参照)。どちらの投稿にも確認済みアカウント が必要ですが、閲覧には不要です。 - ストレージ層: PostgreSQL (リレーショナルメタデータのみ)、MinIO (生ファイル + テキスト/JSON 成果物、S3互換)、そしてプラグインの成果物が属する任意のストア (ベクトル用のQdrantなど) — Postgresがファイル内容やベクトルを直接保持することは決してなく、参照ポインタのみを保持します。
指針となる原則
これらはプロジェクト憲法 (.specify/memory/constitution.md) に由来し、あらゆる設計判断を形作ります:
- イベント駆動アーキテクチャ — すべての状態遷移はブローカーイベントであり、明示的に許可された 唯一の内部成果物コールバックを除いて、サービス間の同期呼び出しはありません。
- プラグインの分離 — 各プラグインは独自のコンテナであり、あるプラグインのクラッシュ・ハング・ バグがコアや他のプラグインに影響することはありません。
- スキーマファーストのデータモデル — Resource/Pipeline/Plugin/Artifactのスキーマは、それらを 読み書きするエンドポイントより先に定義されます。
- APIコントラクトの規律 — すべてのRESTエンドポイントは
/api/v1/配下にあり、一貫したJSON エラーエンベロープ ({ "error": { "code", "message" } }) を使用します。 - ストレージの分離 — リレーショナルメタデータ、生ファイル、生成された成果物はそれぞれ独自の層に 存在し、層をまたいで重複することはありません。
- UIの一貫性 — Web UIはライブのAPI状態を反映します。画面が接続された後にハードコードされた モックデータはありません。
- テストの規律 — すべてのRESTエンドポイントとイベントハンドラーは、実際の Postgres/RabbitMQ/MinIO/Qdrantに対して実行される統合テストを持ちます — モックは一切ありません。
- サイレント障害の禁止 — 失敗したステップはリソース上に具体的な
failure_reasonを表示します。 完了・失敗のいずれにもならず、あるいは (応答しないステップの場合) タイムアウト監視で捕捉されずに 永遠にProcessingのまま残ることはありません。
リクエストフロー: リソースの登録
User → POST /api/v1/resources
→ Core persists Resource (PENDING), matches a Pipeline by trigger_type
→ Core publishes RESOURCE_CREATED
→ Pipeline Router consumes it, snapshots the pipeline's steps onto the resource, dispatches step 0
→ Plugin Worker consumes PIPELINE_STEP_DISPATCHED, does its work
→ Plugin calls back POST /api/v1/internal/artifacts/{resource_id}
→ Core upserts the Artifact, advances to the next step (or marks COMPLETED)リトライ/バックオフ/タイムアウトの状態遷移を含む完全な詳細は、 イベントリファレンス と、仕様内の contracts/events.md にあります。