# JobData - 招聘数据采集与统计分析平台

## 变更记录 (Changelog)

| 版本 | 日期 | 说明 |
|------|------|------|
| 初始化 | 2026-03-20 | 首次生成架构文档，覆盖全部四个核心模块 |

---

## 项目愿景

JobData 是一个面向招聘市场的全栈数据采集与分析平台。系统从三大主流招聘平台（Boss 直聘、前程无忧、智联招聘）自动抓取职位与公司数据，统一存储到 ClickHouse 列式数据库，并通过 FastAPI 后端 + Vue3 前端提供数据查看、定向清洗、统计分析等能力。ECS 弹性实例管理模块支持在阿里云上按需批量启停爬虫节点。

---

## 架构总览

```
[招聘平台]          [爬虫层]                  [后端 API]            [数据库]
Boss直聘  ──►  jobs_spider/boss/     ──►                      ┌── MySQL
前程无忧  ──►  jobs_spider/qcwy/     ──►  app (FastAPI)  ──►  └── ClickHouse
智联招聘  ──►  jobs_spider/zhilian/  ──►
                                                              ▲
                                                              │
                                          web (Vue3)  ────────┘
                                          (前端页面)

ecs_full_pipeline.py  ──►  阿里云 ECS  ──►  批量启动爬虫节点
```

**核心技术栈**

| 层次 | 技术 |
|------|------|
| 后端 | Python 3.13, FastAPI 0.111, Tortoise-ORM 0.23, APScheduler |
| 数据库（业务） | MySQL（用户/权限/审计/关键词/Token） |
| 数据库（采集） | ClickHouse（职位/公司 JSON 原始数据 + 分析视图） |
| 爬虫 | requests / httpx / Playwright（Python 脚本） |
| 前端 | Vue 3.3, Vite 4, Naive UI, Pinia, ECharts |
| 基础设施 | 阿里云 ECS（按量抢占实例），APScheduler 定时任务 |

---

## 模块结构图

```mermaid
graph TD
    ROOT["(根) JobData"] --> APP["app - FastAPI 后端"]
    ROOT --> WEB["web - Vue3 前端"]
    ROOT --> SPIDER["jobs_spider - 平台爬虫"]
    ROOT --> ECS["ecs_full_pipeline.py - ECS 批量部署"]

    APP --> APP_API["app/api - 路由层"]
    APP --> APP_SVC["app/services - 业务逻辑"]
    APP --> APP_CORE["app/core - 框架核心"]
    APP --> APP_MODELS["app/models - ORM 模型"]
    APP --> APP_REPO["app/repositories - 数据仓库"]

    SPIDER --> SP_BOSS["jobs_spider/boss"]
    SPIDER --> SP_QCWY["jobs_spider/qcwy"]
    SPIDER --> SP_ZL["jobs_spider/zhilian"]

    click APP "./app/AGENTS.md" "查看 app 模块文档"
    click WEB "./web/AGENTS.md" "查看 web 模块文档"
    click SPIDER "./jobs_spider/AGENTS.md" "查看 jobs_spider 模块文档"
```

---

## 模块索引

| 模块路径 | 语言 | 职责简述 |
|----------|------|----------|
| `app/` | Python | FastAPI 后端，提供 REST API、权限管理、定时任务、数据入库与分析 |
| `web/` | Vue3/JS | 前端管理界面，数据展示、关键词管理、代理管理、数据清洗操作 |
| `jobs_spider/` | Python | 三大平台的爬虫脚本，独立运行，结果通过 HTTP 推送到后端 |
| `ecs_full_pipeline.py` | Python | 阿里云 ECS 实例批量创建/销毁/命令下发全流程脚本 |
| `reclean_qcwy_jobs.py` | Python | 前程无忧数据重清洗独立脚本 |

---

## 运行与开发

### 后端启动

```bash
# 安装依赖（pipenv）
pipenv install

# 开发模式（默认端口 9999，20 个 worker）
python run.py

# 环境变量覆盖
APP_HOST=0.0.0.0 APP_PORT=9999 UVICORN_WORKERS=4 python run.py
```

