--- name: pleasanter-site-spec description: Pleasanterのサイト設定JSON(get-site-config.js / api-site-get の getsite レスポンス)から、SiteSettingsを読み解いたMarkdown仕様書を生成し、Scripts/Styles/ServerScripts/Processesの抽出・編集・反映(extract-site-config.js / build-desired-config.js / apply-site-config.js)を行う。ユーザー/組織/グループのマスターデータ取得(get-master-data.js)、別サイトへのSiteSettings丸ごと適用や項目の追加・連番リネームといった構造変更(restructure-site-*.js / apply-to-site-*.js)、権限(Permissions)の名前指定での追加(apply-permission-grant.js)にも対応する(これらはSiteId 480111/496626専用の実例テンプレートで「新・着工要因システム」プロジェクト限定)。プロセス設定(Processes)のStatus遷移を横向きMermaidフローチャートとして可視化(generate-process-flowchart.js)、業務担当者向け概要書生成・PDF化(md-to-pdf.js)、複数サイトの関連図生成にも対応する。「仕様書を作って」「サイト仕様書」「SiteSettingsをドキュメント化」「スクリプトを抜き出して」「プロセス設定を直して反映して」「別サイトに丸ごと適用して」「項目を追加して連番をズラして」「この人と同じ権限を追加して」「フローチャートを作って」「概要書を作って」「PDFにして」「関連図を作って」「site-spec」等の依頼で使う。 --- # Pleasanter サイト仕様書生成・構成管理 `configs/site-{SiteId}_{サイト名}/`(または`siteSettingJsons/`。下記「レイアウト」参照)配下の 生JSON・抽出済みファイル読み解き、`docs/site-{SiteId}_spec.md` へ日本語Markdown仕様書出力。 ## ツール置き場所(共通化・全プロジェクト共有) 実装本体は `ClaudePleasanter/.claude/js/`(このSKILL.mdと同じ `.claude/` 配下)に1本化済み。 各プロジェクトの `.claude/js/{スクリプト名}.js`(またはプロジェクト直下)は共通実装を `require` する 数行ラッパーのみ。修正は共通実装1箇所で全プロジェクトに反映。同一ファイルのコピー増殖禁止。 ラッパーは環境変数セット後に共通実装を `require`: - `PLEASANTER_PROJECT_ROOT` … 呼び出し元プロジェクトルートの絶対パス(必須) - `PLEASANTER_LAYOUT` … `"flat"` | `"separate"` | 未設定(既定=`"hierarchical"`)。次項「レイアウト」参照 新規プロジェクト導入時も実体コピーせずラッパー設置。 ## サーバー環境(本番/テスト)の指定(`--env`必須) 接続先サーバー情報(`BaseUrl`/`ApiKey`/`ApiVersion`)と対象サイト(`SiteId`)は別ファイルに分離済み: - リポジトリルート直下 `config_production.json`(本番: `nextoffice.next-hd.co.jp`) / `config_development.json`(テスト: `neo999.next-hd.net`) … サーバー接続情報。`resolve-project.js`の `loadServerConfig(env)`で読む。 - 各プロジェクト直下 `siteid.json`(`{"SiteId": "..."}`のみ) … 対象サイトID。旧`config.json` (`BaseUrl`/`SiteId`/`ApiKey`が同居)から移行済み。`loadSiteId(baseDir)`で読む。 全ツールは実行時に `--project` に加えて `--env=production|development` を必須指定する (`resolveProjectRoot()`が両方まとめて解決し `{ baseDir, env, argv }` を返す。誤送信事故防止のため デフォルト値は無く、未指定・不正値はエラー終了)。取得データ(`configs/`配下)もenvごとに 物理的に別ディレクトリへ保存されるため、本番/テストのデータが同一フォルダで混在・上書きされることはない (2026-08-21、config.json一本化方式からこの方式へ移行。旧方式では同一config.jsonにBaseUrl/ApiKeyが 同居しており、xwiki/build-pleasanter-scheme.js内に「config.jsonが他プロジェクトの値と誤って コピーされていた」という過去の取り違え事故の注記が残っている)。 ## レイアウト(プロジェクトごと固定、自動判定なし) 生JSON(`getsite`レスポンス)保存場所は過去運用により3パターン。既存`configs/{env}/`実データ構造を 変えないため、プロジェクトごとに1つ固定使用(ラッパーの`PLEASANTER_LAYOUT`で指定。混在・自動判定なし)。 抽出済みファイル(`configs/{env}/site-{SiteId}_{サイト名}/scripts/`等)置き場所は3パターン共通。 | layout値 | 生JSON保存先 | 該当プロジェクト | |---|---|---| | `hierarchical`(既定) | `configs/{env}/site-{SiteId}_{サイト名}/sitesettings/site-{SiteId}_latest.json` | IC(東京)【引継依頼】、★マスターシート、MSS回覧板システム、営業積算システム、新・着工要因システム、新・稟議申請システム、事業計画、助っ人クラウド、#積算問合せ | | `flat` | `configs/{env}/site-{SiteId}_latest.json`(`configs/{env}`直下フラット、サイト名フォルダなし) | files | | `separate` | `siteSettingJsons/{env}/site-{SiteId}_latest.json`(configs/とは別のトップレベルフォルダ) | (現在該当プロジェクトなし) | 不明時は実際の`configs/{env}/`(と`siteSettingJsons/{env}/`有無)を見て判断。新規プロジェクトは`hierarchical`既定。 production対象8プロジェクト(本番: nextoffice.next-hd.co.jp)、development対象2プロジェクト (テスト: neo999.next-hd.net、`営業積算システム`・`files`)は2026-08-21に既存`configs/`データを `configs/{env}/`へ移行済み。 ## フォルダ構成(`hierarchical`の場合。他layoutは生JSON部分のみ上表通り読み替え) ``` configs/ {env}/ … "production" | "development"(サーバー環境で必ず1段分離) master/ … ユーザー/組織/グループのマスターデータ(get-master-data.js) master_users.json master_depts.json master_groups.json site-{SiteId}_{サイト名}/ sitesettings/ … getsiteの生JSON(get-site-config.jsが保存。latest.json + タイムスタンプ付き履歴) site-{SiteId}_latest.json site-{SiteId}_{timestamp}.json scripts/ styles/ serverscripts/ html/ processes.json / manifest.json … extract-site-config.js による分割済みファイル(layout共通) docs/ … 仕様書(.md)・概要書(.md)・PDF等、sitesettings以外の関連ドキュメント modify/{リクエストラベル}/ … 修正依頼のたびに新規作成。変更前後のconfigファイル・ 差分プレビュー・送信結果に加え、summary.md(後述)を 必ずひとまとめに保管 ``` 修正1件でも反映した場合、`modify/{リクエストラベル}/`フォルダへ機械可読な生JSON(差分プレビュー・送信結果)だけでなく、 人間可読サマリー`summary_{timestamp}.md`を必ず作成・保存(ユーザー明示指示なくても毎回)。 `{timestamp}`は同じ反映で生成される送信結果ファイル(`site-{SiteId}_full_update_result_{timestamp}.json`等)と揃える。 `summary.md`のような固定名で毎回上書きせず、反映のたびに別ファイルとして残す。記載内容目安: - 対象サイト・反映日時・反映方法(実行コマンド)・反映結果(HTTPステータス・メッセージ) - 依頼内容ごとの変更点(変更前→変更後を表や箇条書きで) - 保留・見送り事項(あれば) `.md`ファイルのため、原始人口調か通常日本語かは他のテキストファイル生成と同様に一度だけユーザーに確認。 パス解決は`site-paths.js`に共通化(`findSiteDir`/`ensureSiteDir`/`sitesettingsDir`/`docsDir`/ `newModifyDir`/`latestModifyDir`/`latestJsonPath`/`rawJsonSaveDir`/`findLatestJsonPath`)。 `rawJsonSaveDir`/`findLatestJsonPath`は`env`引数を取る(`separate`レイアウトの `siteSettingJsons/{env}/`分離用。呼び出し元は`configsDir = path.join(baseDir, "configs", env)`を 自分で組み立てて渡す設計のため、hierarchical/flatではこの2関数以外は無改修でenv分離が効く)。 サーバー接続情報・SiteId解決は`resolve-project.js`の`loadServerConfig(env)`/`loadSiteId(baseDir)`に共通化。 新規スクリプト作成時はここ再利用、パス組み立て・config読み込みの重複禁止。 ## 入力の特定 1. ユーザーがJSONファイルパスやSiteId指定した場合はそれを使う。 2. 指定なければ`--env`で指定されたenv・layoutに応じた場所(`configs/{env}/site-*/sitesettings/site-*_latest.json` / `configs/{env}/site-*_latest.json` / `siteSettingJsons/{env}/site-*_latest.json`)を探す。複数あればユーザーに確認。 3. 見つからなければ、先に`node get-site-config.js --project=... --env=production|development`実行を提案 (エンドポイントは`/api/items/{SiteId}/getsite`使用。`/api/items/{SiteId}/get`はアイテム一覧取得APIで別物、注意)。 ## 出力ファイル `docs/site-{SiteId}_spec.md`(既存あれば上書き可。置き場所は`configs/site-{SiteId}_{サイト名}/docs/`直下か プロジェクト直下`docs/`か、プロジェクトごとの既存慣例優先)。 ## 仕様書の構成(この順番・見出しレベル踏襲) ```markdown # サイト仕様書:{Title}(SiteId: {SiteId}) - 取得元データ: [site-{SiteId}_latest.json]({生JSONへの相対リンク}) - 取得日時: {UpdatedTime}(サイト更新日時)/設定バージョン `Ver: {Ver}` ## 1. サイト基本情報 (TenantId, Title, ReferenceType, ParentId, InheritPermission, Publish, DisableCrossSearch, Creator/Updator, CreatedTime, SiteSettings.Version を表形式で) ## 2. アクセス権限(Permissions) (Permissions配列を 種別/対象ID/権限レベル の表に分解。可能であれば `resolve-names.js` の `resolveName` でユーザー名・組織名・グループ名も併記する。 InheritPermissionが自サイト以外を指している場合は、権限の実体はそちらのサイトにある旨を明記し、 継承元サイトのPermissionsも取得できていれば併せて記載する。 「権限値はビットフラグの加算方式のため正確な意味は環境のロール定義に依存する」旨を注記) ## 3. 画面構成 ### 3.1 一覧画面(GridColumns) (GridColumns配列を 順番/列名/表示ラベル の表に。ラベルはColumns配列から解決、 無ければ「項目種別の判定ルール」のデフォルト名を使う) ### 3.2 編集画面レイアウト(EditorColumnHash / Sections) (EditorColumnHashの各タブ配列を 順番/項目名(内部名)/ラベル名 の表に。 `_Section-N` はラベル名欄に「―(セクション「{LabelText}」開始)」と記載。 続けてSections配列を Id/ラベル/AllowExpand/Expand の表で示す) ### 3.3 タイトル表示(TitleColumns / TitleSeparator) (TitleColumns配列をTitleSeparatorで連結した式を明記) ## 4. 項目定義(Columns) (Columns配列を 列名(内部)/種別/表示ラベル/説明・入力ガイド/備考 の表に。 種別は下記「項目種別の判定ルール」で推定。 備考にはNoWrap, FieldCss, ExtendedHtmlAfterControlの有無などを記載) ### 4.1 項目ごとの補足HTML(ExtendedHtmlAfterControl) (該当項目があれば 列名/色(styleやclassから読み取れれば)/内容 の表。無ければこの節は省略) ## 5. 作成・更新権限(フィールド単位) (PermissionForCreating / PermissionForUpdating を表で。無ければ「設定なし」と明記) ## 6. 集計設定(Aggregations) (存在する場合のみ。Id/GroupBy/Type/Target を表で) ## 7. 他サイト連携(Links / ルックアップ) (存在する場合のみ。起点列/参照先SiteId/参照先の値→自コピー先/JsonFormat を表で。 「参照先サイトの{From}列の値を、このサイトの{To}列にコピーする」という関係性を文章でも補足) ## 8. プロセス設定(Processes) (存在する場合のみ。定義ファイルへのリンク processes.json を明記した上で、 Id/Name・DisplayName/実行条件(CurrentStatus→ChangedStatus)/動作(OnClick等)/成功メッセージ を表で。 加えて、generate-process-flowchart.jsで生成したMermaid横向きフローチャート(Status遷移図)を表の後に掲載する) ## 9. スタイル(Styles) (存在する場合のみ。Id/Title/適用範囲(New/Edit/Index等のフラグ)/ファイルへのリンクを表で。 CSS本体はMarkdownに貼らず、抽出済みファイルへのリンクのみとする) ## 10. スクリプト(Scripts)/サーバースクリプト(ServerScripts) (存在する場合のみ。Id/Title/適用画面/ファイルへのリンクを表で。 スクリプト本体はMarkdownに貼らず、抽出済みファイルへのリンクのみとする。 概要は「何をするスクリプトか」を1〜2行で要約。 本文中にAPIキー・Webhook URL・パスワード等の秘密情報らしき文字列(`API_KEY`, `SECRET`, `Bearer `, URLに埋め込まれたトークン等)を見つけた場合は、値そのものをMarkdownに転記せず、 「気になる点」に必ずセキュリティ上の指摘として記載する) ## 11. その他設定 (NoDisplayIfReadOnly, HideLink, SectionLatestId, 各種ガイド文の設定有無, Commentsの使用有無など) --- ## 気になる点(レビュー観点) (プレースホルダーらしき文言、権限設定の偏り、項目単位の権限の抜け、 未設定のガイド文など、気づいた点を箇条書きで) ``` ## 項目種別の判定ルール(Columns内ColumnNameのプレフィックスから推定) | プレフィックス/名前 | 種別 | |---|---| | ClassA〜Z | 文字列(分類) | | Class001〜040等(3桁連番) | 文字列(拡張分類)。`Hide: true`の場合が多く、他項目のルックアップ先の値を裏で保持する用途が多い | | NumA〜Z | 数値 | | DateA〜Z | 日付 | | DescriptionA〜Z | 説明(複数行文字列) | | CheckA〜Z | チェックボックス | | AttachmentsA〜Z | 添付ファイル | | Owner, Manager, Assignee等 | ユーザー選択 | | Status | 状態 | | {対象}Id(ResultId, IssueId等) | 自動採番ID | | Title | タイトル | | Comments | コメント欄 | 「予定/実行/無し/備考」の4列1組パターン(`DateNNN`/`Date(NNN+100)`/`Check(NNN+100)`/`ClassNNN`、NNNは3桁ゼロ埋め連番) 繰り返し登場するサイトあり。この場合`DateNNN.Description`が入力担当(部署名等)、`DateNNN.GridLabelText`が 項目の表示名。詳細は下記「クロスサイト構造変更」参照。 ## 注意事項 - SiteSettingsに存在しない項目・空の設定(例: `ClassHash`, `NumHash` などのラベル定義ハッシュが `{}`)は 「標準ラベルのまま」として仕様書に明記、存在しないかのように省略しない。 - 表形式基本、箇条書きより表優先(編集画面レイアウトは項目名とラベル名必ず併記)。 - 出力言語は日本語。 - 複数サイト関連仕様書(「関連するテーブルと合わせて」等の依頼)作成時は、対象サイトの`Links`設定だけでなく、 ServerScripts内で`items.Get(masterTableId)`のように直接SiteIdをハードコードして参照している「正式なLinks設定に現れない 暗黙的なテーブル参照」も洗い出し、別セクションとして明記。あわせて`ParentId`を辿ってサイトツリー上の位置関係も 簡潔に図示するとレビューしやすい。 ## 概要書(業務担当者向け機能説明)の生成 技術仕様書(spec.md)とは別に、「概要書を作って」「機能的な説明がほしい」等の依頼時は、 `ColumnName`(ClassA, DateB, Class001等の内部コード)やJSON設定値・スクリプト実装といった技術的要素を一切排除し、 ラベル名と業務フローのみで構成した概要書を作成する。 ### 出力ファイル `docs/site-{SiteId}_overview.md`(`configs/`・`siteSettingJsons/`ではなく`docs/`フォルダに置く。これらは秘密情報 含み得るため`.gitignore`済みだが、`docs/`配下の概要書・PDFは共有物としてGit管理対象にする想定)。 `docs/`フォルダ無ければ作成。 ### 概要書の構成 ```markdown # 概要書:{Title} - 技術仕様(項目のシステム上の名称・設定値等)は [{spec.mdへのリンク}] を参照。 本書は業務担当者向けに、機能面のみを平易に説明するものです。 ## 1. これは何か (業務的にこのサイトが何のためのものかを2〜4文で) ## 2. 登場する情報(入力項目) (分類/項目(ラベル名のみ)/内容 の表。ColumnNameは記載しない。Hide項目でも 業務上意味のあるもの(自動反映される裏項目等)は「内容」欄で触れる) ## 3. 業務の流れ(ボタン操作) (操作/状態の変化(ラベル値同士、例:「新規作成→承認回覧」)/説明 の表。 Processesの内部処理・スクリプト名には触れず、「何が起きるか」を業務言葉で説明する) ## 4. 通知される場面 (Notificationsを「◯◯時に誰に何が届くか」という箇条書きに変換。メール本文・件名の技術的書式は転記しない) ## 5. 関連する仕組み(マスタ連携) (Links・暗黙的テーブル参照を「◯◯マスタ:何を自動反映するか」という業務目線の箇条書きに変換。 SiteIdやColumnNameは書かず、サイト名(Title)とその役割のみ記載。 兄弟サイト(同じ設計パターンの別サイト)があれば、違いを1文で触れる) ``` ### 作成時の注意 - 表内「項目」列は必ずラベル名(LabelText)のみ。ラベル未設定項目は概要書に載せない(業務上意味を説明できないため)。 - Statusの遷移は内部コード(100/300/900等)を書かず、ラベル値(新規作成/完了等)同士の矢印で表現。 - スクリプト内で見つけた秘密情報(APIキー等)は概要書に一切転記しない(そもそも概要書はスクリプト実装に触れない)。 - 複数サイト分まとめて依頼時、共通する業務フローは重複して書いてよいが、各サイト固有の違い(段階数の違い、 追加の管理項目など)を各概要書の末尾で明示、他サイトとの差分が一目で分かるようにする。 ## 複数サイトの全体関連図(site-relations_overview.md) `siteid.json`の`SiteId`に複数サイト列挙されている場合など、「全体の関連図を作って」「サイト間の連携をまとめて」 等の依頼あれば、個々のサイト仕様書とは別に`docs/site-relations_overview.md`を作成。対象は `siteid.json`の`SiteId`に列挙された全サイト(または依頼で指定された範囲)。 ### 出力ファイルと構成 `docs/site-relations_overview.md`(同名`.pdf`も作成対象)。以下を1枚で俯瞰できるようまとめる。 ```markdown # サイト関連図:{システム名など} ## 1. サイトツリー(ParentId) (`ParentId` を辿った親子関係を、簡易的なツリー表記かMermaid `graph` で図示。 各ノードにSiteIdとサイト名(Title)を併記) ## 2. サイト一覧 (SiteId/サイト名/役割(1行)の表。概要書へのリンクも併記) ## 3. 明示的な連携(Links) (各サイトの`Links`設定を 起点サイト/起点列/参照先サイト/参照先の値→コピー先 の表にまとめる。 Idではなくサイト名で表現し、業務的に何を自動反映しているかも一言添える) ## 4. 暗黙的な連携(ServerScriptsのハードコード参照) (ServerScripts内で`items.Get(SiteId)`等により直接SiteIdを指定して他サイトを参照している箇所を洗い出し、 起点サイト/参照先サイト/該当スクリプトファイル/目的(推測) の表にまとめる。 正式なLinks設定には現れないため、レビュー上重要な情報として明記する) ``` ### 作成時の注意 - 各サイトの`spec.md`(7. 他サイト連携)で洗い出した内容を集約すればよい。個別spec.md作成より先に全サイト分の spec.md作成しておくと効率的。 - サイト名はTitle使用、SiteIdは補助情報として併記(概要書と違い技術仕様書寄り、SiteId自体は隠さなくてよい)。 ## PDF化 概要書(または他Markdown)PDF化依頼時は、共通実装のラッパー経由で`md-to-pdf.js`使用。 ``` node md-to-pdf.js ./docs/site-{SiteId}_overview.md ``` - 追加npmパッケージ非依存。Markdown→HTML変換はスクリプト内簡易パーサ(見出し/表/太字/リンク/箇条書き/水平線/段落)で行い、 PDF化はOS標準Microsoft Edge(無ければGoogle Chrome)ヘッドレス印刷機能使用。 - 出力は入力と同じフォルダに`{同名}.pdf`(中間HTMLは一時フォルダ作成後、変換後自動削除)。 - 複数ファイル一度に渡せる(`node md-to-pdf.js ./docs/*.md`)。 - **既知の落とし穴**: フォルダパスに`#`含む場合(例: `#GitHub`)、素朴に`file://` + パス文字列連結すると `#`以降がURLフラグメントと誤認識され、無関係なページが開かれてPDFの中身が空/別物になる。 `md-to-pdf.js`は`url.pathToFileURL()`で正しくエンコードしているため通常問題ないが、 同種のブラウザ自動化コード新規作成時は同じ罠に注意。 ## 関連ツール:Scripts/Styles/ServerScripts/Processesの抽出・編集・反映 仕様書化とは別に、「スクリプトを個別ファイルに分けて」「プロセス設定を直して反映して」等の依頼では、 以下のツールチェーンを使う。 1. `node get-site-config.js --project="..." --env=production|development` … 生JSON (layoutに応じた保存先。上記「レイアウト」参照)を取得し、続けて自動的に抽出も行う (`extract-site-config.js` が内部から呼ばれ、`configs/{env}/site-{SiteId}_{サイト名}/` に 以下を分割保存する。未取得なら先にこれを実行) - `scripts/{Id}_{Title}.js`(クライアントスクリプト本体) - `styles/{Id}_{Title}.css`(スタイル本体) - `serverscripts/{Id}_{Title}.js`(サーバースクリプト本体) - `html/{GuideName}.html`(GridGuide等のガイドHTML。SiteSettingsではなくサイトデータ直下の項目) - `processes.json`(`SiteSettings.Processes` の定義ファイル、1ファイルにまとめる。分割しない) - `manifest.json`(上記ファイルとId/Titleの対応表。再構成に必須) - `siteid.json`の`SiteId`はカンマ区切りで複数指定可能。また、取得したサイトの`InheritPermission`が 自サイト以外を指している場合、権限の実体を持つそのサイトも自動的に追いかけて取得する。 - 抽出だけをやり直したい場合(`latest.json`は既に取得済み)は`node extract-site-config.js`を単独実行してもよい - **注意**: `get-site-config.js`を再実行すると、その時点のサイトの生の状態で`scripts/` `styles/`等が 上書きされる。あるサイトの内容を「別サイトへ適用するための下書き」として編集している最中に、 同じサイトへ`get-site-config.js`を再実行すると編集内容が失われるので、クロスサイト作業中は むやみに元サイトを再取得しない(詳しくは後述の「クロスサイト構造変更」参照)。 - **下書きファイルの整理**: `scripts/` `styles/` `serverscripts/`配下に`_修正`等のサフィックス付きで `manifest.json`未登録の下書きファイルが残っていることがある(過去に本文を直接編集した際の作業ファイル)。 再取得後は、この下書きファイルと対応する正規ファイル(`manifest.json`の`File`に記載された方)を diffで比較。内容が完全一致していれば、下書きの編集内容は既にサイトへ反映済みということなので、 その下書きファイルは削除してよい。内容が異なる場合は未反映の編集が残っている可能性があるため、 削除せずユーザーに確認する。 2. ユーザーの指示に従い、`scripts/*.js`等の中身を直接編集(`manifest.json`のId/メタ情報は変更しない)。 新規追加の場合は`manifest.json`に対応エントリ(`Id`は既存と重複しない値、`File`名)を追加してからファイルを作成。 3. `node build-desired-config.js site-{SiteId}` … 分割ファイルを再構成し`desired_config.json`を生成(送信なし)。 フォルダ名はサイト名まで含む正式名(`site-{SiteId}_{サイト名}`)だが、`site-{SiteId}`の前方一致指定でも `configs/`配下から自動解決される 4. `node apply-site-config.js` … ドライラン確認(差分・送信Body・curlコマンド表示のみ、送信なし) 5. 内容をユーザーに確認してもらい、問題なければ表示されたcurlコマンドをユーザー自身が手動実行する `updatesitesettings`(部分更新)はこの環境でHTTP 200を返しても実際には反映されないことを確認済み。 Scripts/Styles/ServerScripts/Processesを確実に反映したい場合は、代わりに `node apply-desired-config-full.js`(`--execute`指定時のみ送信、既定はプレビューのみ)を使う (`updatesite`全体更新で、Columns/GridColumns/Permissions等それ以外は一切変更しない)。 ## 関連ツール:プロセス設定のMermaidフローチャート化 「フローチャートを作って」「フローチャートを更新」等の依頼では、`generate-process-flowchart.js`を使う。 ``` node generate-process-flowchart.js site-335411 ``` `processes.json`(`extract-site-config.js`で抽出済みであること)と、サイトの生JSON`Status`列`ChoicesText`から、 横向きMermaidフローチャート(Status遷移図)を標準出力へ表示。ファイル書き込み・API送信は行わない。 出力された```mermaid```ブロックは、仕様書「8. プロセス設定」節へ手動で組み込む。 - ノード = Status値(例: `450`)。ラベルは`Status`列`ChoicesText`から解決(`{ラベル}
{値}`形式) - エッジ = プロセス名。`Depts`指定あれば`(Dept25)`付記、`Notifications`配列空でなければ先頭に📧付与 - `CurrentStatus`/`ChangedStatus`が`-1`(任意状態からの実行・状態変化なしのアクション)の場合、 `View.ColumnFilterHash.Status`あればその対象Statusごとに矢印、なければ仮想ノード`((任意))`使用 - 対象は`processes.json`の構造化データのみ。Scripts/ServerScriptsによるボタン非表示化・独自ボタン経由 呼び出しの検出は含まない(サイトごとに実装が異なり自動化困難なため)。該当する非表示化・独自ボタンの 有無は、仕様書8節の表・文章側で別途補足すること ## 関連ツール:ユーザー/組織/グループのマスターデータ取得 権限(Permissions)やスクリプト内の担当者振り分けなどをID表記ではなく名前で扱いたい場合に使う。 1. `node get-master-data.js --project="..." --env=production|development` … `configs/{env}/master/`へ 以下を取得・保存(ページング自動対応。layout非依存で共通。 `/api/users/get`はレスポンスの`TotalCount`が1回あたりの件数を超えることがあるため、 トップレベルの`Offset`パラメータで全件取得しきるまでループする)。 - `master_users.json`(`UserId` / `LoginId` / `Name` / `DeptId` 等) - `master_depts.json`(`DeptId` / `DeptCode` / `DeptName`) - `master_groups.json`(`GroupId` / `GroupName` / `GroupMembers[]` / `GroupChildren[]`) - 参照した公式マニュアル: [ユーザ取得(全て)](https://pleasanter.org/ja/manual/api-user-get-all) / [組織取得](https://pleasanter.org/ja/manual/api-dept-get) / [グループ取得](https://pleasanter.org/ja/manual/api-group-get) 2. `resolve-names.js`をスクリプトから`require`して使う: - `loadMasterData(baseDir, env)` … 3つの`master_*.json`を読み込む(両方省略時は`resolveProjectRoot()`で解決) - `resolveName(master, { Type: "User"|"Dept"|"Group", Id })` … IDから名前を引く - `resolveId(master, { Type, Name })` … 名前から一致するIDの配列を引く(完全一致。0件/複数件はエラーとして扱う) ## 関連ツール:クロスサイト構造変更(項目追加・連番リネーム・別サイトへの丸ごと適用) 「Aサイトを土台に項目を追加してBサイトへ適用して」「この項目の後ろに新しい項目を追加して、以降の連番を ズラして」のような依頼で使うパターン。**「新・着工要因システム」プロジェクト限定**、2026-07-16にSiteId 480111→496626への適用(「解体紹介料申請」項目の追加・連番リネーム・GridDesign一括改修・改善要望3件の反映)で 実際に使った実例スクリプトが`.claude/js/site-scripts/{プロジェクト名}/`配下(`restructure-site-480111.js` / `apply-to-site-496626.js` / `apply-permission-grant.js`等)に残っている(他プロジェクトには対象サイトの configsデータ自体が存在しないため、これらのスクリプトは置かない)。`apply-permission-grant.js`はSiteId 496626・UserId 579・特定ユーザー名がハードコードされた当時専用の実例であり、汎用ツールではない。 `PROJECT_NAME`/`ENV`もファイル冒頭で当該プロジェクト・当該サーバー環境にハードコード済み (一回限りの過去実行スクリプトのため、`--project`/`--env`引数は取らない)。 **次回別の依頼が来たら、これらをコピーして対象サイトID・`PROJECT_NAME`・`ENV`・フェーズの中身を書き換えて使う** (汎用パラメータ化はしていない。要望ごとに列の増減やチェックリストの中身が違うため、都度スクリプトとして 書き下ろす方が確実)。 ### 全体の流れ 1. **マスターデータ+サイト情報の取得**: `node get-master-data.js` → `node get-site-config.js` (`siteid.json`の`SiteId`を一時的に`"元サイトId,対象サイトId"`にして実行し、終わったら単一IDへ戻す。 `--env`は対象プロジェクトの環境をそのまま指定)。 `InheritPermission`が自サイト以外を指していれば、その継承元サイトも自動的に追いかけて取得される。 2. **抽出済みScripts/Stylesの編集**: 元サイトの`configs/{env}/site-{元SiteId}_.../scripts/*.js`等を直接編集。 ⚠️ここは元サイト自身の抽出フォルダなので、元サイトを`get-site-config.js`で再取得すると 編集内容が消える。編集後は速やかにrestructureスクリプト(次項)を走らせて`modify/`フォルダへ 本文を取り込んでおくこと。 3. **`restructure-site-{元SiteId}.js`(新規作成)**: 元サイトの生JSONを読み込み、 構造変更(列の挿入・連番リネーム・GridDesign書き換え等)を行い、`manifest.json`経由で 編集済みのScripts/Styles本文を組み込んだ上で、対象サイトの`modify/{リクエストラベル}/`フォルダへ `site-{元SiteId}_updated.json`として書き出す(`site-paths.js`の`findSiteDir` / `newModifyDir`を使う)。 同じフォルダへ対象サイトの変更前スナップショット(`before_site-{対象SiteId}_latest.json`)も コピーしておく。書き込み前に、想定した件数増分・重複の有無などの整合性チェックを必ず入れる (実装では「フェーズA:事前ガード」「フェーズH:整合性チェック」として実施した)。 4. **`apply-to-site-{対象SiteId}.js`(新規作成)**: `modify/`フォルダの`site-{元SiteId}_updated.json`を `updatesite`(`Mode:"full"`)で対象サイトへ送る。`Title`/`ReferenceType`/`ParentId`/`InheritPermission`は **対象サイト自身の現状値**から取得し、`SiteSettings`のみ元サイト由来の内容で置き換える。 `Permissions`は送信ボディに含めない(対象サイトが権限を継承している場合、直接の書き込み対象ではないため。 継承有無は`InheritPermission`で判定する)。**`SiteSettings.Links`は元サイトの生JSON値をそのまま含める** (省略厳禁。理由は「厳守事項」節のLinks欠落注意を参照)。デフォルトは差分プレビュー+アーティファクト保存のみ、 `--execute`指定時のみ実際に送信する。差分プレビュー・送信結果は同じ`modify/`フォルダへ保存する。 5. **権限を名前指定で追加する場合**: `apply-permission-grant.js`のパターンで、対象サイトの `InheritPermission`が指す継承元サイトに対して行う(対象サイト自身の`Permissions`は空配列=継承の ままにしておき、直接は変更しない)。`Permissions`はサイトデータ直下の項目で`"Type,Id,PermissionType"` 形式の文字列配列(例: `"User,579,15"`)。`updatesitesettings`(部分更新)APIはPermissionsを更新対象に 含まないことを公式マニュアルで確認済みのため、`updatesite`(全体更新)を使い、継承元サイトの `SiteSettings`等は一切変更せずそのまま再送信しつつ`Permissions`のみ新規エントリを追加する。 ⚠️公式マニュアルには`updatesite`のリクエストボディで`Permissions`を指定できるという明記が 無いため、実行前に必ずプレビュー出力をユーザーに確認してもらうこと。 6. **内容確認 → 実行**: 生成された`modify/`フォルダの中身(`before_*.json` / `site-*_updated.json` / `*_diff_*.txt`)をユーザーに提示、レビューを受けてから`--execute`を実行する。 ## 厳守事項(安全設計、全ツール共通) 以下は破壊的操作の安全ガードに関する規約のため、通常日本語で明記する。 - **`apply-site-config.js`は常にドライラン。Claude自身がAPIへ実送信することはしない** (`ENABLE_ACTUAL_SEND`を有効化する改修や、curlコマンドの代理実行も行わない)。これは変更しない。 - `apply-desired-config-full.js` / `apply-to-site-{対象SiteId}.js` / `apply-permission-grant.js`のような **`--execute`で実際に送信できるスクリプト**は、ユーザーがその場で明示的に「今回は直接実行してよい」と 許可した場合に限り実行してよい。実送信を伴うスクリプトを作る・`--execute`を走らせる前には、 改めてユーザーに差分プレビューを提示し、明示的な許可を得ること。 - `build-desired-config.js`が作る`desired_config.json`は`Mode:"partial"`(`updatesitesettings`)専用。 Scripts/Styles/ServerScripts/Processes以外のサイト設定には触れない。Columns/EditorColumnHash/Sections/ GridColumns/Permissions等の構造変更は、「クロスサイト構造変更」節で説明した`restructure-site-*.js`パターンで行う。 - ガイドHTML(`html/*.html`)は`updatesitesettings`では反映できない(サイト直下の項目のため)。 反映が必要なら`Mode:"full"`(`updatesite`)用の別JSONが要ることをユーザーに伝える。自動生成はしない。 - 抽出したスクリプト・サーバースクリプトの中に**APIキーやWebhook URL等の秘密情報がハードコードされている場合がある** (実例あり)。抽出・編集作業でこれらの値を見つけたら、チャット上にそのまま貼り付けず、ユーザーに直接ファイルを確認してもらう。 また`configs/`フォルダ・`siteSettingJsons/`フォルダ・リポジトリルート直下の`config_production.json`/ `config_development.json`は`.gitignore`済みだが、誤ってコミットしないよう注意喚起する。 - 権限変更・別サイトへの丸ごと上書きはブラスト半径が大きい。実行前に必ず差分プレビューを提示し、 対象サイトIDや継承関係(`InheritPermission`)の理解が誤っていないか、実行のたびに確認する。 - **`updatesite`(`Mode:"full"`)は全置換**。送信ボディで省略した項目は「値なし」として上書きされ消える (`Links`に限らず`Columns`/`GridColumns`/`Processes`等`SiteSettings`配下全項目共通)。フル更新用ボディは 必要項目だけを抜き出して新規に組み立てるのではなく、常に**取得済み生JSON(`getsite`レスポンス)を丸ごと ベースにコピーし、変更箇所だけ差し替える**方式を徹底する。 - **`SiteSettings.Links`(サイト内検索/ルックアップのリンク解決キャッシュ)はフル更新(`Mode:"full"`/ `updatesite`)送信時、省略厳禁**。`Links`は各`Column.ChoicesText`(サイト内検索設定のJSON文字列)から サーバー側が都度自動生成するものではなく、独立フィールドとしてサーバーが保持する。送信ボディで `SiteSettings.Links`キー自体を欠落させると、`ChoicesText`側の内容が正しくても保存後にリンク解決キャッシュが 空になりうる(実例: 営業積算システム SiteId 335410、2026-08-08調査で確認。`Links`空の状態では、 DropDownSearch型項目の入力候補にリンク先レコードの名称ではなく`ChoicesText`の生JSON文字列がそのまま 表示される不具合と一致)。フル更新用ボディを組み立てる際は、取得済み生JSON(`getsite`レスポンス)の `SiteSettings.Links`をそのまま転記し、送信前プレビューで**件数・ColumnName一覧を必ず表示してユーザーに 確認させる**(`build-desired-config.js`は対象外=`Mode:"partial"`専用でLinksに触れないため無関係。 `apply-to-site-*.js`系・その他フル更新スクリプト新規作成時に適用)。反映後は`get-site-config.js`で 再取得し、`SiteSettings.Links`の件数が反映前と一致する(増減が意図通り)ことを確認してから完了報告する。 - **Claude処理で新規にサイト内検索型リンク設定を追加する場合、`Links`エントリも同時に新規追加する**。 Columnの`ChoicesText`へ`SiteId`/`Lookups`形式のJSONを新規に書いた(=新しいリンク項目を追加した)だけでは、 対応する`SiteSettings.Links`配列にエントリが無ければ保存後もリンクは機能しない。`ChoicesText`のJSON構造 (`SiteId`/`View`/`SearchFormat`/`Lookups`等)に`ColumnName`を付与した形で`Links`配列へ変換し、追記する (既存エントリのフォーマットはこのSKILL調査時点の335410実データを参考にできる)。`ChoicesText`だけ追加して `Links`への追記を怠ると、前項の欠落と同じ症状(リンク先レコード名の代わりに定義値の生JSON文字列がそのまま 表示される)が新規追加項目にだけ発生する。