面談の記録をExcelで作っていると、前回の話や、その後どうなったかを探し直すことになる。ファイルを共有して上位管理者に確認してもらう運用も、更新のたびに手間がかかる。
そこで、面談結果と次回へのフォローアップをプリザンターで管理する構成を考えた。閲覧するのは面談担当リーダーと上位管理者だけ。メンバー本人にはシステム上の閲覧権限を与えない前提だ。
注意:掲載するサイトパッケージは公開仕様とエクスポート例に合わせて作成したテンプレート。実際のPleasanterからエクスポートしたものではなく、対象バージョンへの実機インポート試験も未実施。テスト環境で動作確認し、権限を設定するまで実データを投入しないこと。
┌────────────────────┐
│ 1on1面談管理 │
│ (フォルダ) │
└──────────┬─────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌────────────┐ ┌────────────┐
│メンバー台帳│ │1on1面談記録 │ │フォロー課題 │
│1人1レコード│───▶│1面談1レコード│───▶│1課題1レコード│
└──────────┘ └────────────┘ └────────────┘
| サイト | テーブル種別 | 役割 |
|---|---|---|
| メンバー台帳 | 記録テーブル | 氏名、所属、役割、育成方針、面談リーダー |
| 1on1面談記録 | 記録テーブル | 面談内容、本人の希望、リーダー所見、上位確認 |
| フォローアップ課題 | 期限付きテーブル | 誰が・いつまでに・何をするか |
上の矢印はテーブル間の参照関係を表している。実装では面談記録の ClassA がメンバー台帳を参照し、フォローアップ課題の ClassA が面談記録を参照する。
下書き(100)──[リーダー:確認依頼]──▶ 上位確認待ち(200)
│
┌───────────┴────────────┐
▼ ▼
[管理者:差し戻し] [管理者:確認完了]
│ │
▼ ▼
差し戻し(300) 確認済み(900)
│
[リーダー:修正/再依頼]
│
└──────────▶ 上位確認待ち(200)
| 状況 | コード | 次に操作する人 |
|---|---|---|
| 下書き | 100 | 面談リーダー |
| 上位確認待ち | 200 | 上位管理者 |
| 差し戻し | 300 | 面談リーダー |
| 確認済み | 900 | 原則として編集停止 |
「上位確認」は人事評価の承認ではなく、面談が行われたことと、必要な支援や対応が整理されていることの確認と位置付ける。
| Pleasanterの項目名 | 表示名 |
|---|---|
Title |
氏名 |
ClassA、ClassB |
所属チーム、役割 |
Owner |
面談担当リーダー |
ClassC |
在籍状況 |
DescriptionA、DescriptionB |
育成目標、担当業務 |
DateA、CheckA |
面談開始日、面談対象 |
| Pleasanterの項目名 | 表示名 |
|---|---|
Title / ClassA / DateA |
面談件名 / 面談対象者 / 面談日 |
Owner / Manager |
面談リーダー / 上位確認者 |
ClassB / ClassC |
面談区分 / 本人申告の業務状況 |
DescriptionA |
現在の業務状況 |
DescriptionB |
困っていること・課題 |
DescriptionC |
本人の意向・希望 |
DescriptionD |
リーダー所見 |
DescriptionE |
双方で合意した対応事項 |
DescriptionF |
次回確認事項 |
DescriptionG |
上位管理者コメント・差戻し理由 |
DateB / DateC / DateD |
次回面談予定日 / 確認依頼日時 / 確認完了日時 |
ClassD / CheckA / Status |
確認完了者 / フォロー要否 / 状況 |
本人が話した内容と、リーダー側の見解は別の欄にする。 読み返したときに、誰の認識だったのかが分からなくなることを防ぎたい。
| Pleasanterの項目名 | 表示名 |
|---|---|
Title |
課題・対応事項 |
ClassA / ClassB |
関連面談記録 / 対象メンバー |
Owner / ClassC |
担当リーダー / 対応主体 |
StartTime / CompletionTime |
対応開始日 / 対応期限 |
Status / ProgressRate |
対応状況 / 進捗 |
Body / DescriptionA |
対応内容 / 結果 |
ここでは標準の CompletionTime を 対応期限 として使っている。実際の完了日を追跡したい場合は別項目を追加する。
site-package.json を指定し、サイト・レコード・項目のアクセス制御、通知、リマインダーの取り込みは OFF にする。サイトパッケージは新しいサイトを作る機能であり、既存サイトの上書きには使えない。トップのフォルダが継承する権限にも注意が必要だ。
面談は機密情報を含む。今回はインポート先のユーザーIDやグループIDが分からないため、サイトパッケージに権限設定を埋め込んでいない。導入先で設定する必要がある。
| 利用者 | メンバー台帳 | 面談記録 | フォロー課題 |
|---|---|---|---|
G_1ON1_LEADER |
担当分のみ読取 | 作成+担当記録の読取・更新 | 作成+担当分の読取・更新 |
G_1ON1_MANAGER |
管轄分の読取・更新 | 管轄分の読取・更新 | 管轄分の読取・更新 |
G_1ON1_ADMIN |
管理 | 管理 | 管理 |
| 一般メンバー | 権限なし | 権限なし | 権限なし |
設定の順番
パッケージ中の StatusControls は、ステータスごとの編集画面を制御する補助設定。API、一括更新などの操作を含めた保護には権限の設定・検証が必要だ。
| プロセス | 遷移 | 入力検証・値更新 |
|---|---|---|
| 確認依頼 | 100 → 200 | 対象者/面談日/リーダー/上位確認者/業務状況/合意事項を必須。依頼日時を記録 |
| 再確認依頼 | 300 → 200 | 合意事項を必須 |
| 差し戻し | 200 → 300 | 管理者コメントを必須 |
| 確認完了 | 200 → 900 | 確認日時と確認者を記録 |
プロセスの実行者制限は取り込み後に必ず追加する。ボタンが表示されるからといって権限設計が終わったわけではない。メール通知も実環境の宛先設定が必要なので同梱せず、内容をメール本文に載せずにサイトへのリンクだけを通知する。
Python 3.10以上で次を実行する。
python docs/pleasanter-1on1/validate-package.py
この検査は形式と意図した状態遷移をチェックするもので、実機インポートの成功を保証しない。
ファイル:docs/pleasanter-1on1/site-package.json(省略なし)
{
"HeaderInfo": {
"AssemblyVersion": "1.5.8.1",
"BaseSiteId": 9700000,
"Server": "https://localhost",
"CreatorName": "1on1 template generator (not an actual Pleasanter export)",
"PackageTime": "2026-10-22T00:00:00+09:00",
"Convertors": [
{
"SiteId": 9700000,
"SiteTitle": "1on1面談管理",
"ReferenceType": "Sites",
"IncludeData": false,
"Order": "[9700001,9700002,9700003]"
},
{
"SiteId": 9700001,
"SiteTitle": "メンバー台帳",
"ReferenceType": "Results",
"IncludeData": false
},
{
"SiteId": 9700002,
"SiteTitle": "1on1面談記録",
"ReferenceType": "Results",
"IncludeData": false
},
{
"SiteId": 9700003,
"SiteTitle": "フォローアップ課題",
"ReferenceType": "Issues",
"IncludeData": false
}
],
"IncludeSitePermission": false,
"IncludeRecordPermission": false,
"IncludeColumnPermission": false,
"IncludeNotifications": false,
"IncludeReminders": false
},
"Sites": [
{
"TenantId": 1,
"SiteId": 9700000,
"Title": "1on1面談管理",
"SiteName": "oneonone_9700000",
"SiteGroupName": "",
"Body": "",
"GridGuide": "",
"EditorGuide": "",
"CalendarGuide": "",
"CrosstabGuide": "",
"GanttGuide": "",
"BurnDownGuide": "",
"TimeSeriesGuide": "",
"KambanGuide": "",
"ImageLibGuide": "",
"ReferenceType": "Sites",
"ParentId": 0,
"InheritPermission": 9700000,
"SiteSettings": {
"Version": 1.017,
"ReferenceType": "Sites",
"NoDisplayIfReadOnly": false
},
"Publish": false,
"DisableCrossSearch": true,
"Comments": []
},
{
"TenantId": 1,
"SiteId": 9700001,
"Title": "メンバー台帳",
"SiteName": "oneonone_9700001",
"SiteGroupName": "",
"Body": "",
"GridGuide": "",
"EditorGuide": "",
"CalendarGuide": "",
"CrosstabGuide": "",
"GanttGuide": "",
"BurnDownGuide": "",
"TimeSeriesGuide": "",
"KambanGuide": "",
"ImageLibGuide": "",
"ReferenceType": "Results",
"ParentId": 9700000,
"InheritPermission": 9700001,
"SiteSettings": {
"Version": 1.017,
"ReferenceType": "Results",
"GridColumns": [
"ResultId",
"Title",
"ClassA",
"ClassB",
"Owner",
"ClassC",
"CheckA"
],
"EditorColumnHash": {
"General": [
"ResultId",
"Title",
"ClassA",
"ClassB",
"Owner",
"ClassC",
"DescriptionA",
"DescriptionB",
"DateA",
"CheckA"
]
},
"Columns": [
{
"ColumnName": "Title",
"LabelText": "氏名",
"ValidateRequired": true
},
{
"ColumnName": "ClassA",
"LabelText": "所属チーム",
"ChoicesText": "統合マスタ\nITツール\nその他"
},
{
"ColumnName": "ClassB",
"LabelText": "役割",
"ChoicesText": "新人\n一般\nサブリーダー\nリーダー"
},
{
"ColumnName": "Owner",
"LabelText": "面談担当リーダー"
},
{
"ColumnName": "ClassC",
"LabelText": "在籍状況",
"ChoicesText": "在籍\n異動\n退職"
},
{
"ColumnName": "DescriptionA",
"LabelText": "育成目標"
},
{
"ColumnName": "DescriptionB",
"LabelText": "担当業務"
},
{
"ColumnName": "DateA",
"LabelText": "面談開始日",
"GridFormat": "Ymd"
},
{
"ColumnName": "CheckA",
"LabelText": "面談対象"
}
],
"ImportEncoding": "UTF-8",
"NoDisplayIfReadOnly": false
},
"Publish": false,
"DisableCrossSearch": true,
"Comments": []
},
{
"TenantId": 1,
"SiteId": 9700002,
"Title": "1on1面談記録",
"SiteName": "oneonone_9700002",
"SiteGroupName": "",
"Body": "",
"GridGuide": "",
"EditorGuide": "",
"CalendarGuide": "",
"CrosstabGuide": "",
"GanttGuide": "",
"BurnDownGuide": "",
"TimeSeriesGuide": "",
"KambanGuide": "",
"ImageLibGuide": "",
"ReferenceType": "Results",
"ParentId": 9700000,
"InheritPermission": 9700002,
"SiteSettings": {
"Version": 1.017,
"ReferenceType": "Results",
"GridColumns": [
"ResultId",
"Title",
"ClassA",
"DateA",
"Owner",
"Manager",
"ClassB",
"Status",
"CheckA"
],
"EditorColumnHash": {
"General": [
"ResultId",
"Title",
"ClassA",
"DateA",
"Owner",
"Manager",
"ClassB",
"ClassC",
"DescriptionA",
"DescriptionB",
"DescriptionC",
"DescriptionD",
"DescriptionE",
"DescriptionF",
"DescriptionG",
"DateB",
"DateC",
"DateD",
"ClassD",
"CheckA",
"Status"
]
},
"Columns": [
{
"ColumnName": "Title",
"LabelText": "面談件名",
"ValidateRequired": true
},
{
"ColumnName": "ClassA",
"LabelText": "面談対象者",
"ChoicesText": "[[9700001]]",
"ValidateRequired": true
},
{
"ColumnName": "DateA",
"LabelText": "面談実施日",
"GridFormat": "Ymd",
"ValidateRequired": true
},
{
"ColumnName": "Owner",
"LabelText": "面談リーダー",
"ValidateRequired": true
},
{
"ColumnName": "Manager",
"LabelText": "上位確認者",
"ValidateRequired": true
},
{
"ColumnName": "ClassB",
"LabelText": "面談区分",
"ChoicesText": "定期面談\n臨時面談\n育成面談\nキャリア面談"
},
{
"ColumnName": "ClassC",
"LabelText": "本人申告の業務状況",
"ChoicesText": "順調\n普通\n支援希望"
},
{
"ColumnName": "DescriptionA",
"LabelText": "現在の業務状況"
},
{
"ColumnName": "DescriptionB",
"LabelText": "困っていること・課題"
},
{
"ColumnName": "DescriptionC",
"LabelText": "本人の意向・希望"
},
{
"ColumnName": "DescriptionD",
"LabelText": "リーダー所見"
},
{
"ColumnName": "DescriptionE",
"LabelText": "双方で合意した対応事項"
},
{
"ColumnName": "DescriptionF",
"LabelText": "次回確認事項"
},
{
"ColumnName": "DescriptionG",
"LabelText": "上位管理者コメント・差戻し理由"
},
{
"ColumnName": "DateB",
"LabelText": "次回面談予定日",
"GridFormat": "Ymd"
},
{
"ColumnName": "DateC",
"LabelText": "確認依頼日時",
"GridFormat": "Ymdhm",
"EditorFormat": "Ymdhm"
},
{
"ColumnName": "DateD",
"LabelText": "確認完了日時",
"GridFormat": "Ymdhm",
"EditorFormat": "Ymdhm"
},
{
"ColumnName": "ClassD",
"LabelText": "確認完了者",
"ChoicesText": "[[Users]]"
},
{
"ColumnName": "CheckA",
"LabelText": "フォローアップ必要"
},
{
"ColumnName": "Status",
"LabelText": "面談記録ステータス",
"ChoicesText": "100,下書き\n200,上位確認待ち\n300,差し戻し\n900,確認済み",
"DefaultValue": "100"
}
],
"Processes": [
{
"Id": 1,
"Name": "request_review",
"DisplayName": "確認依頼",
"ScreenType": 20,
"CurrentStatus": 100,
"ChangedStatus": 200,
"ExecutionType": 0,
"ActionType": 0,
"AllowBulkProcessing": false,
"ConfirmationMessage": "上位管理者へ確認を依頼しますか?",
"ValidateInputs": [
{
"Id": 1,
"ColumnName": "ClassA",
"Required": true
},
{
"Id": 2,
"ColumnName": "DateA",
"Required": true
},
{
"Id": 3,
"ColumnName": "Owner",
"Required": true
},
{
"Id": 4,
"ColumnName": "Manager",
"Required": true
},
{
"Id": 5,
"ColumnName": "DescriptionA",
"Required": true
},
{
"Id": 6,
"ColumnName": "DescriptionE",
"Required": true
}
],
"DataChanges": [
{
"Id": 1,
"Type": "InputDateTime",
"ColumnName": "DateC",
"BaseDateTime": "CurrentTime",
"Value": "0,Days"
}
]
},
{
"Id": 2,
"Name": "request_again",
"DisplayName": "再確認依頼",
"ScreenType": 20,
"CurrentStatus": 300,
"ChangedStatus": 200,
"ExecutionType": 0,
"ActionType": 0,
"AllowBulkProcessing": false,
"ValidateInputs": [
{
"Id": 1,
"ColumnName": "DescriptionE",
"Required": true
}
]
},
{
"Id": 3,
"Name": "return_review",
"DisplayName": "差し戻し",
"ScreenType": 20,
"CurrentStatus": 200,
"ChangedStatus": 300,
"ExecutionType": 0,
"ActionType": 0,
"AllowBulkProcessing": false,
"ValidateInputs": [
{
"Id": 1,
"ColumnName": "DescriptionG",
"Required": true
}
]
},
{
"Id": 4,
"Name": "complete_review",
"DisplayName": "確認完了",
"ScreenType": 20,
"CurrentStatus": 200,
"ChangedStatus": 900,
"ExecutionType": 0,
"ActionType": 0,
"AllowBulkProcessing": false,
"DataChanges": [
{
"Id": 1,
"Type": "InputDateTime",
"ColumnName": "DateD",
"BaseDateTime": "CurrentTime",
"Value": "0,Days"
},
{
"Id": 2,
"Type": "InputUser",
"ColumnName": "ClassD"
}
]
}
],
"StatusControls": [
{
"Id": 1,
"Name": "下書き",
"Status": 100,
"ColumnHash": {
"Status": "ReadOnly"
}
},
{
"Id": 2,
"Name": "確認待ち",
"Status": 200,
"ColumnHash": {
"Status": "ReadOnly",
"ClassA": "ReadOnly",
"DateA": "ReadOnly",
"Owner": "ReadOnly",
"DescriptionA": "ReadOnly",
"DescriptionB": "ReadOnly",
"DescriptionC": "ReadOnly",
"DescriptionD": "ReadOnly",
"DescriptionE": "ReadOnly",
"DescriptionF": "ReadOnly"
}
},
{
"Id": 3,
"Name": "差し戻し",
"Status": 300,
"ColumnHash": {
"Status": "ReadOnly"
}
},
{
"Id": 4,
"Name": "確認済み",
"Status": 900,
"ReadOnly": true
}
],
"PermissionForCreating": {
"Owner": 5
},
"PermissionForUpdating": {
"Owner": 5
},
"ImportEncoding": "UTF-8",
"NoDisplayIfReadOnly": false
},
"Publish": false,
"DisableCrossSearch": true,
"Comments": []
},
{
"TenantId": 1,
"SiteId": 9700003,
"Title": "フォローアップ課題",
"SiteName": "oneonone_9700003",
"SiteGroupName": "",
"Body": "",
"GridGuide": "",
"EditorGuide": "",
"CalendarGuide": "",
"CrosstabGuide": "",
"GanttGuide": "",
"BurnDownGuide": "",
"TimeSeriesGuide": "",
"KambanGuide": "",
"ImageLibGuide": "",
"ReferenceType": "Issues",
"ParentId": 9700000,
"InheritPermission": 9700003,
"SiteSettings": {
"Version": 1.017,
"ReferenceType": "Issues",
"GridColumns": [
"IssueId",
"Title",
"ClassA",
"ClassB",
"Owner",
"Status",
"StartTime",
"CompletionTime",
"ProgressRate"
],
"EditorColumnHash": {
"General": [
"IssueId",
"Title",
"ClassA",
"ClassB",
"Owner",
"ClassC",
"StartTime",
"CompletionTime",
"Status",
"ProgressRate",
"Body",
"DescriptionA"
]
},
"Columns": [
{
"ColumnName": "Title",
"LabelText": "課題・対応事項",
"ValidateRequired": true
},
{
"ColumnName": "ClassA",
"LabelText": "関連する面談記録",
"ChoicesText": "[[9700002]]"
},
{
"ColumnName": "ClassB",
"LabelText": "対象メンバー",
"ChoicesText": "[[9700001]]"
},
{
"ColumnName": "Owner",
"LabelText": "担当リーダー"
},
{
"ColumnName": "ClassC",
"LabelText": "対応主体",
"ChoicesText": "本人\nリーダー\nその他"
},
{
"ColumnName": "StartTime",
"LabelText": "対応開始日",
"GridFormat": "Ymd",
"EditorFormat": "Ymd"
},
{
"ColumnName": "CompletionTime",
"LabelText": "対応期限",
"GridFormat": "Ymd",
"EditorFormat": "Ymd"
},
{
"ColumnName": "Body",
"LabelText": "対応内容"
},
{
"ColumnName": "DescriptionA",
"LabelText": "結果・確認事項"
},
{
"ColumnName": "Status",
"LabelText": "対応状況",
"ChoicesText": "100,未着手\n200,対応中\n900,完了",
"DefaultValue": "100"
}
],
"PermissionForCreating": {
"Owner": 5
},
"PermissionForUpdating": {
"Owner": 5
},
"ImportEncoding": "UTF-8",
"NoDisplayIfReadOnly": false
},
"Publish": false,
"DisableCrossSearch": true,
"Comments": []
}
],
"Data": [],
"Permissions": [],
"PermissionIdList": {
"DeptIdList": [],
"GroupIdList": [],
"UserIdList": []
}
}
ファイル:docs/pleasanter-1on1/validate-package.py(省略なし)
#!/usr/bin/env python3
# UTF-8 / Python 3.10+ / 追加依存なし
import json
import sys
from pathlib import Path
EXPECTED = {"Sites": 1, "Results": 2, "Issues": 1}
def main():
path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).with_name("site-package.json")
data = json.loads(path.read_text(encoding="utf-8-sig"))
assert data["HeaderInfo"]["IncludeSitePermission"] is False, "権限を同梱しない方針"
assert data["Data"] == [], "実データを含めないこと"
ids = [site["SiteId"] for site in data["Sites"]]
assert len(ids) == 4 and len(set(ids)) == 4, "サイトIDの重複"
for name, count in EXPECTED.items():
assert sum(s["ReferenceType"] == name for s in data["Sites"]) == count, name
meetings = next(s for s in data["Sites"] if s["Title"] == "1on1面談記録")
conf = meetings["SiteSettings"]
transitions = {(p["CurrentStatus"], p["ChangedStatus"]) for p in conf["Processes"]}
assert transitions == {(100, 200), (300, 200), (200, 300), (200, 900)}
assert conf["StatusControls"][-1]["ReadOnly"] is True
for s in data["Sites"]:
names = [c["ColumnName"] for c in s["SiteSettings"].get("Columns", [])]
assert len(names) == len(set(names)), "項目名重複: " + s["Title"]
print("PASS: JSON構造・テーブル・状態遷移(静的検査)")
print("NOTE: Pleasanter実機でのインポート・権限・動作は未検証")
if __name__ == "__main__":
main()