🏗️

第一幕:Creators Dashboard を作る — サービス設計とシステム構成

に公開

この記事について

AI対話ログと実験記録をもとに Claude Code が下書きを作成し、私が加筆修正しました。
最初にサービスの紹介を少しだけさせていただき、その後は技術スタックと設計判断の話に入ります。個人開発の PoC フェーズにおける判断なので一般最適ではありませんが、似たようなサービスを作られる方の参考のひとつになれば幸いです。

前回の連載(第四部)では、初めての iOS アプリを企画からリリースまで作り切りました。

34日間・全六幕の舞台を振り返る

今回から新しい連載(第七部・全五幕予定)が始まります。テーマは Web サービス。個人開発者のプロジェクト情報を集約するダッシュボードを、DB を持たず YAML だけで動かす話です。[1]


はじめに

やること

  • Creators Dashboard のコンセプトと設計思想を紹介する
  • DB を使わず YAML 駆動で動かす判断の背景を説明する
  • GitHub からブラウザまでのシステム構成図を示す
  • 技術スタックの全体像を紹介する

やらないこと

  • 各技術要素の実装詳細- Backstage そのものの解説
  • デプロイ手順やチュートリアル

「個人開発者のポートフォリオ」が欲しかった

個人開発を続けていると、こうなります。

  • 作ったものは増えていく
  • でも「今どれが動いているか」は自分でも分からなくなる
  • どれも途中なのに、その途中経過がどこにも残らない

プロジェクトの「今、これから」を横断・一覧で見られる場所がない。

GitHub Profile はリポジトリの一覧であって、プロダクトの現在地を見せる場所ではありません。個人サイトを作ってもメンテナンスが続かない。X に投稿しても流れていく。

イラストレーターには pixiv がある。映像クリエイターには YouTube がある。ソフトウェア開発者にはそれに相当するものを見つけることができませんでした。であれば、Web サイト構築の勉強も兼ねて自分で作り、PoC として公開してみよう — そう思ったのが出発点です。

Creators Dashboard は、開発者が GitHub リポジトリに YAML ファイルを1つ置くだけで、プロジェクトがカード形式で掲載されるサービスです。フォローしなくても、気になるプロジェクトの「今」と「次」がいつでも見える場所。

現在 2026年6月末までの期間限定で PoC を公開中です。外部ユーザーはまだいません。個人開発をされている方で、ご自身のプロジェクトを掲載してみたいという方がいらっしゃれば、ぜひ覗いてみてください。掲載方法は使い方ガイドをご覧ください。

Creators Dashboard
https://creators-dashboard.devour.jp

サービスの紹介はここまでです。ここからは、これをどう作ったのか — 具体的な設計判断と技術スタックの話に入ります。


システム概要

GitHub にある YAML を、ローカルサーバー(wk-02)がパイプラインで取得・検証し、正規化した JSON を Vercel に配置。Vercel はそれを読んで HTML を返す。この3者の流れが全体像です。


システム構成 — 各レイヤーの詳細

上の概要図をもう少し詳しく見ていきます。

ポイントは 書き込みと読み取りの分離 です。

  • 書き込み: wk-02(ローカルネットワーク内、外部からアクセス不可)
  • 読み取り: Vercel(グローバル配信、GET のみ)
  • 中継: Vercel Blob(トークン認証で書き込みを保護)

パイプライン(job1024)が GitHub から YAML を取得し、バリデーションと安全性チェックを経て、正規化した JSON を Vercel Blob に配置する。Hono サーバーはその JSON を読んで HTML を返すだけ。

当初の狙いは「出面はクラウド、裏面は手元」という分離でした。

ユーザーが触れるフロントエンドは Vercel に任せる。データの収集・加工・検証はローカルサーバー(wk-02)に置く。こうすることで、裏面のバッチ処理が特定のクラウドプラットフォームにロックされません。将来 Vercel 以外に移行したくなっても、変更するのは配置先だけで済みます。

出面の安全対策 — DDoS 対策、HTTPS 終端、エッジキャッシュ — はプロであるクラウドサービスに任せた方が安心できる、というのも理由のひとつです。

副次的な効果として、開発環境と運用環境がほぼ同一になりました。クラウドでバッチ処理を動かすとスケジュール実行やコンピューティングのコストが発生しますが、手元のマシンで cron を回すだけならその負担はありません。PoC フェーズではこの構成で十分です。

パイプラインが担う安全対策

