/** * rotate-tabs-507570.js * ------------------------------------------------------------ * SiteId 507570(事業計画v2)専用のワンオフスクリプト。 * 期首を4月→10月に変更したことに伴い、画面タブ「1Q/2Q/3Q/4Q」(Tabs配列のラベルはそのまま)に * 割り当てられている中身(EditorColumnHashの_Tab-1〜_Tab-4配列)をローテーションする。 * * 変更前: _Tab-1(1Q)=4-6月, _Tab-2(2Q)=7-9月, _Tab-3(3Q)=10-12月, _Tab-4(4Q)=1-3月 * 変更後: _Tab-1(1Q)=10-12月, _Tab-2(2Q)=1-3月, _Tab-3(3Q)=4-6月, _Tab-4(4Q)=7-9月 * (新1Q=旧3Q、新2Q=旧4Q、新3Q=旧1Q、新4Q=旧2Qの中身をそのまま入れ替えるだけ。 * Section Id等も含めて配列ごと移動するので、タブ内の受注/着工/完成セクション構造は保持される) * * SiteSettings.Linksは省略厳禁のため、取得済み生JSONをそのままベースにコピーし、 * EditorColumnHashのみ差し替える。Permissionsは対象サイト自身が実体を持つ * (InheritPermission === SiteId自身)ためそのまま含める。 * * 使い方: * node rotate-tabs-507570.js … プレビューのみ(差分表示、送信なし) * node rotate-tabs-507570.js --execute … 実際にupdatesiteへ送信 * ------------------------------------------------------------ */ const fs = require("fs"); const path = require("path"); const https = require("https"); const PROJECT_NAME = "NEXTGROUP経営計画"; const ENV = "production"; const SITE_ID = 507570; const REPO_ROOT = path.join(__dirname, "..", "..", "..", ".."); const baseDir = path.join(REPO_ROOT, PROJECT_NAME); const siteDir = path.join(baseDir, "configs", ENV, `site-${SITE_ID}_事業計画v2`); const latestJsonPath = path.join(siteDir, "sitesettings", `site-${SITE_ID}_latest.json`); const modifyDir = path.join(siteDir, "modify", "rotate-tabs"); const configPath = path.join(REPO_ROOT, `config_${ENV}.json`); const serverConfig = JSON.parse(fs.readFileSync(configPath, "utf-8")); const execute = process.argv.includes("--execute"); const raw = JSON.parse(fs.readFileSync(latestJsonPath, "utf-8")); const data = raw.Response.Data; const ss = data.SiteSettings; const eh = ss.EditorColumnHash; const before = { "_Tab-1": eh["_Tab-1"], "_Tab-2": eh["_Tab-2"], "_Tab-3": eh["_Tab-3"], "_Tab-4": eh["_Tab-4"], }; const newEh = { ...eh, "_Tab-1": before["_Tab-3"], // 1Q <- 旧3Q(10-12月) "_Tab-2": before["_Tab-4"], // 2Q <- 旧4Q(1-3月) "_Tab-3": before["_Tab-1"], // 3Q <- 旧1Q(4-6月) "_Tab-4": before["_Tab-2"], // 4Q <- 旧2Q(7-9月) }; console.log("========================================"); console.log(" タブ内容ローテーション(プレビュー)"); console.log("========================================"); console.log(`SiteId: ${SITE_ID}\n`); for (const key of ["_Tab-1", "_Tab-2", "_Tab-3", "_Tab-4"]) { const descBefore = before[key].filter((x) => typeof x === "string" && x.startsWith("Description")).slice(0, 3); const descAfter = newEh[key].filter((x) => typeof x === "string" && x.startsWith("Description")).slice(0, 3); console.log(`${key}: [${descBefore.join(",")}...] -> [${descAfter.join(",")}...]`); } const body = { ApiVersion: serverConfig.ApiVersion || "1.1", ApiKey: serverConfig.ApiKey, SiteId: SITE_ID, Title: data.Title, ReferenceType: data.ReferenceType, ParentId: data.ParentId, InheritPermission: data.InheritPermission, Permissions: data.Permissions, SiteSettings: { ...ss, EditorColumnHash: newEh, }, }; fs.mkdirSync(modifyDir, { recursive: true }); const ts = new Date().toISOString().replace(/[:.]/g, "-"); const beforeSnapshotPath = path.join(modifyDir, `before_site-${SITE_ID}_latest_${ts}.json`); const previewPath = path.join(modifyDir, `site-${SITE_ID}_rotate_tabs_preview_${ts}.json`); fs.writeFileSync(beforeSnapshotPath, JSON.stringify(raw, null, 2)); fs.writeFileSync(previewPath, JSON.stringify({ ...body, ApiKey: "***masked***" }, null, 2)); console.log(`\n[OK] 変更前スナップショット保存: ${beforeSnapshotPath}`); console.log(`[OK] 送信予定内容(APIキーマスク)保存: ${previewPath}`); if (!execute) { console.log("\n[注意] --execute が指定されていないため、送信は行っていません。"); console.log("内容を確認の上、問題なければ次を実行してください: node rotate-tabs-507570.js --execute"); process.exit(0); } console.log("\n実際に送信します(updatesite)..."); const url = new URL(`${serverConfig.BaseUrl}/api/items/${SITE_ID}/updatesite`); const payload = JSON.stringify(body); const req = https.request( { hostname: url.hostname, path: url.pathname, method: "POST", headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(payload), }, }, (res) => { let chunks = ""; res.on("data", (c) => (chunks += c)); res.on("end", () => { console.log(`HTTP ${res.statusCode}`); console.log(chunks); const resultPath = path.join(modifyDir, `site-${SITE_ID}_rotate_tabs_result_${ts}.json`); fs.writeFileSync(resultPath, chunks); console.log(`[OK] 応答を保存しました: ${resultPath}`); }); } ); req.on("error", (e) => console.error("[エラー]", e)); req.write(payload); req.end();