docs(org-master-sync): n8n production移行の設計メモを追加
模倣(Mock)Users/Depts/Groupsテーブルの設計意図と実態乖離、
staging/production分離、config値修正、①③④④-1④-2④-3の
標準API化(models/groups/{id}/update等の実機検証結果込み)を記録。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
8e8bbcde6e
commit
5abf932fa6
@ -0,0 +1,123 @@
|
|||||||
|
# org-master-sync n8n production移行 設計メモ
|
||||||
|
|
||||||
|
2026-09-04〜進行中。org-syncのn8nワークフロー群をproduction(本番プリザンター `nextoffice.next-hd.co.jp`)向けに構築する作業の設計意図・進捗記録。適宜追記していく。
|
||||||
|
|
||||||
|
## 1. 背景: 「模倣(Mock)テーブル」の設計意図
|
||||||
|
|
||||||
|
n8nの`org-sync`系ワークフロー(①③④④-1④-2④-3)は、Pleasanter標準のUsers/Depts/Groups API(`/api/users/get`等)ではなく、staging環境に用意した「模倣テーブル」(SiteId 504737=ユーザー, 504736=組織, 504738=グループ、いずれも`ReferenceType: Results`の通常テーブル)を参照して構築されていた。
|
||||||
|
|
||||||
|
**意図(本人確認、2026-09-05)**: 開発当時は本番データを直接いじれなかったため、模倣テーブルでフロー構築を先に進め、「宛先(SiteId/BASE_URL)を変更するだけで本番化できる」ことを狙った設計だった。
|
||||||
|
|
||||||
|
**判明した実態(2026-09-05調査)**: この狙いは実現できていなかった。
|
||||||
|
- 模倣テーブルはPleasanterのitems/export形式(表示名キーのJSON/CSV、例: `ログインID`, `組織`)を返すが、本物の標準API(`/api/users/get`, `/api/depts/get`, `/api/groups/get`)はシステムフィールド名(`UserId`/`LoginId`/`DeptId`/`GroupId`等)+Offset/TotalCountページング必須という全く別の形式。「宛先を変えるだけ」では動かず、レスポンス変換層の追加が必要だった
|
||||||
|
- LWグループマッピングテーブル(SiteId 504411、66件: 組織48・役職8・職級6・利用権限タイプ4)の「グループID(」列は模倣Groupsテーブル内の独自連番(1〜135+)で、本物のPleasanter Groups(GroupId実在範囲5〜69、全59件)とは無関係。名前での突合でも一致0件=本物のGroupsには1件も対応物が無い
|
||||||
|
|
||||||
|
## 2. n8nワークフロー構成(2026-09-04時点で判明した正式版一覧)
|
||||||
|
|
||||||
|
Proto系(`org-master-sync prototype`フォルダに格納済み、検証用として維持、変更しない)とは別に、正式版として以下が存在:
|
||||||
|
|
||||||
|
| ワークフロー | ID |
|
||||||
|
|---|---|
|
||||||
|
| org-sync: ① LINEWORKSマスタ→プリザンターマスタ情報更新 | pJBj07V5p4Av8f6E |
|
||||||
|
| org-sync: ② バックアップ | HuKpZQEQeU4iUCUf |
|
||||||
|
| org-sync: ③ マージマスターメイン処理 | ScoUpIshCsdO2KdI |
|
||||||
|
| org-sync: ④ プリザンターマスタ更新(④-0〜④-3の統合版) | 82y3S515PbEBLSDv |
|
||||||
|
| org-sync: ④-0 状態判定 | UQ7vtaajy9O93jhW |
|
||||||
|
| org-sync: ④-1 新規ユーザー作成 | 6NwZXgXY2eK1Wt4g |
|
||||||
|
| org-sync: ④-2 ユーザー更新・退職処理 | I9NimeonT8rM51KW |
|
||||||
|
| org-sync: ④-3 グループ更新 | QPt4JRHOgSuN0nnS |
|
||||||
|
|
||||||
|
## 3. staging/production分離(2026-09-04実施)
|
||||||
|
|
||||||
|
上記8本を複製し、`org-sync: staging: ...`(既存の8本をリネーム)と`org-sync: production: ...`(新規複製8本)に分離。
|
||||||
|
|
||||||
|
- production版はdataTable取得ノードのconfigKeyを`_TEST`→`_PROD`へ全置換(④-0〜④-3内の「設定値統合」Codeノードにハードコードされてた`_TEST`参照も含む)
|
||||||
|
- production版のWebhookパスは全部`-prod`サフィックスで一意化(例: `org-sync-01-lw-master-update-prod`)
|
||||||
|
- production版8本は全部`active: false`(未有効化)で作成。**稼働テストは今回のスコープ外、明示許可があるまで有効化しない**
|
||||||
|
- フォルダ構成: `org-master-sync`(production版8本)/ `org-master-sync staging`(staging版8本)/ `org-master-sync prototype`(Proto系旧版15本)/ `LINEWORKS`(通知系2本)
|
||||||
|
|
||||||
|
## 4. `workflow_config_values`(n8n Data Table)のPROD値修正
|
||||||
|
|
||||||
|
旧`_PROD`値(`PLEASANTER_MASTER_SITE_ID_PROD=502552`等)はいずれも404で存在しない廃止済みSiteIdだった。TESTが既に`504406〜504412`系列を使っていたのに対応させ、以下へ更新(2026-09-04、UI手動編集で完了):
|
||||||
|
|
||||||
|
| キー | 更新後の値 |
|
||||||
|
|---|---|
|
||||||
|
| PLEASANTER_MASTER_SITE_ID_PROD | 504412(社員・組織マスタ管理テーブル) |
|
||||||
|
| PLEASANTER_POSITION_MASTER_SITE_ID_PROD | 504408(LINEWORKS:役職マスタ) |
|
||||||
|
| PLEASANTER_LEVEL_MASTER_SITE_ID_PROD | 504410(LINEWORKS:職級マスタ) |
|
||||||
|
| PLEASANTER_USERTYPE_MASTER_SITE_ID_PROD | 504409(LINEWORKS:利用権限マスタ) |
|
||||||
|
| PLEASANTER_BACKUP_SITE_ID_PROD | 504407(社員・組織マスタ管理(副・バックアップ用)) |
|
||||||
|
| PLEASANTER_LW_GROUP_MAP_SITE_ID_PROD | 504411(LWグループマッピング、新規追加) |
|
||||||
|
|
||||||
|
n8n Data Table Public APIは行のupdate/delete専用エンドポイントが存在しない(PATCH/PUT/DELETEいずれも404か405、POSTのみ実装)。UI側の値セルはダブルクリックで編集・削除可能と判明(削除もUIから実施できた)。
|
||||||
|
|
||||||
|
## 5. 模倣テーブル→本物API移行の対応状況
|
||||||
|
|
||||||
|
| ワークフロー | 参照する模倣テーブル | 対応状況 |
|
||||||
|
|---|---|---|
|
||||||
|
| ③ マージマスターメイン処理(production版のみ) | Users(504737), Depts(504736) | **完了(2026-09-05)**。下記5-1参照 |
|
||||||
|
| ① LINEWORKSマスタ→プリザンターマスタ情報更新(production版のみ) | Groups(504738) | **完了(2026-09-05)**。下記5-2参照 |
|
||||||
|
| ④ プリザンターマスタ更新(統合版) | Users, Depts, Groups全部 | **完了(2026-09-05)**。下記5-3参照 |
|
||||||
|
| ④-1 新規ユーザー作成 | Depts, Groups, Users(create先も504737) | **完了(2026-09-05)**。下記5-4参照 |
|
||||||
|
| ④-2 ユーザー更新・退職処理 | Depts, Users, Groups | **完了(2026-09-05)**。下記5-4参照 |
|
||||||
|
| ④-3 グループ更新 | Groups | **完了(2026-09-05)**。下記5-4参照 |
|
||||||
|
|
||||||
|
これで①②③④④-0④-1④-2④-3、production版8本すべての模倣テーブル参照が解消された。
|
||||||
|
|
||||||
|
### 5-1. ③の対応内容(production版のみ、staging版は変更していない)
|
||||||
|
|
||||||
|
- `プリザンターUsers取得`ノード: `POST items/504737/export` → `POST api/users/get`(`View:{ApiGetMailAddresses:true}`付き、Offset+TotalCountページング設定済み)
|
||||||
|
- `プリザンターDepts取得`ノード: `POST items/504736/export` → `POST api/depts/get`(同上ページング設定)
|
||||||
|
- 「マージ計算」Codeノード: 標準APIの生データ(`UserId`/`LoginId`/`DeptId`等)を、旧・模倣テーブルと同じキー名(`ユーザID`/`ログインID`/`組織`等)の中間形式へ変換する処理を先頭に追加。`組織`は`DeptId`から`プリザンターDepts取得`の結果で逆引き(`deptIdToName`マップ)。これにより後続のマージ判定ロジック(`pleasanterUserToFields`等)は無改造で流用できている
|
||||||
|
- `SecretKey`・`Manager`は本番データ上使用者ゼロを確認済み(該当者が出ても空文字扱いになるだけで実害小)
|
||||||
|
|
||||||
|
### 5-2. ①の対応内容(production版のみ、2026-09-05完了)
|
||||||
|
|
||||||
|
当初は「LWグループマッピング66件が本物のGroupsに1件も対応物を持たないため本物化には書込み移行が前提になり、構築のみでは完結しない」と判断していたが、①のワークフロー自体が元々「本物のGroupsに存在しないグループを自動で新規作成する」設計(差分計算→groupsToCreate→グループ作成実行)だったため、**ワークフロー定義の書き換え自体は構築の範囲で完結できる**と整理し直した(実際の新規作成・無効化という書込みは、このワークフローを実際に実行したときに初めて発生する=稼働テスト禁止と同じ制約の範囲内)。
|
||||||
|
|
||||||
|
- `模倣Groups取得`ノード → `Groups取得`へ改名、`items/504738/export` → `api/groups/get`(Offset+TotalCountページング設定込み)
|
||||||
|
- `グループ作成実行`ノード: `items/504738/create`(`ClassA`=独自連番, `ClassB`=グループ名) → `api/groups/create`(`GroupName`のみ送信。Pleasanterが自動採番するGroupIdを使う設計に変更、独自連番の`nextGroupId`計算は廃止)
|
||||||
|
- `グループ無効化更新実行`ノード: `items/{itemId}/update`(`CheckA`) → `api/groups/{groupId}/update`(body`{Disabled}`のみ、GroupIdはURLパス側)。**実機検証済み(2026-09-05、本人許可の下stagingのGroupId=40「テスト用グループ」で確認)**。当初`api/groups/update`(bodyにGroupId)で試したところ404(nginxレベルで存在しないパス)、`items`系と同じ「IDをURLパスに含める」パターンが正解だった
|
||||||
|
- `作成結果ペアリング`ノード: 独自連番をそのまま通していた処理から、`グループ作成実行`のレスポンス(`Id`)を実際に取得して使うよう変更
|
||||||
|
- `差分計算`ノード: 標準APIから取得した本物のGroups一覧(`GroupName`→`GroupId`のマップ)を使い、LWグループマッピング66件の各行について「グループ名が本物のGroupsに実在するか」を追加でチェック。実在しなければ`groupsToCreate`に回して作り直し、実在するがグループID列がズレていれば`groupsToFixId`として修正対象に追加。これにより66件の移行問題もワークフロー実行時に自動的に解消される設計にした
|
||||||
|
- `新規マッピングCSV組立`ノード: `groupsToFixId`も統合。ここでCSVの列を共通ヘッダーにする際、fixId行が持たない列(分類・sourceKey等)を空文字で送ると既存値を上書き消去してしまう危険があった([[org-master-sync-n8n-mock-tables]]、8月の実データ事故と同種のパターン)ため、`groupsToFixId`側にも`category`/`sourceKey`/`groupName`の元の値を保持させて対応
|
||||||
|
|
||||||
|
**未検証・要注意点**: `グループ作成実行`のレスポンス形式(`Id`をトップレベルで返す前提、`createGroup`関数の実装から類推)、SplitInBatches(`グループ作成Loop`)内での入出力アイテムの対応順序、いずれも稼働テストなしでは確証が持てない。①のproduction版を初めて実行する際は、必ず少数件(1件)に絞ってから全体を回すこと。
|
||||||
|
|
||||||
|
(2026-09-05追記)`グループ更新`のURL(`/api/groups/{groupId}/update`)は本人許可の下stagingのGroupId=40「テスト用グループ」で実機検証済み。詳細は8-2節参照。
|
||||||
|
|
||||||
|
### 5-3. ④(統合版)の対応内容(production版のみ、2026-09-05完了)
|
||||||
|
|
||||||
|
`NodeSrv/apps/org-master-sync/sample/sampleアカウント作成スクリプト.js`(本番プリザンターのフィールドスクリプトとして稼働実績あり)から、Users/Groups標準APIの正確な使用例が得られたため、これをベースに実装した。
|
||||||
|
|
||||||
|
- `プリザンターUsers取得`/`プリザンターGroups取得`/`プリザンターDepts取得`: ①③と同様に標準API化(`/api/users/get`, `/api/groups/get`, `/api/depts/get`、Pagination込み)
|
||||||
|
- `users_create実行`: `items/504737/create` → `/api/users/create`。サンプルスクリプトの`createPleasanterUser`関数のbody構造をそのまま採用(`LoginId`/`Name`/`Password`/`DeptId`/`DeptCode`/`MailAddresses`等、フラットなフィールド名でHashネスト不要)
|
||||||
|
- `users_update実行`: `items/{itemId}/update` → `/api/users/{userId}/update`。**このURL自体はサンプルスクリプトに例が無く実機未検証**。Groups update(`/api/groups/{groupId}/update`)と同じ「IDをURLパスに含める」パターンからの類推
|
||||||
|
- `グループ取得`(メンバー判定用): `items/504738/export`(全件取得して対象1件をfind) → `/api/groups/{groupId}/get`(単体取得、対象1件だけ取得するよう効率化)
|
||||||
|
- `グループ更新実行`: `items/{itemId}/update` → `/api/groups/{groupId}/update`。サンプルスクリプトの`addUserGroup`関数を参考に、`GroupName`/`Body`/`GroupMembers`をまとめて送る形に変更(`Disabled`には触れない)
|
||||||
|
- **重要な発見**: 模倣Groupsの「グループメンバー(種別,キー,管理者フラグ 1行1メンバー)」というテキスト行形式は、本物の標準API`GroupMembers`配列の各要素(`'User,{userId},False'`という文字列)と**完全に同じフォーマット**だった(サンプルスクリプトで確認)。改行区切りテキスト⇔配列という違いだけで、行内容自体の変換は不要だった
|
||||||
|
- `対象判定`ロジックの変更点:
|
||||||
|
- 新規ユーザー作成時のメールアドレスを、旧実装の`社員マスタのメールアドレスのローカル部 + '@nexthd.jp'`固定ドメインから、**LINEWORKS側のメールアドレスをそのまま使う**方式に変更(本人指示、2026-09-05。ドメイン統一済みのため固定ドメイン付け替えは不要と判断)
|
||||||
|
- `DeptId`はUsers create時に必須のため、Depts標準APIの結果から`DeptName→DeptId`マップを新設(旧実装は`DeptCode`しか計算していなかった)
|
||||||
|
- 退職処理・組織変更の`userUpdateTasks.fields`を、模倣テーブルの内部列名(`無効`/`ロック`/`組織コード`等)から標準APIのフィールド名(`Disabled`/`Lockout`/`DeptCode`/`DeptId`/`MailAddresses`)へ変更
|
||||||
|
|
||||||
|
**未検証点**: `/api/users/{userId}/update`の実在(ダミーユーザー作成テストは本人許可が得られていないため確認できていない)。④のproduction版を実行する前に、退職処理か組織変更いずれかの経路で必ず1件だけ実行して確認すること。
|
||||||
|
|
||||||
|
### 5-4. ④-1・④-2・④-3の対応内容(production版のみ、2026-09-05完了)
|
||||||
|
|
||||||
|
④(統合版)を機能別に分割した部分抜粋版のため、同じ修正パターンを適用した。
|
||||||
|
|
||||||
|
- ④-1新規ユーザー作成: ④と同じくUsers/Depts/Groups取得を標準API化、`users_create実行`を`/api/users/create`化。新規ユーザーの初期グループ所属反映(`書き戻しグループ反映組立`)もGroupMembers配列ベースに変更
|
||||||
|
- ④-2ユーザー更新・退職処理: 同様にDepts/Users/Groups取得を標準API化。`対象展開`(退職処理・組織変更)を`/api/users/{userId}/update`化。模倣Usersテーブル固有の「itemId」概念(`userIdToItemId`によるUserId→模倣テーブル内部ID変換)は不要になった(標準APIはUserIdそのものが更新のキーになるため)
|
||||||
|
- ④-3グループ更新: Groups取得を標準API化、グループメンバー反映を`/api/groups/{groupId}/update`化
|
||||||
|
|
||||||
|
**重要な発見(バグ)**: ④(統合版)の対象判定コードに`const NEXT_GROUP_ALL_ID = '4'`という定義があったが、模倣Groupsテーブルにも本物のGroupsにも`GroupId=4`は存在しない誤った値だった(未使用の変数だったため実害はなかった)。④-1/④-2/④-3では同じ定数が正しく`'27'`(実在する「ネクストグループ全社員」グループ)になっていたため、そちらを正として全ワークフローで統一した。
|
||||||
|
|
||||||
|
**検証結果(2026-09-05追記)**: `/api/users/{userId}/update`は本人許可の下stagingのUserId=705「野木テストユーザ」で実機検証済み(`Disabled:false`送信、200 OK「"野木テストユーザ"を更新しました。」)。Groups/Depts系と同じ「IDをURLパスに含める」パターンで、④④④-1④-2の実装通りで問題なかった。①③④④-1④-2④-3、production版8本すべて未検証エンドポイントなしの状態になった。
|
||||||
|
|
||||||
|
## 6. 今回の制約(2026-09-05確認)
|
||||||
|
|
||||||
|
- n8nワークフロー定義の編集(PUT/POST /workflows、Data Table操作含む)は確認不要で全自動
|
||||||
|
- 本番プリザンター・LINEWORKSへの**読み取り**(GET系API、`items/{id}/export`、`items/{id}/get`含む)は許可
|
||||||
|
- 本番プリザンターへの**書き込み**(create/update/import/bulkupsert等)は不可。特に①のグループ作成、③のマージ結果書き込みは明示的に禁止
|
||||||
|
- ワークフローの稼働テスト(Webhookを実際に叩く、Manual Trigger実行)は不可
|
||||||
Loading…
Reference in New Issue
Block a user