「誰でも YAML を置ける」設計には、安全対策が欠かせません。パイプラインは以下を処理します。

対策 処理内容
スキーマバリデーション 必須フィールド・型チェック
Cloud Vision SafeSearch 画像の不適切コンテンツ検出
Safe Browsing API URL の脅威判定
ドメインホワイトリスト リンク先を GitHub / App Store 等に制限
postId 数字制限 X 投稿 ID に悪意ある文字列が入るのを防止
NG ワードフィルタ 正規表現による確定的なテキスト検証
SLM テキスト検証 ローカル SLM による文脈を考慮した品質チェック

API バジェットキャップ

外部 API にはそれぞれ異なるレート制限・課金体系があります。統一された ApiBudget クラスで一元管理し、上限の 80% でアラート通知、90% で自動停止する実装にする予定です。

API 上限 期間 コスト
GitHub API 4,000 req 時間 無料(認証ユーザー)
X API 100 req 日次 有料プラン(月額固定)
Safe Browsing API 8,000 req 日次 無料
Cloud Vision SafeSearch 900 req 月次 〜$0.45/月

Cloud Vision の月次 900 件が最もタイトなボトルネックです。同一画像の再チェックをキャッシュ(SHA256)で回避し、HEAD リクエストで画像かどうかを事前判定することで、実際の消費を抑えています。

パイプラインの詳細は第二幕で掘り下げます。


なぜ DB を使わないのか

結論を先に書きます。Creators Dashboard にデータベースはありません。

プロジェクト情報の入力は YAML、内部処理は JSON、表示は SSR の HTML。DB が登場する余地がない設計にしました。

catalog-info.yaml を借りる

入力フォーマットには Backstage(CNCF のデベロッパーポータル)の catalog-info.yaml を採用しました。

catalog-info.yaml の例(クリックで展開)
apiVersion: devour.jp/v1alpha1
kind: Component
metadata:
  name: "kokosuki"
  description:
    short: "好きな場所の記録アプリ"
    long: "日常の中で見つけた「ここが好き」を記録する\niOS / Android アプリ"
  tags: ["unity", "ios", "android"]
  links:
    - url: https://github.com/example/kokosuki
      title: GitHub
    - url: https://apps.apple.com/app/id123456
      title: App Store
spec:
  type: game
  lifecycle: production
  owner: "devour-jp"
  devour:
    image: "https://example.com/hero.png"
    release:
      current:
        version: "v1.0.0"
        date: "2026-03-14"
        headline:
          short: "iOS リリース"
    social:
      x:
        account: "DEVOUR_JP"

Backstage の標準フィールド(metadata, spec.type, spec.lifecycle)はそのまま使い、独自の拡張は spec.devour に集約しています。spec.devour を無視すれば、標準的な Backstage カタログとしても機能します。

既存のスキーマを借りることで、設計のショートカットができました。フィールド名の命名で悩む時間が減り、将来のエコシステム接続の余地も残せます。

YAML → JSON の2層構造

掲載者が書くのは YAML。サーバーが読むのは JSON。この分離が設計の要です。

形式 誰が使うか
入力 YAML(catalog-info.yaml) 掲載者(人間が読み書きしやすい)
内部 JSON(v2.json) サーバー(JSON.parse() 一発)

サーバーに YAML パーサーを持たせない。責務を分離して、Hono サーバーは JSON を読んで表示するだけにする。この判断で構成がシンプルになりました。

DB を入れない理由は「不要だから」です。トランザクションは要らない。複雑なクエリも要らない。JSON ファイルで十分なうちは、JSON ファイルで動かす。スケールが必要になったら、その時に考えます。


技術スタック

ここから先は今後の幕で詳細を紹介する可能性がありますが、まず頭出しとして現在の構成を一覧にします。

フロントエンド・バックエンド

レイヤー 技術
FE/BE フレームワーク Hono(JSX + SSR)
言語 TypeScript
ランタイム Node.js(Vercel)
画像生成 satori + @resvg/resvg-js

Hono を選んだのは、SSR と API を同一フレームワークで扱えるからです。React は使っていません。Hono の JSX で HTML を組み立て、サーバーサイドでレンダリングしています。

インフラ

機能 サービス
ホスティング Vercel(Edge / Serverless)
ストレージ Vercel Blob
DNS お名前.com(CNAME → Vercel)
データ収集 job1024(wk-02 cron)
X 連携 X API v2

