ken_nogi/NodeSrv/docs/superpowers/plans/2026-09-05-org-master-sync-n8n-production-migration.md
Kenichiro NOGI 5abf932fa6 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>
2026-09-05 10:40:17 +09:00

16 KiB
Raw Blame History

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/GroupIdOffset/TotalCountページング必須という全く別の形式。「宛先を変えるだけ」では動かず、レスポンス変換層の追加が必要だった
  • LWグループマッピングテーブルSiteId 504411、66件: 組織48・役職8・職級6・利用権限タイプ4の「グループID(」列は模倣Groupsテーブル内の独自連番1〜135+で、本物のPleasanter GroupsGroupId実在範囲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-syncproduction版8本/ org-master-sync stagingstaging版8本/ org-master-sync prototypeProto系旧版15本/ LINEWORKS通知系2本

4. workflow_config_valuesn8n 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 504408LINEWORKS:役職マスタ)
PLEASANTER_LEVEL_MASTER_SITE_ID_PROD 504410LINEWORKS:職級マスタ)
PLEASANTER_USERTYPE_MASTER_SITE_ID_PROD 504409LINEWORKS:利用権限マスタ)
PLEASANTER_BACKUP_SITE_ID_PROD 504407社員・組織マスタ管理(副・バックアップ用)
PLEASANTER_LW_GROUP_MAP_SITE_ID_PROD 504411LWグループマッピング、新規追加

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/exportPOST api/users/getView:{ApiGetMailAddresses:true}付き、Offset+TotalCountページング設定済み
  • プリザンターDepts取得ノード: POST items/504736/exportPOST api/depts/get(同上ページング設定)
  • 「マージ計算」Codeード: 標準APIの生データUserId/LoginId/DeptId等)を、旧・模倣テーブルと同じキー名(ユーザID/ログインID/組織等)の中間形式へ変換する処理を先頭に追加。組織DeptIdからプリザンターDepts取得の結果で逆引き(deptIdToNameマップ)。これにより後続のマージ判定ロジック(pleasanterUserToFields等)は無改造で流用できている
  • SecretKeyManagerは本番データ上使用者ゼロを確認済み(該当者が出ても空文字扱いになるだけで実害小)

5-2. ①の対応内容production版のみ、2026-09-05完了

当初は「LWグループマッピング66件が本物のGroupsに1件も対応物を持たないため本物化には書込み移行が前提になり、構築のみでは完結しない」と判断していたが、①のワークフロー自体が元々「本物のGroupsに存在しないグループを自動で新規作成する」設計差分計算→groupsToCreate→グループ作成実行だったため、ワークフロー定義の書き換え自体は構築の範囲で完結できると整理し直した(実際の新規作成・無効化という書込みは、このワークフローを実際に実行したときに初めて発生する=稼働テスト禁止と同じ制約の範囲内)。

  • 模倣Groups取得ノード → Groups取得へ改名、items/504738/exportapi/groups/getOffset+TotalCountページング設定込み
  • グループ作成実行ノード: items/504738/createClassA=独自連番, ClassB=グループ名) → api/groups/createGroupNameのみ送信。Pleasanterが自動採番するGroupIdを使う設計に変更、独自連番のnextGroupId計算は廃止)
  • グループ無効化更新実行ノード: items/{itemId}/updateCheckAapi/groups/{groupId}/updatebody{Disabled}のみ、GroupIdはURLパス側実機検証済み2026-09-05、本人許可の下stagingのGroupId=40「テスト用グループ」で確認。当初api/groups/updatebodyにGroupIdで試したところ404nginxレベルで存在しないパスitems系と同じ「IDをURLパスに含める」パターンが正解だった
  • 作成結果ペアリングノード: 独自連番をそのまま通していた処理から、グループ作成実行のレスポンス(Id)を実際に取得して使うよう変更
  • 差分計算ノード: 標準APIから取得した本物のGroups一覧GroupNameGroupIdのマップを使い、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メンバー)」というテキスト行形式は、本物の標準APIGroupMembers配列の各要素('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}/exportitems/{id}/get含む)は許可
  • 本番プリザンターへの書き込みcreate/update/import/bulkupsert等は不可。特に①のグループ作成、③のマージ結果書き込みは明示的に禁止
  • ワークフローの稼働テストWebhookを実際に叩く、Manual Trigger実行は不可