**关键环境变量**

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `APP_HOST` | `0.0.0.0` | 监听地址 |
| `APP_PORT` | `9999` | 监听端口 |
| `UVICORN_WORKERS` | `20` | Worker 数量 |
| `CLICKHOUSE_HOST` | `121.4.126.241` | ClickHouse 地址（需修改为实际地址） |
| `CLICKHOUSE_USER` / `CLICKHOUSE_PASS` | 见 config.py | ClickHouse 认证 |
| `SMTP_HOST` / `SMTP_USER` / `SMTP_PASS` | 见 config.py | 邮件告警配置 |
| `REPORT_ENDPOINT` | 空 | 统计结果 Webhook 上报地址 |
| `RUN_MIGRATIONS_ON_STARTUP` | `True` | 是否启动时自动迁移 |
| `INITIALIZE_SEED_DATA_ON_STARTUP` | `True` | 是否启动时初始化种子数据 |

> 安全警告：`config.py` 中 `SECRET_KEY`、数据库连接串、SMTP 密码均为硬编码默认值，生产环境必须通过环境变量覆盖。

### 前端启动

```bash
cd web
pnpm install
pnpm dev        # 开发模式，默认 http://localhost:5173
pnpm build      # 构建产物到 web/dist
```

### ECS 批量爬虫部署

```bash
# 需配置阿里云凭据（环境变量或 ~/.alibabacloud/credentials）
python ecs_full_pipeline.py
```

---

## 定时任务

APScheduler 在应用启动时注册以下任务（`app/core/scheduler.py`）：

| 任务 ID | 频率 | 职责 |
|---------|------|------|
| `stats_job` | 每 6 小时 | 统计 ClickHouse 各表总量并通过邮件/Webhook 上报 |
| `ecs_full_pipeline` | 每 6 小时 | 调用 `ecs_full_pipeline.py` 批量刷新爬虫节点 |
| `ip_alert_job` | 每 10 分钟 | 检查 IP 上报异常并告警 |
| `company_cleaning_job` | 每 5 分钟 | 自动清洗待处理公司数据（collect 50 + process 30） |
| `daily_cleanup_job` | 每天 00:05 | 清理历史任务运行记录 |

所有任务通过分布式文件锁（或可选 Redis 锁）保证多 Worker 下只执行一次。

---

## 测试策略

- 当前代码库**无自动化测试文件**（缺口：单元测试、集成测试均缺失）。
- 推荐补充：
  1. `app/services/` 的 service 层单元测试（使用 `pytest` + `anyio`）
  2. `app/api/v1/` 的 API 集成测试（使用 `httpx.AsyncClient`）
  3. `jobs_spider/` 的数据解析函数单元测试

---

## 编码规范

- Python：使用 `ruff`（已在 Pipfile 中），格式化用 `black`，排序用 `isort`。
- 前端：ESLint（`@zclzone` + `@unocss` 规则集），`prettier` 格式化。
- 类型：后端强制 `pydantic` Schema 做入参校验；前端以 JS 为主（未启用严格 TS）。
- 日志：后端统一使用 `loguru`，结构化字段 `logger.info(...)` 方式输出。

---

## AI 使用指引

- 修改爬虫逻辑时，重点关注反爬机制：`SmartIPManager`、`IPAnomalyDetector` 在 `jobs_spider/boss/boos_api.py` 中实现，随机延迟至少 10 秒。
- 新增 API 路由后需同步在 `app/api/v1/__init__.py` 注册，并执行 `api_controller.refresh_api()` 更新权限表。
- ClickHouse 表结构变更在 `app/core/clickhouse_init.py` 中维护，**不走 Aerich 迁移**。
- MySQL 模型变更走 Aerich（`aerich migrate && aerich upgrade`）。
- 前端新增页面需要在 `web/src/views/{模块}/route.js` 和后端 `init_menus()` 中同步注册菜单。
- `config.py` 中已硬编码真实 MySQL/ClickHouse 连接串和 SMTP 凭据，**提交代码前务必确认不泄露敏感信息**。