当初は Cloudflare を検討していましたが、独自ドメインの利用に DNS 管理の移行が必要だったため、既存の DNS 設定を変えずに CNAME 追加だけで済む Vercel を選択しました。

安全対策

対策 提供元
画像チェック Cloud Vision SafeSearch
URL チェック Safe Browsing API
NG ワードフィルタ 正規表現による確定的なテキスト検証
SLM テキスト検証 ローカル SLM による文脈を考慮した品質チェック
XSS 防御 入口・中間・出口の3層バリデーション
CSP Content Security Policy ヘッダー

安全対策については AI の力を借りながら、自分の知識で検討・実装しました。まだまだ不足している部分はあると思いますが、今後経験を積みながら拡充していきたいと考えています。

外部サイトによるスコア

以下は 2026/03/28 時点の計測結果です。

セキュリティヘッダー

検証ツール スコア
Mozilla HTTP Observatory A+
Security Headers A+

PageSpeed Insights

指標 携帯電話 デスクトップ
パフォーマンス 88 98
ユーザー補助 95 92
おすすめの方法 100 100
SEO 100 100

URL 設計

現在実装されているパスの全体像です。

パス 用途
/ トップ(カード一覧、24件/ページ)
/org/:name 開発者ポートフォリオ
/share/embed/card/:owner/:repo.png OGP カード画像(1200×630)
/share/embed/badge/:owner/:repo.svg バッジ画像(shields.io 風)
/how-to-use 使い方ガイド
/create-yaml catalog-info.yaml 作成ツール
/terms, /privacy, /about, /licenses 法務・情報ページ

将来の API 拡張に備えて /api/(内部)と /share/api/(外部)のパスを予約していますが、PoC フェーズでは未実装です。サブドメイン分離は現時点ではオーバーエンジニアリングと判断し、パスベースで始めています。


まとめ

この記事では、Creators Dashboard のサービス設計とシステム構成の全体像を紹介しました。

  • コンセプト: 個人開発者が YAML を1つ置くだけでプロジェクトが掲載される
  • DB なし: YAML → JSON の2層構造で、Hono サーバーは JSON を読んで返すだけ
  • 構成: GitHub → パイプライン(wk-02)→ Vercel Blob → Hono SSR → ブラウザ
  • 安全対策: パイプラインが SafeSearch / Safe Browsing / バリデーションを一括処理

この先に残った課題

全体像はこれで見えました。ここからは個別の技術的な判断に入ります。

第二幕 では、パイプライン(job1024)の中身を掘り下げます。GitHub API の差分取得、Cloud Vision SafeSearch と Safe Browsing API のバジェット管理、そして SLM を使ったテキスト品質チェック。「信頼できるデータを自動で作る」ための仕組みの話です。


上演目録(docs × AI による開発記録)

※本シリーズでは、試行錯誤のプロセスを「上演」に見立て、進行単位を「幕」として記述します。

第七部:Creators Dashboard を作る(全五幕予定)

  • 第一幕:サービス設計とシステム構成 ← いまここ
  • 第二幕:fetch パイプライン — SLM × 外部 API で安全なデータを作る
  • 第三幕:X/Twitter 投稿埋め込みの三度の転換
  • 第四幕:DOM XSS 3層防御のセキュリティ設計
  • 第五幕:Vercel Blob 帯域制約下の動的画像生成

第一部:docs × AI(全五章)

第二部:対話ログの整理(全六幕 + 幕間)

第三部:ワークフローとタスク管理(全四幕)

第四部:初めてのアプリを作る(全六幕 + カーテンコール)

第五部:SLM パイプラインのその後(全三幕)

第六部:SLM を本番で使い倒す(幕数未定)

第一部:docs × AI(全五章)


作成日: 2026-03-28
生成元: pg10 docs/design.md, docs/architecture.md, AI 対話サマリ 2026-03-26〜28(3セッション分)

記事作成プロセス

  • プロット作成: Claude Code(素材調査 + 構成案)
  • 初期作成: Claude Code
  • 初回レビュー: 私
  • 添削: ChatGPT
  • 投稿前: 未実施
  • 投稿後レビュー: NotebookLM

※ pg10 の設計ドキュメントと、3/26〜28 の AI 対話サマリ 3 セッション分を素材として使用

脚注
  1. 2026/03/28 時点の構成です。将来 DB による運用が必要になれば対応を行う予定です。 ↩︎

Discussion