diff --git a/Pleasanter/.claude/js/site-scripts/健康診断管理/update-clientscript-process-508971.js b/Pleasanter/.claude/js/site-scripts/健康診断管理/update-clientscript-process-508971.js new file mode 100644 index 00000000..c8b8559d --- /dev/null +++ b/Pleasanter/.claude/js/site-scripts/健康診断管理/update-clientscript-process-508971.js @@ -0,0 +1,68 @@ +// 健康診断管理 SiteId 508971: 既存のクライアントスクリプト「プロセス実行スクリプト」のBodyのみ +// ローカルファイルの最新内容で上書きする。Columns/EditorColumnHash/Processesには一切触れない。 +"use strict"; +const fs = require("fs"); +const path = require("path"); +const { findSiteDir, newModifyDir } = require("../../site-paths.js"); + +const PROJECT_NAME = "健康診断管理"; +const ENV = "production"; +const SITE_ID = 508971; +const REQUEST_LABEL = "update-clientscript-process"; +const TITLE = "プロセス実行スクリプト"; + +const REPO_ROOT = path.join(__dirname, "..", "..", "..", ".."); +const PROJECT_ROOT = path.join(REPO_ROOT, PROJECT_NAME); +const CONFIGS_DIR = path.join(PROJECT_ROOT, "configs", ENV); +const SCRIPT_FILE = path.join( + CONFIGS_DIR, + "site-508971_社員別健康診断管理", + "scripts", + "3_プロセス実行スクリプト.js" +); + +function loadServerConfig() { + return JSON.parse(fs.readFileSync(path.join(REPO_ROOT, `config_${ENV}.json`), "utf-8")); +} +function loadLatest() { + const siteDir = findSiteDir(CONFIGS_DIR, SITE_ID); + const p = path.join(siteDir, "sitesettings", `site-${SITE_ID}_latest.json`); + const raw = JSON.parse(fs.readFileSync(p, "utf-8")); + return { current: raw.Response.Data, siteDir, rawText: fs.readFileSync(p, "utf-8") }; +} + +const execute = process.argv.includes("--execute"); +const server = loadServerConfig(); + +(async () => { + const { current, siteDir, rawText } = loadLatest(); + const settings = JSON.parse(JSON.stringify(current.SiteSettings)); + settings.Links = current.SiteSettings.Links || []; + + const script = (settings.Scripts || []).find((s) => s.Title === TITLE); + if (!script) { + console.error(`[エラー] スクリプト「${TITLE}」が見つかりません。`); + process.exit(1); + } + const newBody = fs.readFileSync(SCRIPT_FILE, "utf-8"); + script.Body = newBody; + + const requestBody = { + ApiVersion: 1.1, ApiKey: server.ApiKey, SiteId: SITE_ID, + Title: current.Title, ReferenceType: current.ReferenceType, + ParentId: current.ParentId, InheritPermission: current.InheritPermission, + SiteSettings: settings, + }; + + const modifyDir = newModifyDir(siteDir, REQUEST_LABEL); + fs.writeFileSync(path.join(modifyDir, `before_site-${SITE_ID}_latest.json`), rawText, "utf-8"); + console.log("更新後Body文字数:", newBody.length); + + if (!execute) { + console.log("(--execute 未指定のためプレビューのみ)"); + return; + } + const url = `${server.BaseUrl}api/items/${SITE_ID}/updatesite`; + const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); + console.log(`[結果] HTTP ${res.status}:`, JSON.stringify(await res.json())); +})(); diff --git a/Pleasanter/健康診断管理/docs/n8n/design-fixed-menu.md b/Pleasanter/健康診断管理/docs/n8n/design-fixed-menu.md index 45f17b57..3ff405cb 100644 --- a/Pleasanter/健康診断管理/docs/n8n/design-fixed-menu.md +++ b/Pleasanter/健康診断管理/docs/n8n/design-fixed-menu.md @@ -1504,3 +1504,40 @@ PDF再提出案内→送信→受付完了、いずれも正常動作。 ノードの`nextAwaitInput`分岐は`processId===5`限定のため、processId=19は影響なし(単純な テキスト送信のみ、待機状態も変更しない)。実機確認: Process19実行→HC-WP Webhook (processId=19)→「■健康診断結果の再提出について」文言が正しく届くことを確認済み。 + +### 【重要】Process実行→HC-WP通知の連携が手動2段階だった問題を解消(2026-09-12) + +これまでの運用(①日程通知・⑤再検査通知・⑲診断書再提出依頼、いずれも)は「①Pleasanter画面で +Process実行→②担当者が別途n8n Webhookを手動でPOST」という2段階だった(設計時点で「現状は +手動。将来n8n側で自動化する可能性あり、未確定」と記載していた未解決事項)。本番運用では +担当者がcurl等を叩けないため、このままでは機能しない。 + +**対応**: 508971にユーザーが新規用意したクライアントスクリプト「プロセス実行スクリプト」 +(`configs/production/site-508971_社員別健康診断管理/scripts/3_プロセス実行スクリプト.js`、 +全17→19件のProcessのOnClickへ`$p.ex.processScript($(this));`を追加済み)へ、Process実行 +前にHC-WP Webhookを自動POSTする処理を追加した。 + +- OnClickスクリプトはProcess本体の処理(Status遷移・DataChanges)より**前**に実行される + (ユーザー確認済み)。`$p.execProcess()`はページ遷移を伴うため、実行後にWebhookを叩く + 設計は成立しない。よって通知は必ず`execProcess`呼び出し**前**に行う +- Process 5(日程通知済み)・11(再検査通知)・19(診断書再提出依頼)のswitch文case内で + `confirmAndNotify(procName, $p.id(), procNum)`を呼び、確認ダイアログ→HC-WP Webhook POST + (`https://n8n32.next-hd.net/webhook/healthcheck-status-push`、`resultId`は`$p.id()`で取得) + →失敗時は`alert`してプロセス自体を中断(`return`でcase内から関数全体を抜けるため、後続の + `$p.execProcess`は実行されない。ユーザーからの懸念に対し、JS仕様上switch内の`return`は + breakと異なり外側の関数から脱出することを確認済み) +- 全Processで共通して、実行前にコメント欄へ「実行者:氏名(UserId:xxx)/プロセス:名前」を + 記録する処理を追加。Pleasanter標準の`#Comments`要素へ`$p.set()`でセットしておくと、 + `execProcess`によるレコード更新と同時にコメントとして保存される(ユーザー提供の他サイト + 実装例`$p.set($('#Comments'), history);`に倣った。`api/items/{id}/update`へ`Comment` + パラメータを直接POSTする方式は試したが反映されず不採用——Hashネストしないフラットな + パラメータが黙って無視される8章の既知挙動と同様の非対称動作) + +反映は`.claude/js/site-scripts/健康診断管理/update-clientscript-process-508971.js` +(`update-clientscript-notice-508971.js`と同一パターン、Title="プロセス実行スクリプト")で実施。 +**事故**: 実装中に`get-site-config.js --env=production`を実行してキャッシュを更新した際、 +個別ファイル抽出処理によりローカル編集中の`3_プロセス実行スクリプト.js`が本番の未反映 +(編集前)内容で上書きされる事故が発生(設計時点で既知だった「クライアントスクリプトの +ローカル編集後にget-site-config.jsを再実行すると上書きされる」パターンそのもの)。編集を +再適用して復旧。実機確認は未実施(次回、担当者がPleasanter画面からProcess5/11/19いずれかを +実行し、LINEWORKS通知とコメント記録の両方が機能するか確認すること)。