Back to index

Change Impact Assessment

Table
Generates documents
Change Impact Assessment

Seen as a design

Take it with you

Copy and paste, or save a file and hand it over. For a machine with no network, one “Everything” file is enough.

Everything

change-impact-assessment-everything.md

Everything in this panel, including the contents behind each URL, in one Markdown file

Prompt

1.5 KB
Build an HTML document with "Change Impact Assessment". This layout runs, so there is no composition to rebuild — what it needs is content.

## What this layout does
Map current and future states, impact magnitude, readiness, and support actions by affected group.

## What you have to supply
- Define affected groups, current and future states, direction, magnitude, readiness, support, and owner.

## The shape of the input
- `title` — string — 変革の要点
- `subtitle` — string? — 対象範囲・基準日・前提
- `initiative` — string — 対象の施策・変更
- `impacts` — array (3–10) — グループ別の状態変化、影響、準備、支援策

schema.ts holds the machine-checkable validation. Ask rather than guess when an input is missing.

## When not to use it
- Use a risk matrix to assess likelihood and loss magnitude.
- Use a stakeholder engagement plan to define audiences, channels, and timing.

## How to build it
Put the input in a JSON file and run:

```bash
node scripts/render.mjs change-impact-assessment <input.json> --theme ink -o out.html
```

The output is one self-contained file and fetches nothing at render time.

## The source
- https://design-vault.pages.dev/designs/change-impact-assessment/source/template.tsx
- https://design-vault.pages.dev/designs/change-impact-assessment/source/schema.ts
- https://design-vault.pages.dev/designs/change-impact-assessment/source/sample-data.json
- https://design-vault.pages.dev/designs/change-impact-assessment/sample.html

Files

Template, input schema, sample data and metadata. This document was generated from those four. The generated document

template.tsx

8.4 KB

/designs/change-impact-assessment/source/template.tsx

Show contents
import type { Props } from "./schema";

const CSS = String.raw`
.asset-change-impact-assessment{font-family:var(--font-sans);color:var(--color-primary);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:3rem 2.5rem;line-height:1.6;font-size:var(--text-body-sm)}
.asset-change-impact-assessment *{box-sizing:border-box}.asset-change-impact-assessment header{margin-bottom:1.5rem}.asset-change-impact-assessment .eyebrow{font-family:var(--font-mono);font-size:var(--text-label);color:var(--color-tertiary);margin-bottom:.75rem}.asset-change-impact-assessment h1{font-size:var(--text-h1);line-height:1.3;max-width:28em}.asset-change-impact-assessment .subtitle{margin-top:.75rem;color:var(--color-secondary)}
.asset-change-impact-assessment .summary{display:flex;gap:1.5rem;flex-wrap:wrap;padding:.75rem 0;border-block:2px solid var(--color-primary);margin-bottom:1rem}.asset-change-impact-assessment .summary p{margin:0;color:var(--color-secondary);font-size:var(--text-label)}.asset-change-impact-assessment .summary strong{font-family:var(--font-mono);font-size:var(--text-h3);color:var(--color-primary);margin-right:.35rem}
.asset-change-impact-assessment .impact{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.3fr) minmax(0,1.3fr) minmax(0,1.4fr);gap:1rem;padding:1rem 0;border-bottom:1px solid var(--color-outline);min-width:0}.asset-change-impact-assessment .impact>*{min-width:0}.asset-change-impact-assessment .impact-head{display:flex;gap:.55rem;flex-wrap:wrap;align-items:baseline}.asset-change-impact-assessment .impact-id{font-family:var(--font-mono);font-size:var(--text-label);color:var(--color-tertiary)}.asset-change-impact-assessment .impact-head strong{font-size:var(--text-body-md)}.asset-change-impact-assessment .tag{display:inline-block;padding:.1rem .4rem;border:1px solid var(--color-outline);font-size:var(--text-label);color:var(--color-secondary)}.asset-change-impact-assessment .tag-emphasis{border-color:var(--color-tertiary);color:var(--color-primary)}.asset-change-impact-assessment .label{display:block;color:var(--color-secondary);font-size:var(--text-label);margin-bottom:.2rem}.asset-change-impact-assessment .state{overflow-wrap:anywhere}.asset-change-impact-assessment .arrow{display:block;color:var(--color-tertiary);font-size:var(--text-label);margin:.2rem 0}.asset-change-impact-assessment .support{overflow-wrap:anywhere}.asset-change-impact-assessment .owner{display:block;margin-top:.45rem;color:var(--color-secondary);font-size:var(--text-label)}.asset-change-impact-assessment footer{margin-top:1.1rem;padding-top:.7rem;border-top:1px solid var(--color-outline);font-size:var(--text-label);color:var(--color-secondary)}.asset-change-impact-assessment .still-svg{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@media(max-width:760px){.asset-change-impact-assessment{padding:1.5rem 1rem}.asset-change-impact-assessment h1{font-size:var(--text-h2)}.asset-change-impact-assessment .impact{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.75rem;padding:.9rem 0}.asset-change-impact-assessment .impact-meta{grid-column:1/3}.asset-change-impact-assessment .support{grid-column:1/3}.asset-change-impact-assessment .summary{gap:1rem}}
@media(print){.asset-change-impact-assessment{max-width:none;padding:1rem}.asset-change-impact-assessment .impact{break-inside:avoid}}
`;

