# esg-crawler｜Claude Code 開工 Prompt

> **用法**：把「開工 Prompt」那一整段貼到 `/Users/ezonelai/Projects/` 下新開的 Claude Code session，
> 它會替你 scaffold 整個專案、建立 CLAUDE.md、docs/NEXT_SESSION.md、docker-compose 等。

---

## ⚠️ 專案命名

- **內部代號**：`esg-crawler`（Eugene 自用）
- **對外品牌**：**保留給顧問命名**——她會取名，之後用 find-replace 換掉即可
- 預留 placeholder：`{{PRODUCT_NAME}}`（命名前用這個佔位符）

---

## 📋 開工前手動步驟（2 分鐘）

```bash
# 1. 建立專案資料夾（與 ronsunai-web、ceyan 同層）
cd ~/Projects/
mkdir esg-crawler && cd esg-crawler

# 2. Git 初始化
git init
git remote add origin git@github.com:ronsunai/esg-crawler.git  # 先別 push，repo 建好後再 push

# 3. 開啟 Claude Code
claude
```

---

## 🚀 開工 Prompt（整段複製給 Claude Code）

````
你是容晟科技（RonsunAI）的資深 Python 工程師。今天是 esg-crawler 專案的 Day 1。
請依照以下規格 scaffold 專案，並建立所有必要的文件。

## 專案定位

- **代號**：esg-crawler（對外品牌名稱待定，以 {{PRODUCT_NAME}} 為 placeholder）
- **目的**：ESG 法規情報共用爬蟲微服務——兩個下游專案（ESG Radar、DAWOO CarbonTrace）共用
- **戰略**：後端由容晟獨家掌控，前端預留三方可插拔（A 方=顧問、B 方=其他合作、C 方=容晟自己）

## 技術棧（已決定，不需再確認）

- Python 3.11 + Poetry
- FastAPI（非同步）+ SQLAlchemy 2.0 + asyncpg
- PostgreSQL 16（dev 用 Docker Compose）
- Redis 7（快取 + rate limit）
- Alembic（migration）
- APScheduler（排程）+ Celery（重活佇列）
- httpx + selectolax + Playwright + feedparser
- pdfplumber + Anthropic SDK（Claude Haiku 摘要 + Sonnet 影響分析）
- Docker Compose（開發）+ 未來 Railway/Fly.io（production）
- pytest + ruff + mypy

## 專案結構（照 Ceyan 慣例）

```
esg-crawler/
├── CLAUDE.md                    ← 專案說明，Claude Code 每次 session 讀
├── README.md                    ← 給人看的 readme
├── pyproject.toml
├── docker-compose.yml
├── Dockerfile
├── .env.example
├── .gitignore
├── .editorconfig
│
├── docs/
│   ├── NEXT_SESSION.md          ← 每次 session 結束更新
│   ├── TRACKER.md               ← 任務追蹤
│   ├── ARCHITECTURE.md          ← 系統架構（簡版）
│   ├── API.md                   ← API 合約（給下游消費者）
│   └── DATA_SOURCES.md          ← 30+ 資料源清單與 Tier 分級
│
├── src/
│   └── esg_crawler/
│       ├── __init__.py
│       ├── config.py            ← Pydantic Settings
│       ├── db.py                ← SQLAlchemy + alembic
│       ├── models.py            ← ORM 模型
│       │
│       ├── fetchers/
│       │   ├── __init__.py
│       │   ├── base.py          ← BaseFetcher 抽象類
│       │   └── generic_rss.py   ← 今天只建骨架，實作 Day 3+
│       │
│       ├── normalizers/
│       │   └── __init__.py      ← 今天只建空 package
│       │
│       ├── analyzer/
│       │   └── __init__.py
│       │
│       ├── scheduler/
│       │   └── __init__.py
│       │
│       ├── api/
│       │   ├── __init__.py
│       │   ├── main.py          ← FastAPI app + /v1/health
│       │   ├── auth.py          ← Bearer token（Day 8 實作，今天先空）
│       │   └── deps.py
│       │
│       └── storage/
│           └── __init__.py
│
├── alembic/
│   ├── env.py
│   ├── script.py.mako
│   └── versions/
│       └── 001_initial.py       ← 今天建立 regulation_source 表
│
├── tests/
│   ├── __init__.py
│   └── test_health.py           ← /v1/health 回 200
│
└── scripts/
    └── seed_sources.py          ← 灌入 Tier 0 三筆（金管會、公司治理、氣候變遷署）
```

## 今天（Day 1）要做完的 6 件事

