AI Dev Lab
GrantBoard

GrantBoard ができるまで — 使える補助金を条件で絞る

補助金・給付金の一覧ツールの開発ログ。 約 30 制度それぞれに受給条件を判定する式を持たせ、 入力した条件に合うものだけ残す仕組みと、 掲示板に貼り紙を留めたような画面の作り方を記録しています。

·decision改善·stage公開中

GrantBoard は 国 + 自治体 補助金 / 給付金 / 助成金 洗い出し ビューア。 年齢 × 世帯 × 子供数 × 雇用 × 住居 × 所得帯 + 7 ライフイベント (妊娠 / 移住 / 住宅取得 / EV / 太陽光 / 起業 / 障害) から、 約 30 制度の中で 該当しそうなものを 公民館 コルクボード風に表示。 ラボ 43 本目、 データ可視化 ジャンル 4 本目 (wiki-orbit 知識 / astro-cast 天文 / pop-drift 人口 / grant-board 補助金、 「知識 / 天文 / 人口 / 補助金」 4 軸)。

#なぜこの形にしたか

外部 AI 90 案リスト 「¥0 月コスト + PV 巨大」 候補の 6 本目として 案 54 「自治体補助金 洗い出し」 を選定。 マネー計算機 8 本は 「払う / 貯める」 側 (NISA / 住宅 / ふるさと / 副業税 / 育休 / 教育費 / 無駄遣い / 一人暮らし) で、 「もらう側」 のラインが ラボ全体で 唯一存在しなかった。 「補助金 一覧 / 給付金 / 助成金 / もらえる お金 / 申請漏れ」 系の検索意図は 「自分が知らないだけで貰える金があるんじゃ?」 という 強い不安 / 期待で、 通年 巨大需要。 既存大手 (政府 e-Gov / 厚労省 HP / 自治体個別 HP) は 「公式一次情報」 として優秀だが、 縦割り + 個別ページで 「自分に該当する制度」 を 横断的に見るツールが ほぼ存在しない。 純 JS + 静的データテーブルで 完結。

#技術スタック

#30 制度 × eligibility 述語マッチング

ts
interface Eligibility {
 ageMin?: number; ageMax?: number
 needChildren?: boolean
 needPregnant?: boolean
 needMoved?: boolean; needBought?: boolean
 needEv?: boolean; needSolar?: boolean
 needStartup?: boolean; needDisability?: boolean
 needUnemployed?: boolean; needRetired?: boolean
 needLowIncome?: boolean; needSelf?: boolean
}

interface Grant {
 id: string; name: string; category: Category
 amount: string; amountYen: number; oneTime: boolean
 agency: "国" | "都道府県" | "市区町村"
 notes: string; eligibility: Eligibility; url: string
}

各制度に eligibility を持たせ、 eligibilityMatch(grant, userState) で 1 件ずつ judge。 失敗した述語を reason として記録、 「該当しなかった理由」 まで表示。

#11 カテゴリ + 4 色 プッシュピン

ts
const CATEGORY_COLOR = {
 出産育児: "#e88aa0", 子育て: "#d8923a", 教育: "#7a2a2a",
 住宅: "#2d5a8b", 移住: "#2d7d5e", シニア: "#6a4828",
 障害: "#8a5aa8", 起業: "#b8923a", 環境: "#4a8a6a",
 失業医療: "#c63224", 税制: "#4a4a4a",
}

各 note カードの 左 border-left を category color に統一、 ピンは 4 色 (赤/青/緑/黄) を :nth-child(2n/3n/4n) で 循環。

#一時金 / 経常 を分けて合算

ts
const totalYearly = matched.filter((r) => !r.grant.oneTime).reduce((acc, r) => acc + r.grant.amountYen, 0)
const totalOneTime = matched.filter((r) => r.grant.oneTime).reduce((acc, r) => acc + r.grant.amountYen, 0)

「年に 〇〇 万円もらえる」 vs 「ライフイベント 1 回で 〇〇 万円もらえる」 を 別カードで表示。 子育て世帯では 経常 (児童手当 + 子ども医療 + 高校無償化) で 年 30-50 万、 住宅取得時は 一時金 (エコホーム + 住宅ローン減税初年度) で 100-150 万、 のように 性格の違う金が並ぶ。

#不該当理由 表示

ts
if (e.needPregnant && !u.pregnant) fails.push("妊娠中 限定")
if (e.ageMin !== undefined && u.age < e.ageMin) fails.push(`年齢 ${e.ageMin}+ 必要`)
// ...
return { grant, matched: fails.length === 0, reason: fails[0] }

「条件が変われば対象に」 として 不該当リストも 灰色で表示、 「妊娠したらこれが追加」 「移住すればこれが追加」 が一目で見える設計。

#見た目の方針