const areaNames = { process: "業務", role: "役割", technology: "技術", skill: "スキル", policy: "方針", data: "データ" };
const directionNames = { positive: "効果", negative: "負担", mixed: "効果と負担" };
const magnitudeNames = { low: "小", moderate: "中", high: "大", critical: "重大" };
const readinessNames = { ready: "準備済み", "support-needed": "支援が必要", unknown: "未確認" };
const compact = (value: string, max: number) => [...value].length > max ? `${[...value].slice(0, max - 1).join("")}…` : value;

function Still({ data }: { data: Props }) {
  const rows = data.impacts.slice(0, 10);
  const rowHeight = 51;
  return <svg className="still-svg" data-layout-still="true" width="1280" height="720" viewBox="0 0 1280 720" aria-hidden="true">
    <rect width="1280" height="720" fill="var(--color-surface)" />
    <text x="48" y="48" fontSize="14" fontFamily="sans-serif" fill="var(--color-secondary)">{data.initiative}</text>
    <text x="48" y="88" fontSize="28" fontWeight="700" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(data.title, 55)}</text>
    <text x="48" y="118" fontSize="13" fontFamily="sans-serif" fill="var(--color-secondary)">変更前の状態 → 変更後の状態 → 支援策</text>
    <text x="48" y="151" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">対象グループ</text>
    <text x="320" y="151" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">変更前 → 変更後</text>
    <text x="790" y="151" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">影響 / 準備</text>
    <text x="1010" y="151" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">支援策</text>
    {rows.map((impact, index) => {
      const y = 181 + index * rowHeight;
      return <g key={impact.id}>
        <line x1="48" x2="1232" y1={y - 17} y2={y - 17} stroke="var(--color-outline)" />
        <text x="50" y={y + 2} fontSize="10" fontFamily="sans-serif" fill="var(--color-tertiary)">{impact.id}</text>
        <text x="50" y={y + 18} fontSize="12" fontWeight="600" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(impact.affectedGroup, 26)}</text>
        <text x="320" y={y + 2} fontSize="11" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(impact.currentState, 36)}</text>
        <text x="320" y={y + 18} fontSize="10" fontFamily="sans-serif" fill="var(--color-tertiary)">↓ {compact(impact.futureState, 36)}</text>
        <text x="790" y={y + 2} fontSize="11" fontFamily="sans-serif" fill="var(--color-on-surface)">{directionNames[impact.direction]} · {magnitudeNames[impact.magnitude]}</text>
        <text x="790" y={y + 18} fontSize="10" fontFamily="sans-serif" fill="var(--color-secondary)">{areaNames[impact.area]} · {readinessNames[impact.readiness]}</text>
        <text x="1010" y={y + 2} fontSize="11" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(impact.supportAction, 29)}</text>
        <text x="1010" y={y + 18} fontSize="10" fontFamily="sans-serif" fill="var(--color-secondary)">{compact(impact.owner, 22)}</text>
      </g>;
    })}
    <text x="48" y="704" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">{data.impacts.length}件の影響 · 支援策を責任者へつなぐ</text>
  </svg>;
}

