@k2works/claude-code-booster 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/.claude/scripts/generate-inception-deck.mjs +1024 -0
- package/lib/assets/.claude/skills/analyzing-inception-deck/SKILL.md +137 -0
- package/lib/assets/.claude/skills/generating-slides/SKILL.md +106 -0
- package/lib/assets/.claude/skills/orchestrating-analysis/SKILL.md +19 -12
- package/lib/assets/CLAUDE.md +2 -3
- package/lib/assets/README.md +1 -1
- package/lib/assets/docs/template//343/202/244/343/203/263/343/202/273/343/203/227/343/202/267/343/203/247/343/203/263/343/203/207/343/203/203/343/202/255.pptx +0 -0
- package/lib/assets/ops/nix/shells/.vimrc +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,1024 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HCOSS インセプションデッキ PowerPoint 生成スクリプト
|
|
3
|
+
*
|
|
4
|
+
* テンプレート: docs/template/インセプションデッキ.pptx のスライド構成に準拠
|
|
5
|
+
* データソース: docs/analysis/inception-deck.md, docs/analysis/business_architecture.md
|
|
6
|
+
*/
|
|
7
|
+
import PptxGenJS from "pptxgenjs";
|
|
8
|
+
import { writeFileSync } from "fs";
|
|
9
|
+
import { resolve } from "path";
|
|
10
|
+
|
|
11
|
+
// ── テーマ設定(テンプレートから抽出) ──
|
|
12
|
+
const COLORS = {
|
|
13
|
+
black: "000000",
|
|
14
|
+
white: "FFFFFF",
|
|
15
|
+
darkBlue: "333399",
|
|
16
|
+
teal: "009999",
|
|
17
|
+
lightTeal: "BBE0E3",
|
|
18
|
+
paleBlue: "DAEDEF",
|
|
19
|
+
green: "99CC00",
|
|
20
|
+
gray: "808080",
|
|
21
|
+
lightGray: "D0D0D0",
|
|
22
|
+
orange: "FF6600",
|
|
23
|
+
red: "CC3333",
|
|
24
|
+
yellow: "FFCC00",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const FONT = {
|
|
28
|
+
title: "Yu Gothic",
|
|
29
|
+
body: "Yu Gothic",
|
|
30
|
+
code: "Courier New",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// ── ヘルパー ──
|
|
34
|
+
function titleSlideOpts(title, subtitle) {
|
|
35
|
+
return {
|
|
36
|
+
color: COLORS.white,
|
|
37
|
+
fontFace: FONT.title,
|
|
38
|
+
bold: true,
|
|
39
|
+
fontSize: subtitle ? 32 : 40,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function addTitle(slide, text) {
|
|
44
|
+
slide.addText(text, {
|
|
45
|
+
x: 0.5,
|
|
46
|
+
y: 0.2,
|
|
47
|
+
w: 9.0,
|
|
48
|
+
h: 1.0,
|
|
49
|
+
fontSize: 28,
|
|
50
|
+
fontFace: FONT.title,
|
|
51
|
+
bold: true,
|
|
52
|
+
color: COLORS.darkBlue,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function addSubtitle(slide, text) {
|
|
57
|
+
slide.addText(text, {
|
|
58
|
+
x: 0.5,
|
|
59
|
+
y: 1.1,
|
|
60
|
+
w: 9.0,
|
|
61
|
+
h: 0.5,
|
|
62
|
+
fontSize: 14,
|
|
63
|
+
fontFace: FONT.body,
|
|
64
|
+
color: COLORS.gray,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function addBullets(slide, items, opts = {}) {
|
|
69
|
+
const top = opts.y ?? 1.6;
|
|
70
|
+
const textRows = items.map((item) => ({
|
|
71
|
+
text: item,
|
|
72
|
+
options: {
|
|
73
|
+
fontSize: opts.fontSize ?? 14,
|
|
74
|
+
fontFace: FONT.body,
|
|
75
|
+
color: opts.color ?? COLORS.black,
|
|
76
|
+
bullet: { type: "bullet" },
|
|
77
|
+
paraSpaceAfter: 6,
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
slide.addText(textRows, {
|
|
81
|
+
x: opts.x ?? 0.7,
|
|
82
|
+
y: top,
|
|
83
|
+
w: opts.w ?? 8.6,
|
|
84
|
+
h: opts.h ?? 5.5 - (top - 1.0),
|
|
85
|
+
valign: "top",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function addTable(slide, header, rows, opts = {}) {
|
|
90
|
+
const top = opts.y ?? 1.8;
|
|
91
|
+
const tableData = [
|
|
92
|
+
header.map((h) => ({
|
|
93
|
+
text: h,
|
|
94
|
+
options: {
|
|
95
|
+
bold: true,
|
|
96
|
+
fontSize: 11,
|
|
97
|
+
fontFace: FONT.body,
|
|
98
|
+
color: COLORS.white,
|
|
99
|
+
fill: { color: COLORS.darkBlue },
|
|
100
|
+
align: "left",
|
|
101
|
+
valign: "middle",
|
|
102
|
+
},
|
|
103
|
+
})),
|
|
104
|
+
...rows.map((row) =>
|
|
105
|
+
row.map((cell) => ({
|
|
106
|
+
text: cell,
|
|
107
|
+
options: {
|
|
108
|
+
fontSize: 10,
|
|
109
|
+
fontFace: FONT.body,
|
|
110
|
+
color: COLORS.black,
|
|
111
|
+
align: "left",
|
|
112
|
+
valign: "top",
|
|
113
|
+
},
|
|
114
|
+
}))
|
|
115
|
+
),
|
|
116
|
+
];
|
|
117
|
+
slide.addTable(tableData, {
|
|
118
|
+
x: opts.x ?? 0.5,
|
|
119
|
+
y: top,
|
|
120
|
+
w: opts.w ?? 9.0,
|
|
121
|
+
colW: opts.colW,
|
|
122
|
+
border: { type: "solid", pt: 0.5, color: COLORS.lightGray },
|
|
123
|
+
rowH: opts.rowH,
|
|
124
|
+
autoPage: false,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function addHighlightBox(slide, text, opts = {}) {
|
|
129
|
+
slide.addText(text, {
|
|
130
|
+
x: opts.x ?? 0.5,
|
|
131
|
+
y: opts.y ?? 1.5,
|
|
132
|
+
w: opts.w ?? 9.0,
|
|
133
|
+
h: opts.h ?? 1.0,
|
|
134
|
+
fontSize: opts.fontSize ?? 16,
|
|
135
|
+
fontFace: FONT.body,
|
|
136
|
+
color: COLORS.darkBlue,
|
|
137
|
+
bold: true,
|
|
138
|
+
fill: { color: COLORS.paleBlue },
|
|
139
|
+
align: "center",
|
|
140
|
+
valign: "middle",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function addSliderBar(slide, label, level, y) {
|
|
145
|
+
// level: 1-4 (1=MIN, 4=MAX)
|
|
146
|
+
const barX = 3.5;
|
|
147
|
+
const barW = 5.0;
|
|
148
|
+
const segW = barW / 4;
|
|
149
|
+
|
|
150
|
+
slide.addText(label, {
|
|
151
|
+
x: 0.5,
|
|
152
|
+
y,
|
|
153
|
+
w: 3.0,
|
|
154
|
+
h: 0.45,
|
|
155
|
+
fontSize: 11,
|
|
156
|
+
fontFace: FONT.body,
|
|
157
|
+
color: COLORS.black,
|
|
158
|
+
valign: "middle",
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < 4; i++) {
|
|
162
|
+
const isFilled = i < level;
|
|
163
|
+
slide.addShape("rect", {
|
|
164
|
+
x: barX + i * segW,
|
|
165
|
+
y: y + 0.05,
|
|
166
|
+
w: segW - 0.05,
|
|
167
|
+
h: 0.35,
|
|
168
|
+
fill: { color: isFilled ? COLORS.darkBlue : COLORS.lightGray },
|
|
169
|
+
line: { color: COLORS.gray, width: 0.5 },
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
slide.addText("MIN", {
|
|
174
|
+
x: barX - 0.05,
|
|
175
|
+
y: y + 0.38,
|
|
176
|
+
w: 0.5,
|
|
177
|
+
h: 0.2,
|
|
178
|
+
fontSize: 7,
|
|
179
|
+
fontFace: FONT.body,
|
|
180
|
+
color: COLORS.gray,
|
|
181
|
+
});
|
|
182
|
+
slide.addText("MAX", {
|
|
183
|
+
x: barX + barW - 0.45,
|
|
184
|
+
y: y + 0.38,
|
|
185
|
+
w: 0.5,
|
|
186
|
+
h: 0.2,
|
|
187
|
+
fontSize: 7,
|
|
188
|
+
fontFace: FONT.body,
|
|
189
|
+
color: COLORS.gray,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ── メイン ──
|
|
194
|
+
async function main() {
|
|
195
|
+
const pptx = new PptxGenJS();
|
|
196
|
+
pptx.defineLayout({ name: "SCREEN_4x3", width: 10, height: 7.5 });
|
|
197
|
+
pptx.layout = "SCREEN_4x3";
|
|
198
|
+
pptx.author = "HCOSS Project";
|
|
199
|
+
pptx.title = "HCOSS インセプションデッキ v0.1.0";
|
|
200
|
+
|
|
201
|
+
// ───────────────────────────────────────
|
|
202
|
+
// Slide 1: タイトル
|
|
203
|
+
// ───────────────────────────────────────
|
|
204
|
+
{
|
|
205
|
+
const slide = pptx.addSlide();
|
|
206
|
+
slide.background = { color: COLORS.darkBlue };
|
|
207
|
+
slide.addText(
|
|
208
|
+
[
|
|
209
|
+
{
|
|
210
|
+
text: "HCOSS",
|
|
211
|
+
options: {
|
|
212
|
+
fontSize: 48,
|
|
213
|
+
fontFace: FONT.title,
|
|
214
|
+
bold: true,
|
|
215
|
+
color: COLORS.white,
|
|
216
|
+
breakLine: true,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
text: "統合業務管理システム",
|
|
221
|
+
options: {
|
|
222
|
+
fontSize: 28,
|
|
223
|
+
fontFace: FONT.title,
|
|
224
|
+
color: COLORS.lightTeal,
|
|
225
|
+
breakLine: true,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
text: "インセプションデッキ",
|
|
230
|
+
options: {
|
|
231
|
+
fontSize: 24,
|
|
232
|
+
fontFace: FONT.title,
|
|
233
|
+
color: COLORS.white,
|
|
234
|
+
breakLine: true,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
{ x: 1.0, y: 1.5, w: 8.0, h: 3.5, align: "center", valign: "middle" }
|
|
239
|
+
);
|
|
240
|
+
slide.addText("ヘルシーカンパニー株式会社", {
|
|
241
|
+
x: 1.0,
|
|
242
|
+
y: 5.5,
|
|
243
|
+
w: 8.0,
|
|
244
|
+
h: 0.5,
|
|
245
|
+
fontSize: 16,
|
|
246
|
+
fontFace: FONT.body,
|
|
247
|
+
color: COLORS.lightTeal,
|
|
248
|
+
align: "center",
|
|
249
|
+
});
|
|
250
|
+
slide.addText("v0.1.0 | 2026-02-27", {
|
|
251
|
+
x: 1.0,
|
|
252
|
+
y: 6.2,
|
|
253
|
+
w: 8.0,
|
|
254
|
+
h: 0.4,
|
|
255
|
+
fontSize: 12,
|
|
256
|
+
fontFace: FONT.body,
|
|
257
|
+
color: COLORS.gray,
|
|
258
|
+
align: "center",
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ───────────────────────────────────────
|
|
263
|
+
// Slide 2: 我われはなぜここにいるのか
|
|
264
|
+
// ───────────────────────────────────────
|
|
265
|
+
{
|
|
266
|
+
const slide = pptx.addSlide();
|
|
267
|
+
addTitle(slide, "我われはなぜここにいるのか");
|
|
268
|
+
addSubtitle(
|
|
269
|
+
slide,
|
|
270
|
+
"正社員 6 名・パート 10 名の小規模体制で 4 つのショッピングモールを運営する課題"
|
|
271
|
+
);
|
|
272
|
+
addBullets(slide, [
|
|
273
|
+
"受注管理の分散:4 モールからの受注データが統合されておらず、個別処理の非効率が発生",
|
|
274
|
+
"在庫管理の複雑性:自社在庫と Amazon FBA 在庫の二元管理が手作業中心",
|
|
275
|
+
"データ分析の不在:売上・顧客データの分析基盤がなく、データに基づく意思決定ができていない",
|
|
276
|
+
"マーケティング戦略の未整備:効果的なマーケティング施策を立案・実行できていない",
|
|
277
|
+
"コーポレートサイトの活用不足:企業情報・製造所情報の発信が不十分",
|
|
278
|
+
]);
|
|
279
|
+
|
|
280
|
+
addHighlightBox(slide, "小規模組織の手作業の限界が、業務の品質と効率を圧迫している", {
|
|
281
|
+
y: 5.8,
|
|
282
|
+
h: 0.7,
|
|
283
|
+
fontSize: 14,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ───────────────────────────────────────
|
|
288
|
+
// Slide 3: エレベーターピッチ
|
|
289
|
+
// ───────────────────────────────────────
|
|
290
|
+
{
|
|
291
|
+
const slide = pptx.addSlide();
|
|
292
|
+
addTitle(slide, "エレベーターピッチ");
|
|
293
|
+
|
|
294
|
+
const pitchParts = [
|
|
295
|
+
{
|
|
296
|
+
text: "マルチモール運営を効率化",
|
|
297
|
+
options: {
|
|
298
|
+
fontSize: 14,
|
|
299
|
+
fontFace: FONT.body,
|
|
300
|
+
color: COLORS.darkBlue,
|
|
301
|
+
bold: true,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
text: " したい\n",
|
|
306
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
text: "正社員 6 名・パート 10 名の小規模食品加工業者",
|
|
310
|
+
options: {
|
|
311
|
+
fontSize: 14,
|
|
312
|
+
fontFace: FONT.body,
|
|
313
|
+
color: COLORS.darkBlue,
|
|
314
|
+
bold: true,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
text: " 向けの、\n",
|
|
319
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
text: "HCOSS(統合業務管理システム)",
|
|
323
|
+
options: {
|
|
324
|
+
fontSize: 14,
|
|
325
|
+
fontFace: FONT.body,
|
|
326
|
+
color: COLORS.darkBlue,
|
|
327
|
+
bold: true,
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
text: " というプロダクトは、\n",
|
|
332
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
text: "マルチモール統合業務管理システム",
|
|
336
|
+
options: {
|
|
337
|
+
fontSize: 14,
|
|
338
|
+
fontFace: FONT.body,
|
|
339
|
+
color: COLORS.darkBlue,
|
|
340
|
+
bold: true,
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
text: " です。\nこれは ",
|
|
345
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
text: "4 モールの受注・在庫・出荷を統合管理し、\n食品トレーサビリティを一貫して管理",
|
|
349
|
+
options: {
|
|
350
|
+
fontSize: 14,
|
|
351
|
+
fontFace: FONT.body,
|
|
352
|
+
color: COLORS.darkBlue,
|
|
353
|
+
bold: true,
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
text: " ができ、\n",
|
|
358
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
text: "各モール個別の手作業管理",
|
|
362
|
+
options: {
|
|
363
|
+
fontSize: 14,
|
|
364
|
+
fontFace: FONT.body,
|
|
365
|
+
color: COLORS.darkBlue,
|
|
366
|
+
bold: true,
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
text: " とは違って、\n",
|
|
371
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
text: "シンプルで運用負荷の低い統合基盤",
|
|
375
|
+
options: {
|
|
376
|
+
fontSize: 14,
|
|
377
|
+
fontFace: FONT.body,
|
|
378
|
+
color: COLORS.darkBlue,
|
|
379
|
+
bold: true,
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
text: " が備わっている。",
|
|
384
|
+
options: { fontSize: 14, fontFace: FONT.body, color: COLORS.black },
|
|
385
|
+
},
|
|
386
|
+
];
|
|
387
|
+
|
|
388
|
+
slide.addText(pitchParts, {
|
|
389
|
+
x: 0.8,
|
|
390
|
+
y: 1.5,
|
|
391
|
+
w: 8.4,
|
|
392
|
+
h: 4.5,
|
|
393
|
+
fill: { color: COLORS.paleBlue },
|
|
394
|
+
valign: "middle",
|
|
395
|
+
paraSpaceAfter: 8,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ───────────────────────────────────────
|
|
400
|
+
// Slide 4: どんな価値をもたらすのか?
|
|
401
|
+
// ───────────────────────────────────────
|
|
402
|
+
{
|
|
403
|
+
const slide = pptx.addSlide();
|
|
404
|
+
addTitle(slide, "どんな価値をもたらすのか?");
|
|
405
|
+
addTable(
|
|
406
|
+
slide,
|
|
407
|
+
["#", "ビジネス目標", "期待される効果"],
|
|
408
|
+
[
|
|
409
|
+
["1", "マルチモール受注の統合管理", "4 モールの受注を一元管理し、処理時間を短縮"],
|
|
410
|
+
[
|
|
411
|
+
"2",
|
|
412
|
+
"在庫の統合管理",
|
|
413
|
+
"自社在庫と FBA 在庫を統合管理し、在庫切れ・過剰在庫を防止",
|
|
414
|
+
],
|
|
415
|
+
[
|
|
416
|
+
"3",
|
|
417
|
+
"トレーサビリティの確保",
|
|
418
|
+
"原材料から出荷までの追跡で食品安全基準への対応を強化",
|
|
419
|
+
],
|
|
420
|
+
[
|
|
421
|
+
"4",
|
|
422
|
+
"データに基づく意思決定",
|
|
423
|
+
"売上・顧客データの分析基盤を構築しマーケティング戦略を立案可能に",
|
|
424
|
+
],
|
|
425
|
+
[
|
|
426
|
+
"5",
|
|
427
|
+
"業務効率の向上",
|
|
428
|
+
"手作業を削減し、小規模体制でも持続可能な業務運営を実現",
|
|
429
|
+
],
|
|
430
|
+
[
|
|
431
|
+
"6",
|
|
432
|
+
"顧客満足度の向上",
|
|
433
|
+
"迅速かつ正確な受注・出荷処理により顧客体験を改善",
|
|
434
|
+
],
|
|
435
|
+
],
|
|
436
|
+
{ colW: [0.4, 3.0, 5.6] }
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ───────────────────────────────────────
|
|
441
|
+
// Slide 5: やらないことリスト(スコープ)
|
|
442
|
+
// ───────────────────────────────────────
|
|
443
|
+
{
|
|
444
|
+
const slide = pptx.addSlide();
|
|
445
|
+
addTitle(slide, "やらないことリスト");
|
|
446
|
+
addSubtitle(slide, "スコープの範囲");
|
|
447
|
+
|
|
448
|
+
// Three columns
|
|
449
|
+
const colW = 2.85;
|
|
450
|
+
const colGap = 0.15;
|
|
451
|
+
const cols = [
|
|
452
|
+
{
|
|
453
|
+
title: "やる(スコープ内)",
|
|
454
|
+
color: COLORS.teal,
|
|
455
|
+
items: [
|
|
456
|
+
"マルチモール受注管理",
|
|
457
|
+
"在庫管理(自社 + FBA)",
|
|
458
|
+
"出荷管理",
|
|
459
|
+
"商品管理",
|
|
460
|
+
"品質管理・トレーサビリティ",
|
|
461
|
+
"調達管理",
|
|
462
|
+
"売上・顧客データ分析",
|
|
463
|
+
"カスタマーサポート管理",
|
|
464
|
+
],
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
title: "やらない(スコープ外)",
|
|
468
|
+
color: COLORS.red,
|
|
469
|
+
items: [
|
|
470
|
+
"財務・会計管理",
|
|
471
|
+
"人事・労務管理",
|
|
472
|
+
"コーポレートサイトの構築",
|
|
473
|
+
"モール API 以外の外部連携",
|
|
474
|
+
],
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
title: "あとで決める",
|
|
478
|
+
color: COLORS.orange,
|
|
479
|
+
items: [
|
|
480
|
+
"外部製造委託管理の範囲",
|
|
481
|
+
"製造所固有記号管理",
|
|
482
|
+
"マーケティング自動化",
|
|
483
|
+
],
|
|
484
|
+
},
|
|
485
|
+
];
|
|
486
|
+
|
|
487
|
+
cols.forEach((col, i) => {
|
|
488
|
+
const x = 0.5 + i * (colW + colGap);
|
|
489
|
+
slide.addText(col.title, {
|
|
490
|
+
x,
|
|
491
|
+
y: 1.7,
|
|
492
|
+
w: colW,
|
|
493
|
+
h: 0.45,
|
|
494
|
+
fontSize: 13,
|
|
495
|
+
fontFace: FONT.body,
|
|
496
|
+
bold: true,
|
|
497
|
+
color: COLORS.white,
|
|
498
|
+
fill: { color: col.color },
|
|
499
|
+
align: "center",
|
|
500
|
+
valign: "middle",
|
|
501
|
+
});
|
|
502
|
+
const bullets = col.items.map((item) => ({
|
|
503
|
+
text: item,
|
|
504
|
+
options: {
|
|
505
|
+
fontSize: 11,
|
|
506
|
+
fontFace: FONT.body,
|
|
507
|
+
color: COLORS.black,
|
|
508
|
+
bullet: { type: "bullet" },
|
|
509
|
+
paraSpaceAfter: 4,
|
|
510
|
+
},
|
|
511
|
+
}));
|
|
512
|
+
slide.addText(bullets, {
|
|
513
|
+
x,
|
|
514
|
+
y: 2.2,
|
|
515
|
+
w: colW,
|
|
516
|
+
h: 4.8,
|
|
517
|
+
valign: "top",
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// ───────────────────────────────────────
|
|
523
|
+
// Slide 6: 主なステークホルダー
|
|
524
|
+
// ───────────────────────────────────────
|
|
525
|
+
{
|
|
526
|
+
const slide = pptx.addSlide();
|
|
527
|
+
addTitle(slide, "プロジェクトコミュニティ");
|
|
528
|
+
addSubtitle(slide, "主なステークホルダーと関心事");
|
|
529
|
+
addTable(
|
|
530
|
+
slide,
|
|
531
|
+
["ステークホルダー", "役割", "主な関心事"],
|
|
532
|
+
[
|
|
533
|
+
[
|
|
534
|
+
"経営者",
|
|
535
|
+
"プロジェクトオーナー",
|
|
536
|
+
"投資対効果、業務効率化、売上向上",
|
|
537
|
+
],
|
|
538
|
+
[
|
|
539
|
+
"販売部門",
|
|
540
|
+
"主要ユーザー",
|
|
541
|
+
"受注・出荷業務の効率化、在庫可視化",
|
|
542
|
+
],
|
|
543
|
+
[
|
|
544
|
+
"製造部門",
|
|
545
|
+
"ユーザー",
|
|
546
|
+
"在庫引当の正確性、品質管理の効率化",
|
|
547
|
+
],
|
|
548
|
+
["顧客", "エンドユーザー", "正確な在庫情報、迅速な配送"],
|
|
549
|
+
[
|
|
550
|
+
"提携製造所",
|
|
551
|
+
"外部パートナー",
|
|
552
|
+
"製造指示の明確化、納品プロセスの効率化",
|
|
553
|
+
],
|
|
554
|
+
[
|
|
555
|
+
"モール運営会社",
|
|
556
|
+
"プラットフォーム",
|
|
557
|
+
"API 連携の安定性、商品情報の正確性",
|
|
558
|
+
],
|
|
559
|
+
[
|
|
560
|
+
"配送業者",
|
|
561
|
+
"外部パートナー",
|
|
562
|
+
"出荷情報の正確性、集荷スケジュールの安定",
|
|
563
|
+
],
|
|
564
|
+
],
|
|
565
|
+
{ y: 1.7, colW: [2.0, 2.2, 4.8] }
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// ───────────────────────────────────────
|
|
570
|
+
// Slide 7: 技術的な解決策の概要
|
|
571
|
+
// ───────────────────────────────────────
|
|
572
|
+
{
|
|
573
|
+
const slide = pptx.addSlide();
|
|
574
|
+
addTitle(slide, "技術的な解決策の概要");
|
|
575
|
+
|
|
576
|
+
// Architecture diagram using shapes
|
|
577
|
+
const boxH = 0.5;
|
|
578
|
+
|
|
579
|
+
// Mall boxes at top
|
|
580
|
+
const malls = ["楽天市場", "Yahoo!", "Amazon", "au PAY"];
|
|
581
|
+
malls.forEach((name, i) => {
|
|
582
|
+
slide.addShape("rect", {
|
|
583
|
+
x: 0.5 + i * 2.2,
|
|
584
|
+
y: 1.5,
|
|
585
|
+
w: 2.0,
|
|
586
|
+
h: boxH,
|
|
587
|
+
fill: { color: COLORS.lightTeal },
|
|
588
|
+
line: { color: COLORS.teal, width: 1 },
|
|
589
|
+
});
|
|
590
|
+
slide.addText(name, {
|
|
591
|
+
x: 0.5 + i * 2.2,
|
|
592
|
+
y: 1.5,
|
|
593
|
+
w: 2.0,
|
|
594
|
+
h: boxH,
|
|
595
|
+
fontSize: 10,
|
|
596
|
+
fontFace: FONT.body,
|
|
597
|
+
color: COLORS.black,
|
|
598
|
+
align: "center",
|
|
599
|
+
valign: "middle",
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
// Arrow label
|
|
604
|
+
slide.addText("API", {
|
|
605
|
+
x: 4.0,
|
|
606
|
+
y: 2.05,
|
|
607
|
+
w: 1.0,
|
|
608
|
+
h: 0.3,
|
|
609
|
+
fontSize: 9,
|
|
610
|
+
fontFace: FONT.body,
|
|
611
|
+
color: COLORS.gray,
|
|
612
|
+
align: "center",
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
// HCOSS main box
|
|
616
|
+
slide.addShape("rect", {
|
|
617
|
+
x: 0.5,
|
|
618
|
+
y: 2.5,
|
|
619
|
+
w: 9.0,
|
|
620
|
+
h: 2.8,
|
|
621
|
+
fill: { color: "F8F8FF" },
|
|
622
|
+
line: { color: COLORS.darkBlue, width: 2 },
|
|
623
|
+
});
|
|
624
|
+
slide.addText("HCOSS 統合業務管理システム", {
|
|
625
|
+
x: 0.5,
|
|
626
|
+
y: 2.5,
|
|
627
|
+
w: 9.0,
|
|
628
|
+
h: 0.4,
|
|
629
|
+
fontSize: 12,
|
|
630
|
+
fontFace: FONT.body,
|
|
631
|
+
bold: true,
|
|
632
|
+
color: COLORS.darkBlue,
|
|
633
|
+
align: "center",
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
// Internal modules
|
|
637
|
+
const modules = [
|
|
638
|
+
"受注管理",
|
|
639
|
+
"在庫管理",
|
|
640
|
+
"出荷管理",
|
|
641
|
+
"商品管理",
|
|
642
|
+
"品質管理",
|
|
643
|
+
"調達管理",
|
|
644
|
+
"分析",
|
|
645
|
+
];
|
|
646
|
+
modules.forEach((name, i) => {
|
|
647
|
+
const row = Math.floor(i / 4);
|
|
648
|
+
const col = i % 4;
|
|
649
|
+
slide.addShape("roundRect", {
|
|
650
|
+
x: 0.8 + col * 2.15,
|
|
651
|
+
y: 3.0 + row * 0.7,
|
|
652
|
+
w: 1.95,
|
|
653
|
+
h: 0.55,
|
|
654
|
+
fill: { color: COLORS.darkBlue },
|
|
655
|
+
rectRadius: 0.05,
|
|
656
|
+
});
|
|
657
|
+
slide.addText(name, {
|
|
658
|
+
x: 0.8 + col * 2.15,
|
|
659
|
+
y: 3.0 + row * 0.7,
|
|
660
|
+
w: 1.95,
|
|
661
|
+
h: 0.55,
|
|
662
|
+
fontSize: 10,
|
|
663
|
+
fontFace: FONT.body,
|
|
664
|
+
color: COLORS.white,
|
|
665
|
+
align: "center",
|
|
666
|
+
valign: "middle",
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
// External services at bottom
|
|
671
|
+
const extServices = [
|
|
672
|
+
{ name: "Amazon FBA", x: 0.5 },
|
|
673
|
+
{ name: "配送業者", x: 3.0 },
|
|
674
|
+
{ name: "自社工場", x: 5.5 },
|
|
675
|
+
{ name: "提携製造所", x: 7.5 },
|
|
676
|
+
];
|
|
677
|
+
extServices.forEach((svc) => {
|
|
678
|
+
slide.addShape("rect", {
|
|
679
|
+
x: svc.x,
|
|
680
|
+
y: 5.6,
|
|
681
|
+
w: 2.0,
|
|
682
|
+
h: boxH,
|
|
683
|
+
fill: { color: "FFF3E0" },
|
|
684
|
+
line: { color: COLORS.orange, width: 1 },
|
|
685
|
+
});
|
|
686
|
+
slide.addText(svc.name, {
|
|
687
|
+
x: svc.x,
|
|
688
|
+
y: 5.6,
|
|
689
|
+
w: 2.0,
|
|
690
|
+
h: boxH,
|
|
691
|
+
fontSize: 10,
|
|
692
|
+
fontFace: FONT.body,
|
|
693
|
+
color: COLORS.black,
|
|
694
|
+
align: "center",
|
|
695
|
+
valign: "middle",
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// Tech stack note
|
|
700
|
+
slide.addText("技術方針: シンプルで運用負荷の低いシステム / マルチモール統合基盤 / トレーサビリティ対応", {
|
|
701
|
+
x: 0.5,
|
|
702
|
+
y: 6.4,
|
|
703
|
+
w: 9.0,
|
|
704
|
+
h: 0.4,
|
|
705
|
+
fontSize: 10,
|
|
706
|
+
fontFace: FONT.body,
|
|
707
|
+
color: COLORS.gray,
|
|
708
|
+
align: "center",
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// ───────────────────────────────────────
|
|
713
|
+
// Slide 8: 夜も眠れなくなるような問題
|
|
714
|
+
// ───────────────────────────────────────
|
|
715
|
+
{
|
|
716
|
+
const slide = pptx.addSlide();
|
|
717
|
+
addTitle(slide, "夜も眠れなくなるような問題は何だろう?");
|
|
718
|
+
addTable(
|
|
719
|
+
slide,
|
|
720
|
+
["#", "リスク", "影響度", "対策"],
|
|
721
|
+
[
|
|
722
|
+
[
|
|
723
|
+
"1",
|
|
724
|
+
"モール API の変更・制約",
|
|
725
|
+
"高",
|
|
726
|
+
"アダプタパターンによる API 変更への対応力確保",
|
|
727
|
+
],
|
|
728
|
+
[
|
|
729
|
+
"2",
|
|
730
|
+
"小規模チームでの開発・運用リソース不足",
|
|
731
|
+
"高",
|
|
732
|
+
"シンプルな設計を最優先。段階的リリース",
|
|
733
|
+
],
|
|
734
|
+
[
|
|
735
|
+
"3",
|
|
736
|
+
"FBA 在庫と自社在庫の同期ズレ",
|
|
737
|
+
"中",
|
|
738
|
+
"Amazon API での定期的な在庫同期。差異検知アラート",
|
|
739
|
+
],
|
|
740
|
+
[
|
|
741
|
+
"4",
|
|
742
|
+
"既存業務プロセスとの不整合",
|
|
743
|
+
"中",
|
|
744
|
+
"現場ヒアリングの徹底。段階的な業務移行",
|
|
745
|
+
],
|
|
746
|
+
[
|
|
747
|
+
"5",
|
|
748
|
+
"食品安全・法令遵守の不備",
|
|
749
|
+
"高",
|
|
750
|
+
"食品衛生法の要件を設計段階から組み込む",
|
|
751
|
+
],
|
|
752
|
+
[
|
|
753
|
+
"6",
|
|
754
|
+
"データ移行の失敗",
|
|
755
|
+
"中",
|
|
756
|
+
"段階的な移行計画。並行稼動期間の確保",
|
|
757
|
+
],
|
|
758
|
+
],
|
|
759
|
+
{ colW: [0.4, 3.0, 0.8, 4.8] }
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// ───────────────────────────────────────
|
|
764
|
+
// Slide 9: 俺たちの "A チーム"
|
|
765
|
+
// ───────────────────────────────────────
|
|
766
|
+
{
|
|
767
|
+
const slide = pptx.addSlide();
|
|
768
|
+
addTitle(slide, '俺たちの "A チーム"');
|
|
769
|
+
addTable(
|
|
770
|
+
slide,
|
|
771
|
+
["役割", "人数", "備考"],
|
|
772
|
+
[
|
|
773
|
+
["プロジェクトオーナー", "1 名", "経営者が兼務"],
|
|
774
|
+
["開発者", "1〜2 名", "AI エージェントとの協働開発"],
|
|
775
|
+
[
|
|
776
|
+
"業務担当(販売・製造)",
|
|
777
|
+
"2〜3 名",
|
|
778
|
+
"要件確認・受入テスト",
|
|
779
|
+
],
|
|
780
|
+
],
|
|
781
|
+
{ y: 1.8, colW: [2.5, 1.5, 5.0] }
|
|
782
|
+
);
|
|
783
|
+
|
|
784
|
+
addHighlightBox(
|
|
785
|
+
slide,
|
|
786
|
+
"AI エージェント(Claude Code)との協働開発により、少人数でも高品質な開発を実現",
|
|
787
|
+
{ y: 4.0, h: 0.8, fontSize: 14 }
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// ───────────────────────────────────────
|
|
792
|
+
// Slide 10: 期間を見極める
|
|
793
|
+
// ───────────────────────────────────────
|
|
794
|
+
{
|
|
795
|
+
const slide = pptx.addSlide();
|
|
796
|
+
addTitle(slide, "期間を見極める");
|
|
797
|
+
|
|
798
|
+
const phases = [
|
|
799
|
+
{
|
|
800
|
+
name: "Phase 1: 分析・設計",
|
|
801
|
+
desc: "要件定義、アーキテクチャ設計、データモデル設計",
|
|
802
|
+
weeks: "2〜3 週間",
|
|
803
|
+
color: COLORS.lightTeal,
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
name: "Phase 2: コア機能開発",
|
|
807
|
+
desc: "受注管理、在庫管理、出荷管理、商品管理",
|
|
808
|
+
weeks: "4〜6 週間",
|
|
809
|
+
color: COLORS.teal,
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
name: "Phase 3: 品質管理・調達管理",
|
|
813
|
+
desc: "品質管理、調達管理機能の開発",
|
|
814
|
+
weeks: "2〜3 週間",
|
|
815
|
+
color: COLORS.lightTeal,
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
name: "Phase 4: 分析・サポート",
|
|
819
|
+
desc: "分析ダッシュボード、カスタマーサポート",
|
|
820
|
+
weeks: "2〜3 週間",
|
|
821
|
+
color: COLORS.teal,
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
name: "Phase 5: リリース準備",
|
|
825
|
+
desc: "受入テスト、データ移行、本番稼動",
|
|
826
|
+
weeks: "2〜3 週間",
|
|
827
|
+
color: COLORS.lightTeal,
|
|
828
|
+
},
|
|
829
|
+
];
|
|
830
|
+
|
|
831
|
+
const barStartX = 0.5;
|
|
832
|
+
const barMaxW = 9.0;
|
|
833
|
+
const totalWeeks = 18;
|
|
834
|
+
const phaseWeeks = [3, 6, 3, 3, 3];
|
|
835
|
+
|
|
836
|
+
phases.forEach((phase, i) => {
|
|
837
|
+
const y = 1.8 + i * 1.0;
|
|
838
|
+
const startWeek = phaseWeeks.slice(0, i).reduce((a, b) => a + b, 0);
|
|
839
|
+
const x = barStartX + (startWeek / totalWeeks) * barMaxW;
|
|
840
|
+
const w = (phaseWeeks[i] / totalWeeks) * barMaxW;
|
|
841
|
+
|
|
842
|
+
slide.addShape("rect", {
|
|
843
|
+
x,
|
|
844
|
+
y,
|
|
845
|
+
w,
|
|
846
|
+
h: 0.45,
|
|
847
|
+
fill: { color: phase.color },
|
|
848
|
+
line: { color: COLORS.teal, width: 1 },
|
|
849
|
+
});
|
|
850
|
+
slide.addText(phase.name, {
|
|
851
|
+
x,
|
|
852
|
+
y,
|
|
853
|
+
w,
|
|
854
|
+
h: 0.45,
|
|
855
|
+
fontSize: 10,
|
|
856
|
+
fontFace: FONT.body,
|
|
857
|
+
bold: true,
|
|
858
|
+
color: COLORS.darkBlue,
|
|
859
|
+
align: "center",
|
|
860
|
+
valign: "middle",
|
|
861
|
+
});
|
|
862
|
+
slide.addText(`${phase.desc}(${phase.weeks})`, {
|
|
863
|
+
x,
|
|
864
|
+
y: y + 0.45,
|
|
865
|
+
w,
|
|
866
|
+
h: 0.35,
|
|
867
|
+
fontSize: 8,
|
|
868
|
+
fontFace: FONT.body,
|
|
869
|
+
color: COLORS.gray,
|
|
870
|
+
align: "center",
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
// MVP marker
|
|
875
|
+
const mvpX =
|
|
876
|
+
barStartX +
|
|
877
|
+
((phaseWeeks[0] + phaseWeeks[1]) / totalWeeks) * barMaxW;
|
|
878
|
+
slide.addShape("line", {
|
|
879
|
+
x: mvpX,
|
|
880
|
+
y: 1.5,
|
|
881
|
+
w: 0,
|
|
882
|
+
h: 5.0,
|
|
883
|
+
line: { color: COLORS.red, width: 2, dashType: "dash" },
|
|
884
|
+
});
|
|
885
|
+
slide.addText("MVP\nリリース", {
|
|
886
|
+
x: mvpX - 0.5,
|
|
887
|
+
y: 6.5,
|
|
888
|
+
w: 1.2,
|
|
889
|
+
h: 0.5,
|
|
890
|
+
fontSize: 10,
|
|
891
|
+
fontFace: FONT.body,
|
|
892
|
+
bold: true,
|
|
893
|
+
color: COLORS.red,
|
|
894
|
+
align: "center",
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
slide.addText("あくまで推測であって、確約するものではありません。", {
|
|
898
|
+
x: 0.5,
|
|
899
|
+
y: 7.0,
|
|
900
|
+
w: 9.0,
|
|
901
|
+
h: 0.3,
|
|
902
|
+
fontSize: 9,
|
|
903
|
+
fontFace: FONT.body,
|
|
904
|
+
color: COLORS.gray,
|
|
905
|
+
align: "right",
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// ───────────────────────────────────────
|
|
910
|
+
// Slide 11: トレードオフ・スライダー
|
|
911
|
+
// ───────────────────────────────────────
|
|
912
|
+
{
|
|
913
|
+
const slide = pptx.addSlide();
|
|
914
|
+
addTitle(slide, "トレードオフ・スライダー");
|
|
915
|
+
|
|
916
|
+
// labels and levels (1=MIN..4=MAX)
|
|
917
|
+
addSliderBar(
|
|
918
|
+
slide,
|
|
919
|
+
"機能をぜんぶ揃える(スコープ)",
|
|
920
|
+
3,
|
|
921
|
+
1.8
|
|
922
|
+
);
|
|
923
|
+
addSliderBar(slide, "予算内に収める(予算)", 2, 2.5);
|
|
924
|
+
addSliderBar(slide, "期日を死守する(時間)", 2, 3.2);
|
|
925
|
+
addSliderBar(
|
|
926
|
+
slide,
|
|
927
|
+
"高い品質、少ない欠陥(品質)",
|
|
928
|
+
4,
|
|
929
|
+
3.9
|
|
930
|
+
);
|
|
931
|
+
|
|
932
|
+
// Additional quality characteristics
|
|
933
|
+
slide.addText("品質特性の優先順位", {
|
|
934
|
+
x: 0.5,
|
|
935
|
+
y: 4.8,
|
|
936
|
+
w: 9.0,
|
|
937
|
+
h: 0.4,
|
|
938
|
+
fontSize: 14,
|
|
939
|
+
fontFace: FONT.body,
|
|
940
|
+
bold: true,
|
|
941
|
+
color: COLORS.darkBlue,
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
addTable(
|
|
945
|
+
slide,
|
|
946
|
+
["優先度", "品質特性", "理由"],
|
|
947
|
+
[
|
|
948
|
+
["1", "正確性", "受注・在庫データの正確性は業務の根幹"],
|
|
949
|
+
["2", "使いやすさ", "小規模チームが日常的に使うため、直感的な操作性が必須"],
|
|
950
|
+
["3", "信頼性", "受注処理の停止は直接的な売上損失につながる"],
|
|
951
|
+
["4", "保守性", "小規模チームでの長期運用を見据えたシンプルな設計"],
|
|
952
|
+
],
|
|
953
|
+
{ y: 5.2, colW: [0.8, 1.8, 6.4] }
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// ───────────────────────────────────────
|
|
958
|
+
// Slide 12: 初回のリリースに必要なもの
|
|
959
|
+
// ───────────────────────────────────────
|
|
960
|
+
{
|
|
961
|
+
const slide = pptx.addSlide();
|
|
962
|
+
addTitle(slide, "初回のリリースに必要なもの");
|
|
963
|
+
|
|
964
|
+
addHighlightBox(
|
|
965
|
+
slide,
|
|
966
|
+
"Phase 2 完了時点で MVP(最小実行可能製品)をリリース",
|
|
967
|
+
{ y: 1.5, h: 0.7, fontSize: 16 }
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
slide.addText("MVP スコープ", {
|
|
971
|
+
x: 0.5,
|
|
972
|
+
y: 2.5,
|
|
973
|
+
w: 9.0,
|
|
974
|
+
h: 0.4,
|
|
975
|
+
fontSize: 14,
|
|
976
|
+
fontFace: FONT.body,
|
|
977
|
+
bold: true,
|
|
978
|
+
color: COLORS.darkBlue,
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
addBullets(
|
|
982
|
+
slide,
|
|
983
|
+
[
|
|
984
|
+
"マルチモール受注管理(楽天市場、Yahoo!、Amazon、au PAY)",
|
|
985
|
+
"在庫管理(自社在庫 + Amazon FBA 在庫の統合管理)",
|
|
986
|
+
"出荷管理(受注に基づく出荷指示・梱包・配送手配)",
|
|
987
|
+
"商品管理(商品マスタの一元管理、各モールへの同期)",
|
|
988
|
+
],
|
|
989
|
+
{ y: 2.9, h: 2.5, fontSize: 13 }
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
slide.addText("リリース戦略", {
|
|
993
|
+
x: 0.5,
|
|
994
|
+
y: 5.2,
|
|
995
|
+
w: 9.0,
|
|
996
|
+
h: 0.4,
|
|
997
|
+
fontSize: 14,
|
|
998
|
+
fontFace: FONT.body,
|
|
999
|
+
bold: true,
|
|
1000
|
+
color: COLORS.darkBlue,
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
addBullets(
|
|
1004
|
+
slide,
|
|
1005
|
+
[
|
|
1006
|
+
"以降のフェーズは段階的にリリースし、フィードバックを反映しながら改善",
|
|
1007
|
+
"各フェーズ完了時にステークホルダーレビューを実施し、次フェーズの優先順位を見直す",
|
|
1008
|
+
],
|
|
1009
|
+
{ y: 5.6, h: 1.5, fontSize: 12 }
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
// ───────────────────────────────────────
|
|
1014
|
+
// Save
|
|
1015
|
+
// ───────────────────────────────────────
|
|
1016
|
+
const outputPath = resolve(
|
|
1017
|
+
"docs/analysis/slide/HCOSS_v0.1.0.pptx"
|
|
1018
|
+
);
|
|
1019
|
+
const dataBuffer = await pptx.write({ outputType: "nodebuffer" });
|
|
1020
|
+
writeFileSync(outputPath, dataBuffer);
|
|
1021
|
+
console.log("Generated:", outputPath);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
main().catch(console.error);
|