ken_nogi/ClaudePleasanter/IC(東京)【引継依頼】/.claude/skills/pleasanter-site-spec/SKILL.md
Kenichiro NOGI ed33892f08 chore: 作業中の変更を整理しコミット(複数プロジェクト分)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 11:09:50 +09:00

257 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: pleasanter-site-spec
description: Pleasanterのサイト設定JSONget-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にも対応する。「仕様書を作って」「サイト仕様書」「SiteSettingsをドキュメント化」「スクリプトを抜き出して」「プロセス設定を直して反映して」「別サイトに丸ごと適用して」「項目を追加して連番をズラして」「この人と同じ権限を追加して」「site-spec」等の依頼で使う。
---
# Pleasanter サイト仕様書生成・構成管理
`configs/site-{SiteId}_{サイト名}/sitesettings/site-{SiteId}_latest.json``getsite` APIレスポンス、`Response.Data` 配下にサイト情報)を読み解き、
`configs/site-{SiteId}_{サイト名}/docs/site-{SiteId}_spec.md` として日本語のMarkdown仕様書を出力する。
## フォルダ構成configs/ 配下)
```
configs/
master/ … ユーザー/組織/グループのマスターデータget-master-data.js
master_users.json
master_depts.json
master_groups.json
site-{SiteId}_{サイト名}/
sitesettings/ … getsiteの生JSONget-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 による分割済みファイル(従来通り)
docs/ … 仕様書(.md)や改善要望プラン等、sitesettings以外の関連ドキュメント
modify/{リクエストラベル}/ … 修正依頼のたびに新規作成。変更前後のconfigファイル・
差分プレビュー・送信結果をひとまとめに保管する
```
パス解決は `site-paths.js` に共通化されている(`findSiteDir` / `ensureSiteDir` / `sitesettingsDir` / `docsDir` /
`newModifyDir` / `latestModifyDir` / `latestJsonPath`)。新しいスクリプトを書くときはここを再利用し、
パス組み立てを重複させない。
## 入力の特定
1. ユーザーがJSONファイルパスやSiteIdを指定した場合はそれを使う。
2. 指定がなければ `configs/site-*/sitesettings/site-*_latest.json` を探す。複数ある場合はユーザーに確認する。
3. 対象サイトの `sitesettings/site-{SiteId}_latest.json` が無ければ、先に `node get-site-config.js` の実行を提案する
(エンドポイントは `/api/items/{SiteId}/getsite` を使うこと。`/api/items/{SiteId}/get` はアイテム一覧取得APIであり別物なので注意
## 出力ファイル
`configs/site-{SiteId}_{サイト名}/docs/site-{SiteId}_spec.md`(既存があれば上書きしてよい)。
## 仕様書の構成(この順番・見出しレベルを踏襲する)
```markdown
# サイト仕様書:{Title}SiteId: {SiteId}
- 取得元データ: [site-{SiteId}_latest.json](../sitesettings/site-{SiteId}_latest.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 項目ごとの補足HTMLExtendedHtmlAfterControl
(該当項目があれば 列名/色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等)/成功メッセージ を表で)
## 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 | 状態 |
| {対象}IdResultId, IssueId等 | 自動採番ID |
| Title | タイトル |
| Comments | コメント欄 |
「予定/実行/無し/備考」の4列1組パターン`DateNNN`/`Date(NNN+100)`/`Check(NNN+100)`/`ClassNNN`、NNNは3桁ゼロ埋め連番
繰り返し登場するサイトもある。この場合 `DateNNN.Description` が入力担当(部署名等)、`DateNNN.GridLabelText` が
項目の表示名を表す。詳細は下記「クロスサイト構造変更(新項目追加・連番リネーム)」を参照。
## 注意事項
- SiteSettingsに存在しない項目・空の設定例: `ClassHash`, `NumHash` などのラベル定義ハッシュが `{}`)は
「標準ラベルのまま」として仕様書に明記し、存在しないかのように省略しない。
- 表形式を基本とし、箇条書きより表を優先する(今回のレビューで「編集画面レイアウトは項目名とラベル名を併記」との
指摘を受けた経緯があるため、内部名とラベル名は必ず併記する)。
- 出力言語は日本語。
## 関連ツールScripts/Styles/ServerScripts/Processesの抽出・編集・反映
仕様書化とは別に、「スクリプトを個別ファイルに分けて」「プロセス設定を直して反映して」等の依頼では、
以下のツールチェーンを使う(詳細は `README.md` 参照)。
1. `node get-site-config.js``configs/site-{SiteId}_{サイト名}/sitesettings/site-{SiteId}_latest.json` を取得し、
続けて自動的に抽出も行う(`extract-site-config.js` が内部から呼ばれ、`configs/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の対応表。再構成に必須
- `config.json``SiteId` はカンマ区切りで複数指定可能。また、取得したサイトの `InheritPermission`
自サイト以外を指している場合、権限の実体を持つそのサイトも自動的に追いかけて取得する(後述)。
- 抽出だけをやり直したい場合(`latest.json`は既に取得済み)は `node extract-site-config.js` を単独実行してもよい
- **注意**: `get-site-config.js` を再実行すると、その時点のサイトの生の状態で `scripts/` `styles/` 等が
上書きされる。あるサイトの内容を「別サイトへ適用するための下書き」として編集している最中に、
同じサイトへ `get-site-config.js` を再実行すると編集内容が失われるので、クロスサイト作業中は
むやみに元サイトを再取得しない(詳しくは後述の「クロスサイト構造変更」参照)。
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コマンドをユーザー自身が手動実行する
## 関連ツール:ユーザー/組織/グループのマスターデータ取得
権限Permissionsやスクリプト内の担当者振り分けなどをID表記ではなく名前で扱いたい場合に使う。
1. `node get-master-data.js``configs/master/` へ以下を取得・保存する(ページング自動対応。
`/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)` … 3つの `master_*.json` を読み込む
- `resolveName(master, { Type: "User"|"Dept"|"Group", Id })` … IDから名前を引く
- `resolveId(master, { Type, Name })` … 名前から一致するIDの配列を引く完全一致。0件/複数件はエラーとして扱う)
## 関連ツール:クロスサイト構造変更(項目追加・連番リネーム・別サイトへの丸ごと適用)
「Aサイトを土台に項目を追加してBサイトへ適用して」「この項目の後ろに新しい項目を追加して、以降の連番を
ズラして」のような依頼で使うパターン。2026-07-16に SiteId 480111 → 496626 への適用(「解体紹介料申請」項目の
追加・連番リネーム・GridDesign一括改修・改善要望3件の反映で実際に使った構成を一般化したもの。
`restructure-site-480111.js` / `apply-to-site-496626.js` / `apply-permission-grant.js` は、その際の実例
(そのまま次回動かせるテンプレートとして残っている)。**次回別の依頼が来たら、これらをコピーして
対象サイトIDやフェーズの中身を書き換えて使う**(汎用パラメータ化はしていない。要望ごとに列の増減や
チェックリストの中身が違うため、都度スクリプトとして書き下ろす方が確実)。
### 全体の流れ
1. **マスターデータ+サイト情報の取得**: `node get-master-data.js``node get-site-config.js`
`config.json` の `SiteId` を一時的に `"元サイトId,対象サイトId"` にして実行し、終わったら単一IDへ戻す
`InheritPermission` が自サイト以外を指していれば、その継承元サイトも自動的に追いかけて取得される。
2. **抽出済みScripts/Stylesの編集**: 元サイトの `configs/site-{元SiteId}_.../scripts/*.js` 等を直接編集する。
⚠️ ここは元サイト自身の抽出フォルダなので、元サイトを `get-site-config.js` で再取得すると
編集内容が消える。編集後は速やかに restructure スクリプト(次項)を走らせて `modify/` フォルダへ
本文を取り込んでおくこと。
3. **`restructure-site-{元SiteId}.js`(新規作成)**: 元サイトの `sitesettings/latest.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` で判定する)。デフォルトは差分プレビュー+アーティファクト保存のみ、
`--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-to-site-{対象SiteId}.js` / `apply-permission-grant.js` のような**専用の直接実行スクリプト**は、
ユーザーがその場で明示的に「今回は直接実行してよい」と許可した場合に限り作成・実行してよい
2026-07-16の実例。これは **その依頼一回限りの例外** であり、標準運用(ドライラン+手動反映)を
恒久的に変更するものではない。次回以降も、実送信を伴うスクリプトを作る/`--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/` フォルダと `config.json``.gitignore` 済みだが、誤ってコミットしないよう注意喚起する。
- 権限変更・別サイトへの丸ごと上書きはブラスト半径が大きい。実行前に必ず差分プレビューを提示し、
対象サイトIDや継承関係`InheritPermission`)の理解が誤っていないか、実行のたびに確認する。