PDF ポートフォリオの自動生成(Month 6 Week 24)
README・checklist.yml・コミット履歴・本番 URL・スクリーンショットを 1 本の PDF にまとめ、修了記念としてアウトプット化する
Week 24 のカリキュラム最終週では、6 ヶ月間の学習成果を 1 つの PDF にまとめ、Menta 契約の Level C(最終修了評価)成果物として納品します。presentation-wataru-kinoshita の約束した「学んだ内容を体系的にまとめた PDF(記念品として進呈)」に相当します。
主旨: このドキュメントはメンターが PDF を生成する側のガイドです。受講者自身がコピペで使える手順にもなっています。
PDF の構成(Table of Contents)
- 表紙 — 受講者名 / 期間 / ロゴ
- エグゼクティブサマリー — 6 ヶ月で何を作り、何を学んだか(1 ページ)
- 完成したアプリ — CloudFront URL + 主要画面スクリーンショット(4〜6 枚)
- 要求チェックリスト達成度 — checklist.yml を表形式でレンダリング
- アーキテクチャ — インフラ構成図 + ER 図 + シーケンス図
- 学習ジャーニー(Month 別) — Tobe / 詰まったポイント / 成長記録
- Git 履歴のハイライト — 意味のあるコミット 10〜20 個
- AI ツール活用記録(N9) — どのプロンプトが効いたか
- 振り返りエッセイ — 受講者本人が書く(2〜3 ページ)
- 謝辞 / 今後の展望
アプローチ:Markdown → PDF
1 つの portfolio/portfolio.md を書き、Pandoc + LaTeX or Puppeteer で PDF 化します。Markdown をソースにする 理由:
- Git で差分管理できる
- VS Code で書ける
- 画像を embed しやすい
checklist.yml/git logからスクリプトで生成しやすい
セットアップ(Pandoc + wkhtmltopdf 方式)
macOS
brew install pandoc wkhtmltopdf
Windows(Git Bash)
winget install JohnMacFarlane.Pandoc
winget install wkhtmltopdf.wkhtmltopdf
動作確認
echo "# Hello" | pandoc -o test.pdf --pdf-engine=wkhtmltopdf
ディレクトリ構成
sns_clone/
└── portfolio/
├── portfolio.md ← ソース(このファイルを育てる)
├── screenshots/ ← アプリのスクリーンショット
│ ├── home.png
│ ├── login.png
│ ├── post-detail.png
│ └── ...
├── diagrams/ ← Mermaid エクスポート or SVG
│ ├── infrastructure.svg
│ └── er-diagram.svg
├── styles.css ← PDF のスタイル
├── metadata.yaml ← 表紙情報
└── build.sh ← 生成スクリプト
portfolio.md のひな型
---
title: "SWEスキル習得カリキュラム 修了ポートフォリオ"
author: "木下 航"
date: "2026-10-15"
toc: true
toc-depth: 2
---
# 1. エグゼクティブサマリー
2026年4月から10月の6ヶ月間で、React + Hono + AWS のフルスタックアプリを...
# 2. 完成したアプリ
- 本番 URL: https://kinoshita-app.cloudfront.net
- GitHub: https://github.com/subaru-hello/fullstack_typescript_curriculum/tree/kinoshita/main


# 3. 要求チェックリスト達成度
<!-- scripts/render-checklist.mjs で自動生成される -->
{{CHECKLIST_TABLE}}
# 4. アーキテクチャ


