← ブログ一覧へ戻る
IR-Brain 開発中 / 未公開 Blazor Server + Minimal API + Worker 投資判断向けの構造化要約

ニュースURLやPDFを、投資家向けの構造化レポートに変換するWebアプリ

IR-Brain は、ニュース記事のURLまたはPDFを投入すると、本文抽出とAI要約を非同期で実行し、投資判断向けの観点で整理したレポートを返す .NET 8 ベースのWebアプリです。単発の要約UIではなく、認証、課金、マルチテナント、非同期ワーカー、永続化まで含めて一つのアプリとして組んでいます。

入力から保存までを一気通貫で実装 URL取得、PDF抽出、要約、DB保存、レポート表示までを同一アプリ内で接続しています。
投資家向けの観点を前提に設計 一般的な要約ではなく、positive / negative / risks / guidance などの構造で結果を扱います。
UIの裏側まで実装範囲が広い 認証、Stripe課金、Tenant分離、管理機能、起動時 migration / seed まで含めて構成しています。

プロダクト概要

解こうとしている課題

ニュースやIR資料を読んで投資判断に必要な情報を抜き出す作業は、単なる要約よりも整理の仕方が難しいと考えています。IR-Brain では、記事やPDFの本文を取って終わりではなく、投資家が見たい比較軸に寄せて結果を構造化することを重視しています。

そのため、出力は自由文だけではなく、executive summary / highlights / positives / negatives / risks / guidance / stock impact / performance / company / ticker といった項目で扱える前提にしています。

入力から出力までの流れ

ユーザーはニュースURLまたはPDFを登録します。登録時点では Source を Pending として保存し、本文取得や要約はリクエスト同期で完結させずに SourceWorker へ渡します。処理完了後、抽出本文は DocumentText、要約結果は Summary に保存され、レポート画面はポーリングで進捗と結果を追従します。

URL または PDF を投入し、Source を Pending 状態で登録する
SourceWorker が対象を取り出し、URLならHTML取得、PDFなら PdfPig で全文抽出を行う
抽出本文を正規化し、Azure OpenAI による要約を実行する。利用不可時は DummySummarizer にフォールバックする
DocumentText と Summary を保存し、Source を Done または Error に更新する
レポート画面でポーリングしながら、投資家向けの構造化レポートとして表示する

実装した主要機能

URL / PDF 取込

URL入力と PDF アップロードの両方に対応しています。URL取得は 15 秒タイムアウト、HTML抽出では script / style を除去してテキスト正規化を行います。PDF は PdfPig で全文抽出し、アップロードサイズは 20MB 上限です。

非同期要約パイプライン

投入直後に重い処理を同期実行せず、Source を状態管理しながら HostedService の SourceWorker で非同期処理します。進行状態が明示されるため、UI、DB、ワーカーの責務を分離しやすい構成です。

投資家向け要約プリセット

要約では複数の観点プリセットを選択でき、インカム投資家、バリュー投資家、グロース投資家、イベント短期、共通比較軸などを反映できます。単なる「短くする要約」ではなく、見る人の意思決定軸を先に置いた設計です。

レポート表示

結果は自由文ではなく構造化されたサマリーとして保持します。company / ticker のような識別情報に加えて、highlights、positives、negatives、risks などを分けて表示できるため、後段の比較やUI整理にもつなげやすい形です。

認証 / 認可

ASP.NET Core Identity をベースに Cookie 認証を構成し、Microsoft OpenID Connect ログインに対応しています。現状の認証導線は Microsoft サインイン中心です。EmailConfirmed を考慮したユーザー管理、ロックアウト、強めのパスワード要件、Admin ロールと AdminOnly ポリシーも入れています。

課金と利用制御

Stripe を連携し、free / pro / biz のプラン定義とサブスクリプション管理を実装しています。Webhook では署名検証を行い、Tenant ごとに有効な Subscription を 1 件に制約しています。利用数は処理開始時ではなく Done 後にコミットする設計です。

マルチテナント管理

ApplicationUser が TenantId を持ち、TenantProvider がログインユーザーからテナントを解決します。Source、Summary、DocumentText、Subscription、UsageCounter などのデータは Tenant 単位で分離しています。管理者向けにはテナント作成、更新、停止、再開、ユーザーの Tenant 紐付け、ロック制御、メール確認状態更新の画面があります。

永続化と制約設計

