Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
「案件の空き」と「人材リソース」をAIで自動マッチングするシステム。 ログイン不要・ニックネーム制・即日利用可能。Read the full README ↗
「案件の空き」と「人材リソース」をAIで自動マッチングするシステム。
ログイン不要・ニックネーム制・即日利用可能。
| 機能 | 説明 |
|---|---|
| マッチング | 案件と人材の相性スコアを算出。スコアは SQL 側のルール計算で完結(fetch_candidates_for_project RPC・スキル40/経験15/単価15/勤務地20/リモート10)。手動 (match-score) / バッチ (match-batch) / 自動 cron (auto-match) の 3 経路。上位のみ外部 AI で再採点する経路も実装されているが現在は使っていない(→ 下記「マッチングのスコアリング」) |
| 人材登録 | テキスト貼り付け・Excel・Word をアップロードするだけで自動解析・登録(PDF / 画像は現状未対応)。HTML テーブル形式メール / [氏名] ラベル / [氏名]男性:51 歳 等の混入パターンに対応 |
| 案件登録 | 同上。メール本文や要件定義書をそのまま貼り付け OK。【場所】【単価】【時期】【備考】等のブラケット形式・単金(税抜) 括弧付きラベル・■PR セクション・希望ラベルに対応 |
| メール自動取り込み | 専用 Outlook アドレスを 5 分ごとにポーリング → 取得 → DB 保存(AI 不使用・ルールベース)。営業/広告メール(メール配信解除・研修販売等)は自動スキップ |
| 人材マップ | 「人材」タブ内のサブ画面で日本地図上の都道府県別ヒートマップ表示。スキルフィルター(RPC 経由)・直近 7 日 / 全期間切替・都道府県クリックで受信メール一覧・都道府県クリックで地図ズームアニメーション |
| 改善案・バグメモ → GitHub Issue | 設定タブで自然文を貼り付けると、create-github-issue Edge Function 経由で GitHub Issue として自動登録。一覧表示・クローズ(PATCH)も同 UI から可能 |
| スコアウェイトのカスタムチューニング | match-batch / fetch_candidates_for_project の 5 観点(スキル / 経験 / 単価 / 勤務地 / リモート)のウェイトを実行時に変更可能(既定: 40/15/15/20/10 = 100pt) |
| スキル別経験年数の活用 | Excel スキルシートから skillYears を抽出し、必須スキルの実年数をスコアリングに反映(総経験年数より優先) |
| 人材ウォッチ通知 | 「通知」タブで条件(名前 / スキル / 最寄駅)を登録すると、合致する人材の登録時にメールで通知(notify-candidates cron・5分)。種類違いは AND、スキル欄の中だけ OR。スキルは語として照合(Java は JavaScript に一致しない) |
| AI による項目補正(社内PC) | Claude Code を使う常駐ワーカーが、新規人材の氏名・年数・スキル年数を読み直し、新規案件の抜けを埋め、提案ごとの所見を書く。マッチングの点数計算とは別系統 |
| 同一人材の検出 | 別の紹介会社から来た同じ人を検出して人材詳細に並べる(統合はしない。会社ごとに提示単価が違うため比較できるようにする) |
| 表示優先スキル | 一覧をどのスキルの人から読むかを設定できる。既定は全体設定、絞り込みから端末ごとに上書きでき、ブラウザに記憶される |
| デモ環境 | 本番データとは独立したデモ用データ環境(?demo=KEY でトグル + 設定タブの「デモモード」スイッチ)。本番→デモコピー・スコア別 5 人生成。デモ案件のリモートポリシーを考慮したスコア設計 |
flowchart TD
A[営業担当者<br/>ブラウザ] -->|テキスト・ファイル入力| B[React フロントエンド<br/>Vercel]
B -->|登録/再解析<br/>force=true| H[Edge Function<br/>inbound-email<br/>※ AI 不使用]
H -->|upsert| D[(Supabase<br/>PostgreSQL)]
B -->|upsert / fetch| D
B -->|手動マッチ要求| MS[Edge Function<br/>match-score<br/>単発スコア + duplicate判定]
B -->|高速/全件マッチ| MB[Edge Function<br/>match-batch<br/>ウェイト調整 + バッチ AI 採点]
B -->|SQL側で<br/>ルールスコア算出 + 上位500件取得| RPC[(RPC<br/>fetch_candidates_for_project<br/>p_weight_skill/exp/rate/location/remote)]
RPC --> D
MS -.->|AI再採点は現在未使用<br/>キー未設定なら ruleScore| AI[外部AIプロバイダ<br/>※未稼働]
MB -.->|AI再採点は現在未使用<br/>キー未設定なら ruleScore| AI
MS -->|upsert submissions| D
MB -->|upsert submissions<br/>ai_raw.ruleScore も保存| D
E[Outlook<br/>専用アカウント×4] -->|未読メール監視| F[pg_cron<br/>5分ごと起動]
F -->|HTTP POST| G[Edge Function<br/>poll-email]
G -->|OAuthトークン取得| M[Microsoft Graph API]
M -->|未読メール最大50件/アカウント| G
G -.->|メール種別分類<br/>Gemini バッチ| CLS[Gemini Flash Lite]
G -->|内部 POST| H
H -->|Drive/Sheets URL検出→fetch| I[Google Drive<br/>共有リンク]
H -->|デプロイ物に同梱した<br/>station_data.json を参照<br/>8,443駅名・実行時DB往復ゼロ| SM[station_data.json<br/>駅名+路線 → 都道府県]
H -->|skill_master DB照合<br/>+ regex + 文章スキャン<br/>+ HTML エンティティデコード| H
CR[pg_cron<br/>毎朝 JST 9:00] -->|HTTP POST| AM[Edge Function<br/>auto-match]
AM -->|match-batch を内部呼び出し| MB
AM -->|insert submissions| D
CR2[pg_cron<br/>毎日 JST 0:00] -->|HTTP POST| AR[Edge Function<br/>archive-candidates]
AR -->|7日以上経過した prod 人材を<br/>サマリー化してから削除| D
AR -->|prefecture/skills/name/subject 保存| AL[(candidates_archive_light<br/>軽量サマリーテーブル)]
B -->|人材マップ表示<br/>※「人材」タブ内サブ画面| HP[HeatmapPage<br/>d3-geo + japan.topojson<br/>都道府県ズームアニメ]
HP -->|prefecture_counts RPC<br/>candidates_by_prefecture RPC| D
HP -->|全期間モード時に合算| AL
B -->|改善案・バグメモ| GHI[Edge Function<br/>create-github-issue]
GHI -->|POST/GET/PATCH| GH[GitHub Issues API]
| レイヤー | 技術 |
|---|---|
| フロントエンド | React 19, Vite 8, TypeScript, Tailwind CSS v4, TanStack Query v5 |
| DB / バックエンド | Supabase(PostgreSQL, Edge Functions, pg_cron, pg_net) |
| AI(ブラウザ) | 未使用(Phase 4.11 で「AI で登録」廃止。VITE_GEMINI_* は設定不要) |
| マッチングのスコア | match-batch / match-score / auto-match。SQL 側のルール計算(スキル40/経験15/単価15/勤務地20/リモート10 = 100pt)。上位のみ外部 AI で再採点する経路も実装されているが現在は未使用(→「マッチングのスコアリング」) |
| メール種別分類 | poll-email の同一受信箱判別(任意・既定は無効) |
| メール解析 | AI 不使用。regex(extractCandidateFieldsRegex + flexLabel) + 文章スキャン(extractFromProse) + skill_master 照合 + station_master 照合(8,443 駅名。デプロイ物に同梱した station_data.json を読むので実行時の DB 往復はゼロ)。HTML テーブル形式メール・複数人材分割・送信者署名除去・営業/広告メールフィルタにも対応 |
| AI(社内PC・人材/案件の読み取り) | Claude Code(claude -p)。社内PCで常駐する scripts/llm_extract/shadow_worker.mjs が5分ごとに、新規人材の項目補正・新規案件の項目補完・マッチング提案の所見生成・Box 経歴書の取込を行う。マッチングの点数計算とは別物(点数はルール計算)。現在このシステムで実際に使っている唯一の AI。セットアップは docs/HandsOn_Setup.md 第1章・第8章 |
| ファイル解析 | xlsx(Excel)・mammoth(Word)。PDF と画像はテキスト解析対象外。Excel から skillYears(スキル別経験月数)を抽出してマッチングに活用 |
| 人材マップ | d3-geo(Mercator 投影) + topojson-client + public/japan.topojson(416KB・47 都道府県)。prefecture_counts / candidates_by_prefecture RPC で SQL 集計(スキルフィルタも RPC 側)。都道府県クリックでズームアニメーション |
| メール自動受信 | Microsoft Graph API + Supabase pg_cron(完全無料・Make.com 不要) |
| データアーカイブ | archive-candidates Edge Function(毎日 JST 0:00 cron)。7 日経過した prod 人材を candidates_archive_light にサマリー化してから DB 削除(人材マップ全期間集計用・Storage 書き込みは廃止) |
| Issue 連携 | create-github-issue Edge Function(POST 作成 / GET 一覧 / PATCH クローズ)。設定タブの「改善案・バグメモ」から自然文を貼り付けて GitHub Issues に登録 |
| Edge Function デプロイ事前検査 |
スコアは外部 AI を使わず、SQL 側のルール計算で出している。
| 観点 | 既定ウェイト |
|---|---|
| スキル一致 | 40 |
| 勤務地 | 20 |
| 経験年数 | 15 |
| 単価 | 15 |
| リモート可否 | 10 |
match-batch には「ルールで上位に来た候補だけ外部 AI に再採点させる」経路(Cerebras → Groq → Gemini の 3 段)が実装されているが、現在は稼働していない。
API キーが未設定なら 3 段とも失敗し、ai?.score ?? c.ruleScore で全件がルールスコアのまま返る。実測(ai_logs・直近 30 日):
This is the beginning of the README. Read the rest at the original. Read the full README ↗
scripts/check-and-deploy-edge.sh(deno check で TS2304 を検知 → デプロイ中止) |
| デプロイ | Vercel(フロント・tsc 型チェックは Vercel ビルドから除外して高速化)/ Supabase(バックエンド) |
| テスト | Vitest, React Testing Library, MSW + scripts/verify_email_extraction.mjs(メール抽出リグレッション) |