PJT推定ロジック
:LiTarget: 用途
タスク名・説明からプロジェクトを自動推定するロジック。
:LiSparkle: 特徴
- キーワードマッチング
- 機械学習
- 手動補正
:LiCode: 実コード(SCALE Base より自動抽出)
:LiInfo:
lib/pjt-infer.tsの中身そのもの。コピペ即可。
// 定例タスク(BottomTask)の PJT を推定する共通ヘルパー
// 1) project フィールドが設定されていれば最優先(projects.id → name 解決、無ければ自由ラベルそのまま)
// 2) 名前から大カテゴリへ自動分類(業務でよく見る集合に寄せる)
// 3) 英字プレフィックス / 漢字プレフィックスで救済
// 4) その他
//
// このロジックは morning/start/routines の3画面で共有する。
import type { BottomTask, Project } from './tasks-api';
export function inferPjt(bt: BottomTask, projects: Project[] = []): string {
// 1. 明示的に project が設定済みなら最優先
if (bt.project) {
const p = projects.find(x => x.id === bt.project);
if (p) return p.name;
// projectsに登録されていない自由ラベルでも、project に直接書かれていればそれを使う
return bt.project;
}
const name = bt.name || '';
// 2. 大カテゴリで分類(優先度順、業務的によく見る集合)
if (name.includes('日報') || name.includes('振り返り') || name.includes('目標') || name.includes('マニュアル')) return '全体';
if (name.includes('採用') || name.includes('スカウト') || name.includes('面談') || name.includes('募集') || name.includes('crowdlinks')) return '採用系';
if (name.includes('請求') || name.includes('経費') || name.includes('売上') || name.includes('振込') || name.includes('パートナー') || name.includes('入金') || name.includes('支払')) return '経理系';
if (name.includes('MTG') || name.includes('ミーティング') || name.includes('会議') || name.includes('アジェンダ') || name.includes('1on1')) return 'MTG系';
if (name.includes('契約') || name.includes('NDA') || name.includes('見積')) return '契約系';
if (name.includes('数値') || name.includes('レポート') || name.includes('集計') || name.includes('分析')) return 'レポート/分析';
if (name.includes('受信トレイ') || name.includes('Slack') || name.includes('メンション')) return 'Slack/受信箱';
if (name.includes('架電') || name.includes('テレアポ') || name.includes('コール')) return 'テレアポ';
// 3. 英字プレフィックス(LinkedIn / X / TERASU / HackCamp 等)
const eng = name.match(/^([A-Za-z][A-Za-z0-9]*)/);
if (eng) return eng[1];
// 4. 先頭の漢字シーケンス(最大4文字)
const ja = name.match(/^([一-龥]{1,4})/);
if (ja) return ja[1];
return 'その他';
}
// グループ化(件数の多い順にソート)
export function groupByPjt(items: BottomTask[], projects: Project[] = []): [string, BottomTask[]][] {
const map: Record<string, BottomTask[]> = {};
items.forEach(it => {
const k = inferPjt(it, projects);
if (!map[k]) map[k] = [];
map[k].push(it);
});
return Object.entries(map).sort((a, b) => b[1].length - a[1].length);
}
:LiFolder: ソースファイルのパス
/Users/oogushiyuuki/Library/CloudStorage/GoogleDrive-y-ogushi@scale-group.co.jp/マイドライブ/AI/scale-base/lib/pjt-infer.ts
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加