export default function Template(data: Props) {
  const supportCount = data.impacts.filter((impact) => impact.readiness !== "ready").length;
  return <section className="asset asset-change-impact-assessment">
    <style>{CSS}</style>
    <header>
      <p className="eyebrow">{data.initiative} · 変更の影響</p>
      <h1>{data.title}</h1>
      {data.subtitle && <p className="subtitle">{data.subtitle}</p>}
    </header>
    <div className="summary" aria-label="影響の集計">
      <p><strong>{data.impacts.length}</strong>影響項目</p>
      <p><strong>{supportCount}</strong>要確認・支援あり</p>
      <p>影響の強さと準備状況を別々に確認</p>
    </div>
    <div>
      {data.impacts.map((impact) => <article className="impact" key={impact.id}>
        <div>
          <div className="impact-head"><code className="impact-id">{impact.id}</code><strong>{impact.affectedGroup}</strong></div>
          <p className="impact-meta"><span className="tag">{areaNames[impact.area]}</span> <span className="tag">{directionNames[impact.direction]}</span> <span className="tag tag-emphasis">影響 {magnitudeNames[impact.magnitude]}</span></p>
        </div>
        <div><span className="label">現在</span><div className="state">{impact.currentState}</div><span className="arrow">変更後</span><div className="state">{impact.futureState}</div></div>
        <div><span className="label">準備状況</span><span className="tag tag-emphasis">{readinessNames[impact.readiness]}</span><p className="owner">支援責任者: {impact.owner}</p></div>
        <div className="support"><span className="label">必要な支援</span>{impact.supportAction}</div>
      </article>)}
    </div>
    <footer>変化の大きさ・方向と、受け入れ準備は別の観点として確認する。</footer>
    <Still data={data} />
  </section>;
}

schema.ts

1.6 KB

/designs/change-impact-assessment/source/schema.ts

Show contents
import { z } from "zod";

const text = z.string().trim().min(1).max(160);
const short = z.string().trim().min(1).max(48);

export const impactSchema = z.object({
  id: short.describe("影響項目の一意な識別子"),
  affectedGroup: short.describe("影響を受ける利用者・チーム"),
  area: z.enum(["process", "role", "technology", "skill", "policy", "data"]).describe("変更が及ぶ領域"),
  currentState: text.describe("変更前の状態"),
  futureState: text.describe("変更後に期待する状態"),
  direction: z.enum(["positive", "negative", "mixed"]).describe("期待効果・負担・両面の別"),
  magnitude: z.enum(["low", "moderate", "high", "critical"]).describe("変化の大きさ"),
  readiness: z.enum(["ready", "support-needed", "unknown"]).describe("受け入れ準備の状態"),
  supportAction: text.describe("移行・習得・負担軽減のための支援"),
  owner: short.describe("支援策の責任者"),
}).strict();

export const schema = z.object({
  title: text.describe("変革の要点"),
  subtitle: text.optional().describe("対象範囲・基準日・前提"),
  initiative: short.describe("対象の施策・変更"),
  impacts: z.array(impactSchema).min(3).max(10).describe("グループ別の変更前後・影響・支援策"),
}).strict().superRefine((data, ctx) => {
  const ids = data.impacts.map((impact) => impact.id);
  if (new Set(ids).size !== ids.length) {
    ctx.addIssue({ code: "custom", path: ["impacts"], message: "影響IDは一意にすること" });
  }
});