1. **專案骨架**：poetry init、目錄結構、pyproject.toml、.gitignore、.editorconfig
2. **Docker Compose**：postgres:16 + redis:7 + api service，`docker compose up` 能跑起來
3. **FastAPI Hello**：src/esg_crawler/api/main.py 有 `/v1/health` endpoint，回 `{"status":"ok","version":"0.1.0"}`
4. **資料庫連線**：SQLAlchemy 非同步 session、alembic 初始化、第一條 migration 建 `regulation_source` 表
5. **Seed**：scripts/seed_sources.py 灌入三筆（參考下方「Seed 資料」）
6. **Claude 文件**：CLAUDE.md、docs/NEXT_SESSION.md、docs/TRACKER.md、docs/ARCHITECTURE.md（簡短）

## regulation_source 表 schema

```sql
CREATE TABLE regulation_source (
  id              SERIAL PRIMARY KEY,
  code            TEXT UNIQUE NOT NULL,
  name_tw         TEXT NOT NULL,
  name_en         TEXT,
  jurisdiction    TEXT,
  base_url        TEXT NOT NULL,
  rss_url         TEXT,
  tier            TEXT NOT NULL,
  fetcher_module  TEXT NOT NULL,
  enabled         BOOLEAN NOT NULL DEFAULT TRUE,
  last_fetched_at TIMESTAMPTZ,
  created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```

## Seed 資料（scripts/seed_sources.py）

```python
SOURCES = [
    {
        "code": "FSC-ESG",
        "name_tw": "金融監督管理委員會 · 永續金融網",
        "name_en": "FSC Sustainable Finance Network",
        "jurisdiction": "TW",
        "base_url": "https://esg.fsc.gov.tw/",
        "rss_url": None,
        "tier": "T0",
        "fetcher_module": "fsc_esg",
    },
    {
        "code": "CGA-CENTER",
        "name_tw": "公司治理中心（TWSE）",
        "name_en": "TWSE Corporate Governance Center",
        "jurisdiction": "TW",
        "base_url": "https://cgc.twse.com.tw/",
        "rss_url": None,
        "tier": "T0",
        "fetcher_module": "cga_center",
    },
    {
        "code": "CCA",
        "name_tw": "環境部氣候變遷署",
        "name_en": "Climate Change Administration",
        "jurisdiction": "TW",
        "base_url": "https://www.cca.gov.tw/",
        "rss_url": None,
        "tier": "T0",
        "fetcher_module": "cca",
    },
]
```

## CLAUDE.md 必含內容