# 5. 学習ジャーニー
## Month 1: 基礎ツアー(Week 1-4)
...
## Month 2: 要求定義(Week 5-8)
...
(以下 Month 6 まで)
# 6. Git 履歴のハイライト
<!-- scripts/render-git-log.mjs で自動生成 -->
{{GIT_LOG_HIGHLIGHTS}}
# 7. AI ツール活用記録(N9)
- Claude Code: カリキュラム全編で活用。特に...
- Claude の使い方で効いたプロンプト:
- 「Week N の Tobe を達成するための最短手順を提示して」
- ...
# 8. 振り返り(自由記述)
(受講者が自由に書く)
# 9. 今後の展望
(このプロジェクトの継続 or 次の挑戦)
自動埋め込みスクリプト
scripts/render-checklist.mjs
checklist.yml を Markdown 表に変換:
#!/usr/bin/env node
import { readFileSync, writeFileSync } from "node:fs";
import yaml from "js-yaml"; // pnpm add -D js-yaml
const checklist = yaml.load(readFileSync("checklist.yml", "utf8"));
function sectionToTable(title, items) {
let md = `### ${title}\n\n| ID | 要求 | 判定 | 根拠 |\n|---|---|---|---|\n`;
for (const [id, item] of Object.entries(items)) {
const judgment = item.judgment === "CLEAR" ? "✅" : item.judgment === "PARTIAL" ? "⚠️" : "❌";
md += `| ${id} | ${item.requirement} | ${judgment} | ${item.evidence || "-"} |\n`;
}
return md + "\n";
}
let out = "";
out += sectionToTable("Must 機能要求", checklist.must_functional);
out += sectionToTable("Must 非機能要求", checklist.must_non_functional);
out += sectionToTable("Nice-to-have", checklist.nice_to_have);
const portfolio = readFileSync("portfolio/portfolio.md", "utf8");
writeFileSync("portfolio/portfolio.md", portfolio.replace("{{CHECKLIST_TABLE}}", out));
console.log("checklist table injected");
scripts/render-git-log.mjs
git log から意味のあるコミットを抽出:
#!/usr/bin/env node
import { execSync } from "node:child_process";
import { readFileSync, writeFileSync } from "node:fs";
// kinoshita/main の 6 ヶ月分のマージコミット(PR マージ単位)を取得
const log = execSync(
`git log kinoshita/main --merges --pretty=format:"- **%ad** %s (%h)" --date=short`,
{ encoding: "utf8" },
);
const portfolio = readFileSync("portfolio/portfolio.md", "utf8");
writeFileSync("portfolio/portfolio.md", portfolio.replace("{{GIT_LOG_HIGHLIGHTS}}", log));
console.log("git log injected");
build.sh(生成スクリプト)
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
# 1. テンプレートをコピー(上書き)
cp portfolio.template.md portfolio.md
# 2. 自動埋め込み
node ../scripts/render-checklist.mjs
node ../scripts/render-git-log.mjs
# 3. PDF 生成
pandoc portfolio.md \
-o portfolio.pdf \
--pdf-engine=wkhtmltopdf \
--metadata-file=metadata.yaml \
--toc \
--toc-depth=2 \
--css=styles.css \
--highlight-style=tango
echo "✅ portfolio.pdf generated ($(du -h portfolio.pdf | cut -f1))"
代替アプローチ:Puppeteer で HTML → PDF
Marp や Astro でスライド化したい場合は Puppeteer 経由がシンプル:
cd web
pnpm add -D puppeteer
scripts/build-portfolio-pdf.mjs:
import puppeteer from "puppeteer";
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("http://localhost:3000/portfolio", { waitUntil: "networkidle0" });
await page.pdf({
path: "portfolio.pdf",
format: "A4",
margin: { top: "20mm", right: "15mm", bottom: "20mm", left: "15mm" },
printBackground: true,
});
await browser.close();
Web ページを 1 本作って、そこに Chart.js / Mermaid などインタラクティブ要素も含められる利点あり。
スクリーンショットの撮り方
Playwright で自動キャプチャ:
e2e/screenshots.spec.ts:
import { test } from "@playwright/test";
test.use({ viewport: { width: 1280, height: 800 } });
test("capture screens for portfolio", async ({ page }) => {
await page.goto("/");
await page.screenshot({ path: "portfolio/screenshots/home.png" });
await page.goto("/login");
await page.screenshot({ path: "portfolio/screenshots/login.png" });
await page.goto("/posts/sample-id");
await page.screenshot({ path: "portfolio/screenshots/post-detail.png" });
});
pnpm exec playwright test e2e/screenshots.spec.ts で 6 画面が一気に撮れます。
受講者が書く部分(手動)
自動化できない(すべきでない)部分:
- エグゼクティブサマリー: 自分の言葉で
- 学習ジャーニーの詰まりポイント: 正直に書くほど資産になる
- 振り返りエッセイ: 2〜3 ページ。「何ができるようになったか」「何が難しかったか」「次の挑戦」
テンプレートを用意:
## Month N でできるようになったこと
- 【具体例】Hono の middleware を自分で書けるようになった
- 【before / after】以前は try-catch だらけだったが、AppError + app.onError で...
## Month N で詰まったこと
- 【事象】CORS エラーが発生してフロントから API が叩けなかった
- 【原因】proxy 設定 vs CORS 設定の混乱
- 【学び】`vite.config.ts` の proxy と Hono の `cors()` は別の層...
## Month N で印象に残った瞬間
- (自由記述)
Week 24 のアウトプット
- ☐
portfolio/ディレクトリがsns_cloneリポジトリに存在 - ☐
portfolio.template.mdに 9 セクション全てのひな型がある - ☐
scripts/render-checklist.mjsが checklist.yml を表に変換できる - ☐
scripts/render-git-log.mjsが意味のあるコミットを抽出できる - ☐
portfolio/screenshots/に 4〜6 枚のスクリーンショット - ☐
build.shを実行するとportfolio.pdfが A4 10〜20 ページで生成される - ☐ 受講者本人が「振り返りエッセイ」を手書きで加筆済み
- ☐ PDF をメンター + 受講者本人が所持
修了の定義(Level C)
以下が全て揃った時点で 修了:
https://xxx.cloudfront.netが 24 時間稼働しているchecklist.ymlの Must 項目が 80% 以上 CLEARportfolio.pdfが完成しているkinoshita/mainの Git 履歴が 6 ヶ月分残っている- 最終 15 分プレゼンを実施済み
- AI ツール活用記録(N9)が README に記載されている
よくある失敗
- PDF 生成を最終週に始める: Month 5 の後半から portfolio.md を育て始めるとラク
- 振り返りを「全部うまくいきました」で埋める: 将来の自分への資産性が低い。詰まったこと こそ価値
- スクリーンショットが粗い:
viewport: { width: 1280, height: 800 }以上で撮影 - Git log が意味不明: Week 22 までの PR ワークフローで良いコミット粒度を保っていれば、Week 24 は抽出するだけで済む
参考
- Pandoc: https://pandoc.org/
- wkhtmltopdf: https://wkhtmltopdf.org/
- Puppeteer: https://pptr.dev/
- js-yaml: https://github.com/nodeca/js-yaml
- 前提: b21-pr-review(評価ルーブリック)/ b23-trivy + b23-cloudwatch-logs(修了までに揃える技術項目)
これで beginner-stepup シリーズは完結です。お疲れさまでした。
生きているコード
本ドキュメントで扱ったパターンの完全な動作コードは、メンター側リポジトリの参照ブランチで確認できます。
- 対応 Week: W24
- 参照ブランチ:
- W24:
reference/week-24 - 対応 checklist 項目: N9
ブランチの作り方・見方は b00-curriculum-map を参照してください。
- 1. 📄環境構築の段階的導入(macOS / Windows)
- 2. 📄SNSアプリの最終インフラ構成図
- 3. 📄SNSクローンの全体設計(Month 1 ゴール)
- 4. 📄カリキュラム全体マップ(Week × 教材 × 参照ブランチ × 要求チェックリスト)
- 5. 📄このカリキュラムの使い方(SQL・Python・Dify経験者向け)
- 6. 📄シェル・ターミナル基礎
- 7. 📄Windows で完全にゼロから始める開発環境構築(Week 1)
- 8. 📄Git基礎
- 9. 📄GitHubワークフロー
- 10. 📄パッケージ管理(pnpm workspace)
- 11. 📄Webアプリアーキテクチャ全体像
- 12. 📄要求ヒアリングとユーザーストーリー(Month 2 Week 5)
- 13. 📄画面ワイヤーフレームと画面遷移図(Month 2 Week 6)
- 14. 📄HTTP・REST API基礎
- 15. 📄ER 図の描き方(Month 2 Week 7)
- 16. 📄認証・認可のパターン
- 17. 📄REST API 仕様書の書き方(Month 2 Week 7)
- 18. 📄HTML/CSS基礎とレイアウト
- 19. 📄JavaScript基礎(Pythonとの対比)
- 20. 📄TypeScript基礎(型システムとPythonとの対比)
- 21. 📄Reactコンポーネント設計の基礎
- 22. 📄状態管理の概念
- 23. 📄フォーム検証(React Hook Form + Zod)(Month 3 Week 11)
- 24. 📄バックエンドAPI設計(Hono)
- 25. 📄ルーティング(React Router v7)
- 26. 📄Hono のエラーハンドリング(Month 4 Week 13)
- 27. 📄データベース設計・SQL→Drizzle ORM対応
- 28. 📄マイグレーションの考え方
- 29. 📄AWSインフラ基礎
- 30. 📄AWS Budget Alert の設定(Month 5 Week 17)
- 31. 📄環境変数管理
- 32. 📄Bastion EC2 と SSH ProxyJump(Month 5 Week 18)
- 33. 📄CI/CD基礎
- 34. 📄ECR への Docker イメージ push と App EC2 デプロイ(Month 5 Week 19)
- 35. 📄テスト設計の基本
- 36. 📄CloudFront + S3 + ALB で公開する(Month 5 Week 20)
- 37. 📄CLAUDE.md・プロジェクト設定
- 38. 📄PR レビュー 5 観点ルーブリック(全 Week 共通)
- 39. 📄タスク分解・仕様の書き方
- 40. 📄Playwright で E2E テスト(Month 6 Week 22)
- 41. 📄生成コードのレビュー・デバッグの勘所
- 42. 📄Trivy で脆弱性スキャン(Month 6 Week 23)
- 43. 📄CloudWatch Logs の読み方と運用(Month 6 Week 23)
- 44. 📄PDF ポートフォリオの自動生成(Month 6 Week 24)