// 健康診断管理 SiteId 508971: タブ「診断結果」のNum061~071(検査項目)に // ラベル末尾" (実施人数)"を付与し、同じ設定(ControlType/NoWrap/Min/Max/Description)を // 複製したNum081~091(ラベル末尾" (有所見者数)")を新規追加、EditorColumnHash._Tab-1の並びを // Num061→Num081→Num062→Num082…のように交互配置へ組み替えるワンショットスクリプト。 // updatesite(Mode:full)を使う。--execute指定時のみ実際に送信、指定なければプレビュー(送信Body・diff)のみ出力。 "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 SITE_NAME = "健康診断管理"; const REQUEST_LABEL = "tab2-jisshi-arishoken-counts"; 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 PAIRS = [ ["Num061", "Num081"], ["Num062", "Num082"], ["Num063", "Num083"], ["Num064", "Num084"], ["Num065", "Num085"], ["Num066", "Num086"], ["Num067", "Num087"], ["Num068", "Num088"], ["Num069", "Num089"], ["Num070", "Num090"], ["Num071", "Num091"], ]; function loadServerConfig() { const configPath = path.join(REPO_ROOT, `config_${ENV}.json`); const config = JSON.parse(fs.readFileSync(configPath, "utf-8")); if (!config.BaseUrl || !config.ApiKey) { console.error(`[エラー] ${configPath} に BaseUrl / ApiKey を設定してください。`); process.exit(1); } return config; } function loadLatest() { const siteDir = findSiteDir(CONFIGS_DIR, SITE_ID); if (!siteDir) { console.error(`[エラー] configs/${ENV}/site-${SITE_ID}_* が見つかりません。先にget-site-config.jsを実行してください。`); process.exit(1); } 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") }; } function buildDesiredSiteSettings(current) { const settings = JSON.parse(JSON.stringify(current.SiteSettings)); const columns = settings.Columns; const addedColumns = []; for (const [srcName, newName] of PAIRS) { const src = columns.find((c) => c.ColumnName === srcName); if (!src) { console.error(`[エラー] Columns内に${srcName}が見つかりません。`); process.exit(1); } if (columns.some((c) => c.ColumnName === newName)) { console.error(`[エラー] Columns内に${newName}が既に存在します(重複追加防止のため中断)。`); process.exit(1); } const originalLabel = src.LabelText; src.LabelText = `${originalLabel} (実施人数)`; const newCol = JSON.parse(JSON.stringify(src)); newCol.ColumnName = newName; newCol.LabelText = `${originalLabel} (有所見者数)`; columns.push(newCol); addedColumns.push(newCol); } // EditorColumnHash._Tab-1 の並びをNum061→Num081→Num062→Num082…と交互に組み替える const tab1 = settings.EditorColumnHash["_Tab-1"]; const pairSrcSet = new Set(PAIRS.map(([src]) => src)); const rebuilt = []; for (const name of tab1) { rebuilt.push(name); if (pairSrcSet.has(name)) { const pair = PAIRS.find(([src]) => src === name); rebuilt.push(pair[1]); } } settings.EditorColumnHash["_Tab-1"] = rebuilt; // Links省略厳禁(全置換のため既存値をそのまま含める) settings.Links = current.SiteSettings.Links || []; return { settings, addedColumns, rebuiltTab1: rebuilt }; } function buildUpdateBody(apiKey, current, desiredSettings) { return { ApiVersion: "1.1", ApiKey: apiKey, SiteId: SITE_ID, Title: current.Title, ReferenceType: current.ReferenceType, ParentId: current.ParentId, InheritPermission: current.InheritPermission, SiteSettings: desiredSettings, }; } const execute = process.argv.includes("--execute"); const server = loadServerConfig(); (async () => { const { current, siteDir, rawText } = loadLatest(); const { settings: desiredSettings, addedColumns, rebuiltTab1 } = buildDesiredSiteSettings(current); const body = buildUpdateBody(server.ApiKey, current, desiredSettings); const modifyDir = newModifyDir(siteDir, REQUEST_LABEL); const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); fs.writeFileSync(path.join(modifyDir, `before_site-${SITE_ID}_latest.json`), rawText, "utf-8"); const updatedPath = path.join(modifyDir, `site-${SITE_ID}_updated_${timestamp}.json`); fs.writeFileSync(updatedPath, JSON.stringify(body, null, 2), "utf-8"); console.log(`\n==== SiteId ${SITE_ID} (${SITE_NAME}) ====`); console.log("ラベル変更(実施人数):"); for (const [srcName] of PAIRS) { const c = desiredSettings.Columns.find((x) => x.ColumnName === srcName); console.log(` - ${srcName}: ${c.LabelText}`); } console.log("新規追加(有所見者数):"); for (const c of addedColumns) { console.log(` - ${c.ColumnName}: ${c.LabelText}`); } console.log("EditorColumnHash._Tab-1 変更後の並び:"); console.log(` [${rebuiltTab1.join(", ")}]`); console.log(`\nColumns件数: 変更前${current.SiteSettings.Columns.length} → 変更後${desiredSettings.Columns.length}`); console.log(`プレビュー保存先: ${updatedPath}`); if (!execute) { console.log("\n(--execute 未指定のためプレビューのみ。送信していません)"); return; } const url = `${server.BaseUrl}api/items/${SITE_ID}/updatesite`; console.log(`送信先: ${url}`); const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const json = await res.json(); console.log(`[結果] HTTP ${res.status}:`, JSON.stringify(json)); const resultPath = path.join(modifyDir, `site-${SITE_ID}_result_${timestamp}.json`); fs.writeFileSync(resultPath, JSON.stringify(json, null, 2), "utf-8"); })();