Cosmic Story v2 のアーキテクチャ — 詳細な解説。

エンジニア、PM、ジャーナリスト、提携スカウトの方々へ。パイプライン全体、4つのMongoDBコレクション、EDAイベント、Vモデルの厳密さ、パフォーマンス目標、セキュリティ、アクセシビリティのすべてを1ページにまとめています。

  • Soulwise-story は、既存の cosmic-story モジュールと並ぶ新しい NestJS モジュールです。機能モジュール間の直接インポートは一切ありません。
  • 4つのMongoDBコレクション:soulwise_persons、soulwise_chapters、soulwise_journal_entries、soulwise_resonances。本文はAES-256で暗号化し、それぞれのクエリに合わせてインデックスを付与しています。
  • 28秒のタイムアウトを設けたBullMQキューによる非同期生成です。イベントはデータベースへのコミット後にのみEventEmitter2経由で発行され、受信トレイに幻のアイテムが残ることはありません。
  • Vモデル仕様:119件の要件、ギャップはゼロ。バックエンドのカバレッジ目標はサービスのステートメントで85%、フロントエンドはPiniaストアで90%です。

パイプラインを、エンジニアリングの詳細とともに改めてご紹介します

各ステップには、サービス、コントラクト、イベントが備わっています。

  1. トリガー

    ユーザーの操作(「Sister の今日のチャプターを生成する」など)、あるいはスケジュールされた cron 処理。たとえば日曜日の9時の振り返りや、6時間ごとの天候更新などです。

  2. キュー

    ジョブは soulwise-chapter-generation という名前の BullMQ キューに入り、28秒の厳格なタイムアウトが設定されています。長時間実行されるジョブは強制終了され、ユーザーには「もう一度お試しください」と通知されます。

  3. コンポーズ

    ChapterGenerationService が、4つの要素からなるプロンプト(人物コンテキスト、占星術、シグナル、ケイデンス)を1つの入力にまとめます。生のユーザー個人情報がそのままプロンプトに入ることはなく、すべて事前に除去されます。

  4. 生成

    AI_GENERATION_ADAPTER シンボルトークンを通じて AI プロバイダーが呼び出されます。プロバイダーは差し替えが可能です。レスポンスは、続行する前に長さ・形式・安全性が確認されます。

  5. 後処理

    次の四つが実行されます。クライシス分類器が危機的な表現をチェックし、アスペクトチップ抽出器が一〜三個の占星術チップを抽出し、アンチクレームフィルターが禁止されている表現を除去し、本文はプラットフォーム管理の鍵で AES-256 により暗号化されます。

  6. 保存

    成果物は、該当する MongoDB コレクション(チャプター、ジャーナルエントリー、レゾナンス)に書き込まれ、高速な検索のために userId と personId のインデックスが付与されます。まずソフトデリートを行い、個人情報のハードデリートは30日後に実施されます。

  7. 通知

    データベースのコミット後に、EventEmitter2 イベント(CHAPTER_COMPLETED、JOURNAL_CREATED)が発火します。通知モジュールがこれを受け取り、受信トレイの項目を作成し、必要に応じてプッシュ通知を送信します(一日一回までに制限され、サイレント時間帯は尊重されます)。

  8. 表示

    フロントエンドは、認証済みの API 呼び出しを通じて成果物を取得します。ハブは新しいコンテンツとともに再描画されます。ユーザーがオフラインだった場合は、キャッシュが前日のビューを提供し、再接続時に新しい成果物が表示されます。

トリガーから表示までの7つのステップ。それぞれが実際に行う働きにちなんで名付けられています。

4つのコレクション

それぞれが応答するクエリに合わせてインデックスを付与しています。

soulwise_persons

アルバムのエントリです。userId、status、deletedAtにインデックスを付与しています。まずソフトデリートを行い、PIIのハードデリートは30日後に実施します。

soulwise_chapters

AIが執筆したチャプターで、本文は暗号化されています。personId、userId、generatedAtにインデックスを付与しています。アスペクトチップは高速なフィルタリングのため、別の配列として保存しています。

soulwise_journal_entries

ユーザーが書いた振り返りで、本文は暗号化されています。userId、personId、createdAtにインデックスを付与しています。検索用に本文へテキストインデックスを設定しています。エントリごとに「プライベート — Luminaraに渡さない」フラグを備えています。

soulwise_resonances

絆ごとの4次元スコアです。personIdに一意インデックスを付与しています。チャプターまたはジャーナルの書き込み後、サービス呼び出しによって再計算されます。

