実装計画にTask13(社員マスタ504412照合ロジック)を追加
メールアドレス整合性チェック・フリガナ補完の判定/補完ロジックを TDDで実装するタスクを追加。実行タイミング(保存時/定期バッチ/ 手動)は未確定のため、呼び出しトリガーは意図的にスコープ外とし、 決まり次第別タスクとして追加する方針を明記した。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
bee42dc56d
commit
08a0b87dcf
@ -1257,10 +1257,148 @@ git commit -m "feat: 508971にStatusプッシュ通知用クライアントス
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Task 13: employeeMasterCheck.js — 社員マスタ(504412)によるメール整合性チェック・フリガナ補完ロジック
|
||||||
|
|
||||||
|
設計書8章(Bot対話フローとは独立した補助機能)に対応。**実行タイミング(保存時/定期バッチ/手動)はまだ決まっていない**ため、本タスクは判定・補完の純粋ロジックとテストのみを作る。504412へのAPI呼び出しをどこから叩くか(クライアントスクリプト/n8n Schedule Trigger/Process)は、タイミングが決まった時点で別タスクとして追加する。
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `NodeSrv/apps/healthcheck-survey-bot/src/lib/employeeMasterCheck.js`
|
||||||
|
- Test: `NodeSrv/apps/healthcheck-survey-bot/test/employeeMasterCheck.test.js`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: なし(Task 3〜6とは独立)
|
||||||
|
- Produces:
|
||||||
|
- `checkEmailConsistency(pleasanterEmail: string, masterRecord: {Class036?: string, ClassB?: string}): { consistent: boolean, masterEmail: string | null }`
|
||||||
|
- `resolveKanaFromMaster(masterRecord: {Class003?: string, Class004?: string}): string`
|
||||||
|
- `needsKanaFill(currentKana: string | null | undefined): boolean`
|
||||||
|
|
||||||
|
`masterRecord`は504412の`api/items/{id}/get`レスポンスの`ClassHash`(`Class011`=ユーザID、`Class036`=PLメールアドレス、`ClassB`=メールアドレス、`Class003`=姓(カナ)、`Class004`=名(カナ)を含む)を想定する。整合性チェックは`Class036`(PLメールアドレス)を優先し、無ければ`ClassB`にフォールバックする。
|
||||||
|
|
||||||
|
- [ ] **Step 1: 失敗するテストを書く**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// test/employeeMasterCheck.test.js
|
||||||
|
const { test } = require("node:test");
|
||||||
|
const assert = require("node:assert");
|
||||||
|
const {
|
||||||
|
checkEmailConsistency,
|
||||||
|
resolveKanaFromMaster,
|
||||||
|
needsKanaFill,
|
||||||
|
} = require("../src/lib/employeeMasterCheck");
|
||||||
|
|
||||||
|
test("checkEmailConsistency: PLメールアドレス(Class036)と一致すればconsistent:true", () => {
|
||||||
|
const result = checkEmailConsistency("taro.yamada@next-hd.co.jp", {
|
||||||
|
Class036: "taro.yamada@next-hd.co.jp",
|
||||||
|
ClassB: "taro.yamada@example.com",
|
||||||
|
});
|
||||||
|
assert.deepStrictEqual(result, { consistent: true, masterEmail: "taro.yamada@next-hd.co.jp" });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("checkEmailConsistency: Class036が無ければClassBにフォールバックする", () => {
|
||||||
|
const result = checkEmailConsistency("taro.yamada@example.com", {
|
||||||
|
ClassB: "taro.yamada@example.com",
|
||||||
|
});
|
||||||
|
assert.deepStrictEqual(result, { consistent: true, masterEmail: "taro.yamada@example.com" });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("checkEmailConsistency: 不一致ならconsistent:false", () => {
|
||||||
|
const result = checkEmailConsistency("taro.yamada@next-hd.co.jp", {
|
||||||
|
Class036: "different@next-hd.co.jp",
|
||||||
|
});
|
||||||
|
assert.deepStrictEqual(result, { consistent: false, masterEmail: "different@next-hd.co.jp" });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("checkEmailConsistency: マスタ側にメールが無ければmasterEmail:null・consistent:false", () => {
|
||||||
|
const result = checkEmailConsistency("taro.yamada@next-hd.co.jp", {});
|
||||||
|
assert.deepStrictEqual(result, { consistent: false, masterEmail: null });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("resolveKanaFromMaster: 姓カナ+名カナを空白区切りで結合する", () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
resolveKanaFromMaster({ Class003: "ヤマダ", Class004: "タロウ" }),
|
||||||
|
"ヤマダ タロウ"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("resolveKanaFromMaster: 片方欠けていても結合できる", () => {
|
||||||
|
assert.strictEqual(resolveKanaFromMaster({ Class003: "ヤマダ" }), "ヤマダ");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("needsKanaFill: 空文字・未定義はtrue", () => {
|
||||||
|
assert.strictEqual(needsKanaFill(""), true);
|
||||||
|
assert.strictEqual(needsKanaFill(undefined), true);
|
||||||
|
assert.strictEqual(needsKanaFill(null), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("needsKanaFill: 値が入っていればfalse", () => {
|
||||||
|
assert.strictEqual(needsKanaFill("ヤマダ タロウ"), false);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: テストが失敗することを確認**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd "C:\Users\k.nogi\#GitHub\ken_nogi\dev\NodeSrv\apps\healthcheck-survey-bot"
|
||||||
|
node --test test/employeeMasterCheck.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Cannot find module '../src/lib/employeeMasterCheck'`で失敗
|
||||||
|
|
||||||
|
- [ ] **Step 3: 実装を書く**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// src/lib/employeeMasterCheck.js
|
||||||
|
function checkEmailConsistency(pleasanterEmail, masterRecord) {
|
||||||
|
const masterEmail = masterRecord.Class036 || masterRecord.ClassB || null;
|
||||||
|
if (!masterEmail) {
|
||||||
|
return { consistent: false, masterEmail: null };
|
||||||
|
}
|
||||||
|
return { consistent: masterEmail === pleasanterEmail, masterEmail };
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveKanaFromMaster(masterRecord) {
|
||||||
|
return [masterRecord.Class003, masterRecord.Class004].filter(Boolean).join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function needsKanaFill(currentKana) {
|
||||||
|
return currentKana === null || currentKana === undefined || currentKana === "";
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { checkEmailConsistency, resolveKanaFromMaster, needsKanaFill };
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: テストが通ることを確認**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node --test test/employeeMasterCheck.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: 8 tests、全てPASS
|
||||||
|
|
||||||
|
- [ ] **Step 5: 全テストを通しで実行**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node --test test/*.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: 6ファイル・36テスト、全てPASS
|
||||||
|
|
||||||
|
- [ ] **Step 6: コミット**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add src/lib/employeeMasterCheck.js test/employeeMasterCheck.test.js
|
||||||
|
git commit -m "feat: 社員マスタ(504412)照合ロジック(メール整合性チェック・フリガナ補完)を追加"
|
||||||
|
```
|
||||||
|
|
||||||
|
**次に必要な作業(本計画のスコープ外):** 実行タイミングが決まったら、(a) 504412から`Class011`=対象PleasanterUserIdでレコードを取得する呼び出し元(クライアントスクリプト/n8nワークフロー/Process)、(b) 不一致・補完が見つかった場合の通知・自動反映方法、を別タスクとして設計する。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Self-Review
|
## Self-Review
|
||||||
|
|
||||||
**Spec coverage:**
|
**Spec coverage:**
|
||||||
- 全体アーキテクチャ(WP/WA + Process流用)→ Task 9〜11でカバー
|
- 全体アーキテクチャ(WP/WA + Process流用)→ Task 9〜11でカバー
|
||||||
|
- 社員マスタ(504412)連携(設計書8章)→ Task 13でロジックのみカバー。呼び出しトリガーは実行タイミング未確定のため意図的にスコープ外
|
||||||
- Data Table「bot_conversation_state」→ Task 8(実装上は`healthcheck_bot_state`という名前にしたが、設計書の構造要件は満たす。理由: 既存のorg-master-sync用テーブルと並んだ一覧で識別しやすくするため)
|
- Data Table「bot_conversation_state」→ Task 8(実装上は`healthcheck_bot_state`という名前にしたが、設計書の構造要件は満たす。理由: 既存のorg-master-sync用テーブルと並んだ一覧で識別しやすくするため)
|
||||||
- Process定義(ツールチップ・入力検証タブ)→ Task 2(実機調査)・Task 5(ロジック)・Task 9(利用)
|
- Process定義(ツールチップ・入力検証タブ)→ Task 2(実機調査)・Task 5(ロジック)・Task 9(利用)
|
||||||
- 対象者解決(メール=LINEWORKS userId)→ Task 9・11のPleasanter `api/users/get`呼び出し
|
- 対象者解決(メール=LINEWORKS userId)→ Task 9・11のPleasanter `api/users/get`呼び出し
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user