```markdown
# esg-crawler

> ESG 法規情報共用爬蟲微服務（RonsunAI 容晟科技）

## 鏈式讀取（Claude Code 每次 session 開始先讀）

1. 本檔 CLAUDE.md
2. docs/NEXT_SESSION.md    ← 上次 session 結束狀態 + 本次要做什麼
3. docs/TRACKER.md         ← 任務進度
4. docs/ARCHITECTURE.md    ← 系統架構參考

## 專案狀態

- Phase：MVP Week 1
- 下一個里程碑：Day 10（2026-05-02）完成 MVP
- 規劃書：`~/Projects/ESG 永續顧問/01_ESG_RADAR_合作方案/06_esg-crawler_開工規劃書.docx`

## 戰略定位（重要）

- **後端 IP 100% 屬容晟**——不與任何合作方共享原始碼
- **前端三方可插**：FE-A（顧問）、FE-B（其他合作）、FE-C（容晟）
- **顧問 Know-how 在外**：EcoVadis 對應、評分邏輯由顧問以 JSON/YAML KB 檔提供，不寫進程式碼

## 開發原則

- 爬蟲禮節：robots.txt、rate limit、User-Agent `RonsunAI-ESG-Crawler/1.0 (+https://ronsunai.org/crawler-bot)`
- 每個 fetcher 必寫至少 3 個 snapshot-based 測試
- LLM 成本每日監控，單日 > USD $5 告警
- commit message 前綴：`feat:` `fix:` `docs:` `chore:` `refactor:` `test:`

## Session 結束前必做

1. 更新 docs/NEXT_SESSION.md（完成什麼、下次做什麼）
2. 更新 docs/TRACKER.md（完成打 ✅、新增問題）
3. git add [指定檔案] && git commit -m "checkpoint: [任務名稱]"
4. 不用 `git add -A` 或 `git add .`，避免誤加敏感檔

## 禁止事項

- 不 push 原始碼到任何非容晟 GitHub
- 不在 commit / PR 中提及顧問個人姓名
- 不硬寫 API key；一律走 .env
- 不刪除函式；不「順手優化」；font-size < 14px 不做
```

## docs/NEXT_SESSION.md 必含內容

```markdown
# NEXT_SESSION — 下次 session 的啟動包

## 上次 session 完成（2026-04-21 Day 1）

- ✅ 專案骨架（poetry、目錄、docker-compose）
- ✅ PostgreSQL 16 + Redis 7 容器跑通
- ✅ FastAPI /v1/health 回 200
- ✅ alembic 初始化 + regulation_source 表
- ✅ scripts/seed_sources.py 灌入三筆 Tier 0 資料源
- ✅ CLAUDE.md / NEXT_SESSION.md / TRACKER.md / ARCHITECTURE.md 建立

## 下次 session 要做（Day 2，2026-04-22）

1. 完整 5 張表的 migration：regulation_item、change_event、consumer、dispatch_log
2. 擴充 seed_sources.py，再加 7 筆 Tier A（IFRS、CDP、EU CBAM、環境部法規、GRI、TCX、ESG InfoHub）
3. /v1/sources endpoint 回傳所有已 seed 的資料源
4. 撰寫 pytest `test_sources_endpoint`

## 已知問題 / 未決事項

- （目前無）

## 環境變數 checklist

```
DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres:5432/esg_crawler
REDIS_URL=redis://redis:6379/0
CLAUDE_API_KEY=（sk-ant-...，Day 7 才用到）
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_BUCKET=esg-crawler-snapshots
```
```

## docs/TRACKER.md 必含內容

```markdown
# TRACKER

## Sprint：MVP Week 1（2026-04-21 ~ 2026-04-25）

| # | 任務 | 狀態 | 預計 | 完成 |
|---|------|------|------|------|
| D1-1 | 專案骨架 | ✅ | 4/21 | 4/21 |
| D1-2 | Docker Compose | ✅ | 4/21 | 4/21 |
| D1-3 | FastAPI /v1/health | ✅ | 4/21 | 4/21 |
| D1-4 | alembic + regulation_source | ✅ | 4/21 | 4/21 |
| D1-5 | seed 三筆 Tier 0 | ✅ | 4/21 | 4/21 |
| D1-6 | 文件骨架 | ✅ | 4/21 | 4/21 |
| D2-1 | 完整 5 張表 migration | ⏳ | 4/22 | — |
| D2-2 | 擴充 seed（+7 筆 Tier A） | ⏳ | 4/22 | — |
| D2-3 | /v1/sources endpoint | ⏳ | 4/22 | — |
```

## docs/ARCHITECTURE.md 必含內容

```markdown
# ARCHITECTURE

## 三層架構

- **L0 Fetchers**：每個來源一個 Python 檔；基類 BaseFetcher
- **L1 Data**：PostgreSQL（結構化）+ Cloudflare R2（原文快照）+ Redis（快取）
- **L2 Distribution**：FastAPI REST + Webhook 推送

## 關鍵邊界

- 爬蟲本身不做「影響評估」；只產生 change_event
- 每個 consumer 獨立 API key + 獨立 filter
- Know-how（EcoVadis 對應等）不進爬蟲；留在消費端

## 詳細規格

見 `~/Projects/ESG 永續顧問/01_ESG_RADAR_合作方案/06_esg-crawler_開工規劃書.docx`
```

## 完成後

1. 跑通 `docker compose up -d`
2. 跑通 `curl http://localhost:8000/v1/health`，應回 `{"status":"ok","version":"0.1.0"}`
3. 跑通 `poetry run alembic upgrade head`
4. 跑通 `poetry run python scripts/seed_sources.py`，應看到「Inserted 3 sources」
5. 跑通 `poetry run pytest tests/test_health.py`，應 PASSED
6. `git add` 具體檔案（不用 -A），commit message：`chore: D1 — 專案骨架與 Tier 0 seed`

不要 push 到 remote，我手動確認後再 push。

開工吧。
````

---

## 🗣️ 給顧問的命名說明（若她問起）

> 「後端我先以 `esg-crawler` 當內部代號開工，不對外曝光。正式產品名你決定——
>
> - 建議是 2-4 個字、中英文皆順、網域可買（`.com` / `.io` / `.ai`）
> - 不要跟 EcoVadis、Persefoni、Watershed 任何既有品牌太像
> - 避開「RonsunAI」「容晟」字樣，讓你將來創業不受限
>
> 你想好了告訴我，我會在系統內做 find-replace，1 小時內換完。」

---

## 🧭 三方前端策略備忘（之後再寫詳細版，先記觀念）

| 前端 | Repo | 品牌 | 誰做 | 何時啟動 |
|---|---|---|---|---|
| **FE-C** 容晟版（先做）| `esg-crawler-webui` | RonsunAI | 容晟自己 | 爬蟲 MVP 完成後 1 週 |
| **FE-A** 顧問版 | `{她的品牌}-frontend` | 她的未來公司 | 她自己找工程師 | 她要才做 |
| **FE-B** 白牌版 | `esg-whitelabel-frontend` | 其他顧問公司 | 容晟 / 授權方 | 有 B 方付錢時 |

**共用**：`@ronsunai/esg-sdk`（npm 套件）——這是容晟的隱性控制點；所有前端都依賴 SDK，我改 SDK 他們就得跟。

---

## ⚡ 今晚可做的事（5 分鐘）

1. Github 建 private repo `ronsunai/esg-crawler`
2. 本機 `cd ~/Projects && mkdir esg-crawler && cd esg-crawler && git init`
3. 把上面的「開工 Prompt」貼給 Claude Code
4. 睡一覺，明天起來看成果