EDAイベント

厳格なルール:イベントはデータベースのコミット後にのみ発火します。モジュール間の依存関係はSymbolインジェクショントークンを介して扱い、forwardRefは使用しません。フィーチャーモジュール間でサービス同士を直接インポートすることはありません。

  • SoulwiseEvents.CHAPTER_COMPLETED — SoulwiseEvents.CHAPTER_COMPLETED — チャプターが暗号化され永続化された後に発火します。Notifications-v2 がリッスンし、受信トレイ項目を作成し、必要に応じてプッシュを送信します。
  • SoulwiseEvents.JOURNAL_CREATED — SoulwiseEvents.JOURNAL_CREATED — ジャーナルエントリが暗号化され永続化された後に発火します。Resonanceサービスがリッスンし、再計算をトリガーします。
  • SoulwiseEvents.PERSON_BIRTH_UPDATED — SoulwiseEvents.PERSON_BIRTH_UPDATED — 人物の出生データが変更された後に発火します。相互占星術のキャッシュが無効化されます。
  • SoulwiseEvents.PUSH_REQUESTED — SoulwiseEvents.PUSH_REQUESTED — notifications-v2 の契約に準拠します。プッシュ予算とサイレント時間を尊重します。

Vモデル仕様の厳密性

119件のトレース可能な要件、ギャップはゼロです。各要件は前方向にテストケース(UTP、ITP、STP、E2E)へ、後方向にユーザーストーリーへとマッピングされます。20件のユーザーストーリー。15件の機能要件。12件の非機能カテゴリ。8件のグローバル受け入れゲート。

パフォーマンス契約

チャプター生成はリクエストの95%において30秒以内を目標とし、BullMQのジョブ処理時間の分布に対して測定します。API p99 のGETレイテンシは1,000人の同時接続ユーザー時に500ミリ秒以内を目標とし、k6 の負荷テストで測定します。フロントエンドのTTIはシミュレートした4G環境で3秒以内を目標とし、Lighthouse CIで測定します。

セキュリティ契約

ジャーナルおよびチャプター本文には、プラットフォーム管理キーによるAES-256の保存時暗号化を適用します。転送時はTLS 1.2以上を使用し、HTTPからHTTPSへリダイレクトします。JWTアクセストークンの有効期間は1時間、リフレッシュトークンの有効期間は30日で、リフレッシュ時にローテーションします。個人情報はソフトデリートとし、完全削除までに30日間の猶予期間を設けます。

アクセシビリティ契約

prefers-reduced-motion はグローバルに尊重され、GSAP のアニメーションは不透明度のみのフェードになります。すべての操作可能な要素に VoiceOver と TalkBack のラベルを付与しています。各リリース前に iOS と Android で手動検証を行っています。

cosmic-story を拡張するのではなく、なぜ独立した soulwise-story モジュールにするのですか。

上流の仕様が機能を再構築するためであり、既存モジュール内で再構築すると v1 の体験を壊すか、あるいは後でフォークしてからマージする必要が生じるからです。新しいモジュールにすれば v1 には手を加えず、v2 で実証を進め、準備が整った段階でクリーンに移行できます。

なぜ Postgres ではなく MongoDB なのですか。

既存の My Zodiac AI のバックエンドは MongoDB 上にあり、切り替えればこの機能とは無関係なインフラ上の判断を迫られることになります。ドキュメントモデルは、入れ子で長さが可変、ブロブとして暗号化されるチャプターやジャーナルのエントリーにもよく適しています。

なぜキューに BullMQ を選んだのですか。

BullMQ は Redis 上で動作し、Redis はセッションとレート制限のために既にスタックに含まれています。新たなインフラは不要です。組み込みのリトライ、タイムアウト、可観測性により、独自の仕組みを作らなくてもチャプター生成のニーズを満たせます。

上流の仕様は実際にはどこに記載されているのですか。

内部リポジトリです。このページの数値や契約は、上流の V モデル成果物を言い換えたものです。My Zodiac AI のブログクラスター上で公開されているエンジニアリングブログの記事('cosmic-story-v2' のタグ付き)では、ビルドの特定の部分をより深く掘り下げています。

My Zodiac AIを今すぐお試しください

Soulwiseがその波を広げていく一方で、フラッグシップの占星術アプリはすでにあなたの手の中にあります。

占星術コンテンツは、内省と娯楽を目的としています。ここで紹介する Cosmic Story v2 の機能は開発中であり、提供内容は予告なく変更される場合があります。