公民館 コルクボード + プッシュピン + 黄色 受付票 + 蛍光マーカー モチーフ:

  • 配色: cork tan #c8a26a + cork dark #9a7a48 + ivory paper #f6efde + 役所 deep teal #2d4a5a + push-pin 4 色 (red / blue / green / yellow) + 黄色 受付票 #ffe96b + 蛍光ハイライト #fff36b + 朱赤 該当 stamp #c63224
  • モチーフ: 12px cork-deep border + cork texture (5 個の radial-gradient で 砂 / 木目 偽装) + 4 隅 thumb-tack (::before/::after + .boardCornerL/R の 4 つで red/blue/green/yellow 4 色のピン) + bulletin head (teal banner + Instrument Serif italic 「公報」 + 黄色 mono sub label) + 受付票風 yellow chip (1deg rotate + 2px 2px 0 cork shadow) + 付箋 note カード (border-left = category color + 中央上に push-pin + nth-child で rotate -0.4 / 0.5 / -0.25 deg のジッタ + 3px 3px 0 cork shadow + 蛍光マーカー highlight)
  • typography: Space Grotesk 800 (banner display) + JetBrains Mono (numerics / readout) + Instrument Serif italic (公報 / 朱印) + Noto Sans JP body + 漢数字ステップ (壱/弐/参)

既存 42 本と完全別軸 (データ可視化 3 本 = wiki-orbit 古地図 / astro-cast 天文台 / pop-drift Risograph 統計年鑑 とは 配色 + モチーフ 完全別、 SoloRoost kraft 段ボール と cork brown は色相が近いが モチーフ (引越し vs 公民館) と 構造 (cross-stripe マステ vs cork radial + thumb-tack) で別、 唯一の 「公民館 コルクボード + 4 色 thumb-tack」 モチーフ)。

#8 プリセット

  • 20 代 単身 / 賃貸 / 中所得
  • 新婚 + 妊娠中 / 賃貸
  • 子育て 30 代 / 子 2 / 中所得
  • 住宅取得 + EV + 太陽光 / 子 1
  • 地方移住 + 起業 / 単身
  • ひとり親 / 子 1 / 低所得
  • シニア 退職後 / 夫婦 / 低所得
  • 学生 19 歳 / 低所得

#まだやっていないこと

  • 47 都道府県 + 主要市区 プルダウンで 「自治体独自制度」 も拡充 (家賃補助 / 移住支援 / 太陽光 補助 等)
  • 申請期限 アラート (年度内 / 数ヶ月以内 の制度を 朱赤 帯で)
  • 正確な所得制限 計算 (児童扶養手当 / 修学支援 / 高校無償化 等の所得テーブル)
  • 公式 HP ディープリンク (現在は所管省庁トップへの暫定リンク)
  • チェックリスト印刷 (該当制度を CSV / PDF で 役所窓口 持参用)
  • クロス導線 (Linked from StorkCast / GradFund / SoloRoost / RoofFund に 「対応する補助金は GrantBoard で」 リンク)

[ ./next_action ]

読んだら、 GrantBoard を実際に動かす。

この開発ログは GrantBoard をどう作ったかの記録です。 読み終わったらそのままサービス本体へ戻って、 実物で価値を確かめてください。

[ ./related_logs ]

関連する開発ログ

all logs →
ToonCast

ToonCast ができるまで — AnimeGANv2 をブラウザで動かす

AnimeGANv2 の小さな ONNX (約9MB) を onnxruntime-web (単一スレッド WASM=COOP/COEP不要、 color-revive で承認済みライブラリの再利用) で実行。 512x512・[-1,1] 正規化で推論し、 結果を元解像度に戻して表示する設計記録。 写真は端末内処理。

read log →
ColorRevive

ColorRevive ができるまで — onnxruntime-web で白黒写真をカラー化

DeOldify の量子化 ONNX を onnxruntime-web (CDN side-load・単一スレッド WASM=COOP/COEP不要) で実行。 256x256 でモデル推論し、 輝度は元写真・色だけ AI を YCbCr で再合成して輪郭を保つ設計記録。 写真は端末内処理。

read log →
PhotoTwin

PhotoTwin ができるまで — CLIP画像埋め込みで似た写真を見つける

CLIP (Xenova/clip-vit-base-patch32) の image-feature-extraction を transformers.js の CDN ESM で side-load し、 各写真を正規化ベクトル化。 cosine 類似度で重複・似た写真をブラウザ内で検出する設計記録 (新ライブラリ追加なし=what-cam と同じ CLIP の再利用)。

read log →
AkinFind

AkinFind ができるまで — ブラウザ内で完結する embeddings 意味検索

多言語の文章埋め込みモデル (Xenova/multilingual-e5-small) を transformers.js の CDN ESM で side-load し、 各文を正規化ベクトル化。 cosine 類似度で意味検索と似ている文ペア検出を全て端末内で行う設計記録。

read log →
WhatCam

WhatCam ができるまで — CLIP のゼロショット画像分類をブラウザで動かす

CLIP (Xenova/clip-vit-base-patch32) を transformers.js の CDN ESM で side-load し、 写真と候補ラベルの近さをブラウザ内で計算。 日本語ラベルを英語プロンプトに変換し、 図鑑と自由入力の両モードで「これ何?」を判定する設計記録。

read log →
DepthCast

DepthCast ができるまで — 1枚の写真をAIの深度推定で立体にする

Depth Anything (transformers.js) を CDN ESM で side-load し、 1枚の写真から深度マップを推定。 WebGL2 フラグメントシェーダで深度に比例した視差 (iterative backward parallax) を作り、 赤青アナグリフ / WebM 書き出しまで端末内で完結させた設計記録。

read log →