SQLite を Entity Framework Core 8 で扱い、Migration を用意しています。Source と DocumentText / Summary は 1:1 関係で保持し、ユニーク制約やインデックスも設定しています。SQLite 運用なので、大規模高並行を前提にした説明は避けつつ、個人開発の一貫した永続化基盤として実装しています。

技術スタック

フロント

Blazor Server(InteractiveServer)

サーバー側状態管理を活かしつつ、フォーム入力やレポート画面を構成。

バックエンド

.NET 8 / ASP.NET Core / Minimal API / HostedService

UI本体と API、非同期処理を同じアプリケーション境界で扱っています。

データベース

Entity Framework Core 8 / SQLite

Migration、1:1 関係、TenantId ベースの分離、各種制約を実装。

認証

ASP.NET Core Identity / Cookie 認証 / Microsoft OpenID Connect

EmailConfirmed、ロックアウト、AdminOnly ポリシーあり。

外部連携

Azure Key Vault / Azure OpenAI / Azure AI Search / Stripe / SignalR / PdfPig

AI、機密情報管理、課金、PDF抽出などを必要範囲で接続しています。

アーキテクチャ / 設計上の工夫

Worker を中核にした処理分離

SourceWorker を HostedService として分離したことで、UIから見える登録処理と、時間のかかる本文抽出・要約処理を分けています。Source の状態遷移を軸にすることで、後から失敗時挙動や再試行戦略を整理しやすい土台になっています。

フォールバックを前提にした AI 接続

Azure OpenAI は ChatClient / EmbeddingClient を利用できる構成ですが、利用不可時は DummySummarizer にフォールバックする実装があります。AI 接続の有無でアプリ全体が起動不能にならないようにしている点は、開発段階でも扱いやすい設計です。

Tenant 単位のデータ分離

TenantId を主要エンティティに持たせ、アプリ利用者とデータ境界を明確にしています。個人開発のアプリでも、後から権限や課金を足すのではなく、最初からテナント単位でまとめる設計に寄せています。

Subscription 制約と利用数コミット

サブスクリプションは Tenant ごとに有効 1 件へ制約し、課金状態を曖昧にしにくくしています。利用数も成功前に先行計上せず、処理完了後にコミットするため、課金と処理成功がずれにくい設計です。現状の課金予約は改善余地がありますが、制約の置き方は明確です。

起動時 migration / seed

起動時に migration と seed を流す仕組みを持たせ、初期管理者や基本データの立ち上がりをコード側で完結させています。開発環境とデプロイ先での初期差分を減らしやすい構成です。

インフラ設定の耐障害性

Azure Key Vault の読み込みに失敗しても起動継続できるようにしており、Managed Identity 優先、API Key フォールバックの実装もあります。Azure App Service 上の SQLite 配置も考慮しており、構成の前提がコードに反映されています。

User Input (URL / PDF) -> Source: Pending -> SourceWorker -> HTML extract or PdfPig text extract -> Text normalize -> Azure OpenAI summarization -> fallback: DummySummarizer -> Save DocumentText / Summary -> Source: Done or Error -> Report page polling -> Tenant-scoped usage / subscription evaluation
現行のレポート更新はポーリング中心です。SignalR は技術スタックに含まれますが、このページでは結果反映を「リアルタイム配信」とは書いていません。

こだわりポイント

単なる要約アプリに寄せていない

IR-Brain の特徴は、ニュースやPDFを要約すること自体ではなく、投資判断に使う情報の並び方まで含めて設計している点です。投資家の観点プリセットを選べること、結果を構造化データとして持つことにより、出力の使い方が最初から具体化されています。

UIの外側まで実装範囲が広い

ポートフォリオではフロントだけが見えやすいですが、このアプリでは Blazor UI の背後に、Minimal API、Identity、Worker、SQLite、Stripe、Key Vault、Tenant 管理まで実装しています。画面を作るだけでなく、アプリとして継続運用できる形に寄せようとしている点を強く出したい制作物です。

課題と今後の改善

まとめ

IR-Brain は、ニュースURLやPDFを入力として、本文抽出、AI要約、構造化レポート表示までをつなぐ Web アプリです。見せたい価値は「要約できます」ではなく、投資判断向けの情報整理を、UI・API・Worker・DB・認証・課金・テナント管理まで含めて一体実装している点にあります。

個人開発の段階でも、処理の流れ、データ境界、権限、課金、失敗時フォールバックまで考慮して組んでいるため、単機能デモではなく、実装力の広さと設計の接続性を見せられる制作物になっています。