export type Props = z.infer<typeof schema>;

meta.yaml

1.7 KB

/designs/change-impact-assessment/source/meta.yaml

Show contents
id: change-impact-assessment
name:
  ja: 変革影響評価
  en: Change Impact Assessment
purpose:
  ja: 対象グループごとに変更前後・影響の大きさ・準備状況と支援策を整理する。
  en: Map current and future states, impact magnitude, readiness, and support actions by affected group.
status: published
still: ./still.png
category: change-management
catalogOrder: 820
jobs:
  - explain-structure
  - assign-governance
useCases:
  - process
layoutKinds:
  - table
tags:
  - change-impact
  - adoption
  - operations
  - offline
  - responsive
whenToUse:
  - ja: 業務変更がグループごとに与える効果・負担と、必要な移行支援を計画するとき。
    en: Use to plan transition support for the benefits and burdens a change creates for each group.
avoidWhen:
  - ja: 発生可能性と損失の大きさを評価する場合は、risk-matrix-registerを使う。
    en: Use a risk matrix to assess likelihood and loss magnitude.
  - ja: 周知相手・連絡手段・日程だけを決める場合は、stakeholder-engagement-planを使う。
    en: Use a stakeholder engagement plan to define audiences, channels, and timing.
requiredInputs:
  - ja: 影響グループ、変更前後の状態、方向・強さ、準備状況、支援策と責任者を定義する。
    en: Define affected groups, current and future states, direction, magnitude, readiness, support, and owner.
relatedLayouts:
  - stakeholder-engagement-plan
  - risk-matrix-register
dataSchema:
  title: string — 変革の要点
  subtitle: string? — 対象範囲・基準日・前提
  initiative: string — 対象の施策・変更
  impacts: array (3–10) — グループ別の状態変化、影響、準備、支援策
sources: []

sample-data.json

2.0 KB

/designs/change-impact-assessment/source/sample-data.json

Show contents
{
  "title": "現場の変化と移行支援をグループごとに整理する",
  "subtitle": "架空の顧客管理刷新|部門ヒアリング後の計画案",
  "initiative": "顧客管理刷新",
  "impacts": [
    {
      "id": "IMP-01",
      "affectedGroup": "営業担当",
      "area": "process",
      "currentState": "顧客情報を複数の表へ手作業で転記する",
      "futureState": "新CRMへ一度入力し、関連部門と共有する",
      "direction": "mixed",
      "magnitude": "high",
      "readiness": "support-needed",
      "supportAction": "実データを使った移行リハーサルと操作演習を行う",
      "owner": "営業企画"
    },
    {
      "id": "IMP-02",
      "affectedGroup": "顧客サポート",
      "area": "technology",
      "currentState": "問い合わせ履歴を個別のチケットで管理する",
      "futureState": "顧客画面から履歴を横断して確認する",
      "direction": "positive",
      "magnitude": "moderate",
      "readiness": "ready",
      "supportAction": "検索手順の変更点を短いガイドにまとめる",
      "owner": "サポート責任者"
    },
    {
      "id": "IMP-03",
      "affectedGroup": "データ管理担当",
      "area": "role",
      "currentState": "各部門が顧客項目を追加・修正する",
      "futureState": "項目変更をデータ管理担当がレビューする",
      "direction": "mixed",
      "magnitude": "high",
      "readiness": "unknown",
      "supportAction": "判断基準と申請経路を共同で定義する",
      "owner": "データ統括"
    },
    {
      "id": "IMP-04",
      "affectedGroup": "支店管理者",
      "area": "skill",
      "currentState": "月次の集計表をローカルで作成する",
      "futureState": "権限に応じた支店レポートを画面で確認する",
      "direction": "positive",
      "magnitude": "low",
      "readiness": "ready",
      "supportAction": "既存集計表との対応関係を説明する",
      "owner": "営業企画"
    }
  ]
}