# GEO 平台 MVP 开发计划

> **文档版本**: v1.0
> **创建日期**: 2026-05-01
> **状态**: 待执行
> **依据文档**:
> - [PRD v1.0](../1-PRD/01-GEO平台PRD-v1.0.md)
> - [需求规格说明书](../2-需求规格/01-GEO平台需求规格说明书-v1.0.md)
> - [技术详细设计](../3-技术设计/01-GEO平台技术详细设计-v1.0.md)

---

## 目录

1. [MVP范围定义](#1-mvp范围定义)
2. [技术架构决策](#2-技术架构决策)
3. [开发任务分解](#3-开发任务分解)
4. [测试策略](#4-测试策略)
5. [执行计划](#5-执行计划)

---

## 1. MVP范围定义

### 1.1 核心功能

| 功能模块 | 功能点 | 优先级 | 验收标准 |
|---------|--------|--------|---------|
| **品牌管理** | 添加品牌 | P0 | 可添加品牌名称、别名、监控平台 |
| | 编辑品牌 | P0 | 可修改品牌别名和监控平台 |
| | 删除品牌 | P0 | 可删除品牌及关联数据 |
| | 品牌列表 | P0 | 展示用户所有品牌 |
| **竞品管理** | 添加竞品 | P1 | 可添加竞品名称和别名 |
| | 删除竞品 | P1 | 可删除竞品 |
| | 竞品列表 | P1 | 展示品牌的竞品 |
| **AI采集** | 7平台采集 | P0 | 支持文心一言/kimi/通义/豆包/讯飞/天工/清言 |
| | 手动触发采集 | P0 | 点击立即查询 |
| **评分服务** | 评分计算 | P0 | 按公式计算综合评分 |
| | 评分展示 | P0 | Dashboard展示评分 |
| **竞品对比** | 对比数据 | P1 | 展示竞品评分对比 |
| | 雷达图 | P2 | 可延后 |
| **报告导出** | CSV导出 | P1 | 可导出引用数据 |

### 1.2 不包含在MVP

以下功能延后至v1.5：
- 情感分析
- PDF报告生成
- 邮件预警通知
- 白标功能

---

## 2. 技术架构决策

### 2.1 后端架构

**开发原则**:
1. **TDD**: 每个功能先写测试，再写实现
2. **分层**: API → Service → Repository
3. **异步**: 使用 async/await
4. **类型安全**: Pydantic模型验证

**模块结构**:
```
backend/app/
├── api/
│   ├── brands.py          # [新增] 品牌API
│   ├── competitors.py      # [新增] 竞品API
│   └── scoring.py          # [新增] 评分API
├── models/
│   ├── brand.py            # [新增] 品牌模型
│   └── competitor.py       # [新增] 竞品模型
├── schemas/
│   ├── brand.py            # [新增] 品牌Schema
│   └── competitor.py       # [新增] 竞品Schema
├── services/
│   ├── brand_service.py    # [新增] 品牌服务
│   ├── competitor_service.py # [新增] 竞品服务
│   └── scoring_service.py  # [新增] 评分服务
└── workers/
    ├── llm_adapter.py      # [新增] LLM适配器
    └── citation_engine.py  # [重构] 使用LLM适配器
```

### 2.2 前端架构

**页面结构**:
```
frontend/app/(dashboard)/
├── brands/
│   ├── page.tsx            # 品牌列表页
│   ├── new/page.tsx        # 添加品牌页
│   └── [id]/page.tsx      # 品牌详情页
├── compare/
│   └── page.tsx            # 竞品对比页
└── reports/
    └── page.tsx            # 报告导出页
```

---

## 3. 开发任务分解

### 阶段一: 后端基础设施 (5个任务)

#### Task 1.1: 品牌数据模型

**文件**:
- 创建: `backend/app/models/brand.py`
- 创建: `backend/app/schemas/brand.py`
- 创建: `backend/tests/test_models/test_brand.py`

**Step 1: 编写测试**

```python
# backend/tests/test_models/test_brand.py
import pytest
from uuid import uuid4
from app.models.brand import Brand

def test_brand_create():
    brand = Brand(
        id=uuid4(),
        user_id=uuid4(),
        name="测试品牌",
        aliases=["测试", "test"],
        platforms=["wenxin", "kimi"],
        frequency="daily"
    )
    assert brand.name == "测试品牌"
    assert brand.platforms == ["wenxin", "kimi"]
```

**Step 2: 运行测试**
```bash
cd backend && pytest tests/test_models/test_brand.py -v
# 预期: FAIL - module not found
```

**Step 3: 编写实现**

```python
# backend/app/models/brand.py
from sqlalchemy import Column, String, JSON
from sqlalchemy.dialects.postgresql import UUID
from app.database import Base
import uuid

class Brand(Base):
    __tablename__ = "brands"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    user_id = Column(UUID(as_uuid=True), nullable=False)
    name = Column(String(50), nullable=False)
    aliases = Column(JSON, default=list)
    platforms = Column(JSON, nullable=False)
    frequency = Column(String(20), default="weekly")
    status = Column(String(20), default="active")
```

**Step 4: 运行测试**
```bash
pytest tests/test_models/test_brand.py -v
# 预期: PASS
```

---

#### Task 1.2: 竞品数据模型

**文件**:
- 创建: `backend/app/models/competitor.py`
- 创建: `backend/app/schemas/competitor.py`
- 创建: `backend/tests/test_models/test_competitor.py`

**测试 → 实现流程同上**

---

#### Task 1.3: 品牌服务层

**文件**:
- 创建: `backend/app/services/brand_service.py`
- 创建: `backend/tests/test_services/test_brand_service.py`

**测试用例**:
```python
def test_brand_service_create():
    # 测试创建品牌
    pass

def test_brand_service_list_by_user():
    # 测试按用户筛选
    pass

def test_brand_service_update():
    # 测试更新品牌
    pass

def test_brand_service_delete():
    # 测试删除品牌
    pass
```

---

#### Task 1.4: 竞品服务层

**文件**:
- 创建: `backend/app/services/competitor_service.py`
- 创建: `backend/tests/test_services/test_competitor_service.py`

---

#### Task 1.5: 品牌API路由

**文件**:
- 创建: `backend/app/api/brands.py`
- 创建: `backend/app/api/competitors.py`
- 创建: `backend/tests/test_api/test_brands.py`
- 修改: `backend/app/main.py` (注册路由)

**API端点**:

| 方法 | 端点 | 描述 |
|------|------|------|
| GET | /api/v1/brands/ | 品牌列表 |
| POST | /api/v1/brands/ | 创建品牌 |
| GET | /api/v1/brands/{id}/ | 品牌详情 |
| PUT | /api/v1/brands/{id}/ | 更新品牌 |
| DELETE | /api/v1/brands/{id}/ | 删除品牌 |
| GET | /api/v1/brands/{id}/competitors/ | 竞品列表 |
| POST | /api/v1/brands/{id}/competitors/ | 添加竞品 |
| DELETE | /api/v1/brands/{id}/competitors/{comp_id}/ | 删除竞品 |

---

### 阶段二: 核心业务 (5个任务)

#### Task 2.1: LLM适配器

**文件**:
- 创建: `backend/app/workers/llm_adapter.py`
- 创建: `backend/tests/test_workers/test_llm_adapter.py`

**核心接口**:
```python
class LLMAdapter:
    async def query_brand_citation(
        self,
        keyword: str,
        brand_name: str,
        brand_aliases: list[str]
    ) -> CitationResult:
        """
        使用LLM检测品牌引用
        返回: cited, position, citation_text, sentiment, confidence
        """
        pass
```

**Prompt模板**:
```python
BRAND_CITATION_PROMPT = """
分析以下AI搜索查询中是否提到了目标品牌。

查询关键词: {keyword}
目标品牌: {brand_name}
品牌别名: {brand_aliases}

返回JSON格式:
{{"cited": true/false, "position": 1, "citation_text": "...", "sentiment": "positive/neutral/negative", "confidence": 0.95}}
"""
```

---

#### Task 2.2: 评分服务

**文件**:
- 创建: `backend/app/services/scoring_service.py`
- 创建: `backend/tests/test_services/test_scoring_service.py`

**评分公式**:
```
综合评分 = MIN(100, 提及率得分×30% + SOV得分×40% + 引用质量得分×30%)

提及率得分 = (品牌被引用次数 / 查询总次数) × 100
SOV得分 = (品牌引用次数 / 品牌+竞品引用次数) × 100
引用质量得分 = (情感系数×0.4 + 位置系数×0.3 + 长度系数×0.3) × 100
```

**测试用例**:
```python
def test_scoring_mention_rate():
    # 测试提及率计算
    pass

def test_scoring_sov():
    # 测试SOV计算
    pass

def test_scoring_quality():
    # 测试引用质量计算
    pass

def test_scoring_overall():
    # 测试综合评分不超过100
    assert overall_score <= 100
```

---

#### Task 2.3: 评分API

**文件**:
- 创建: `backend/app/api/scoring.py`
- 创建: `backend/tests/test_api/test_scoring.py`

**API端点**:

| 方法 | 端点 | 描述 |
|------|------|------|
| GET | /api/v1/brands/{id}/score/ | 获取品牌评分 |
| GET | /api/v1/brands/{id}/score/history/ | 评分历史 |

---

#### Task 2.4: 报告导出API

**文件**:
- 创建: `backend/app/api/reports.py` (扩展现有)
- 创建: `backend/tests/test_api/test_reports.py`

**API端点**:

| 方法 | 端点 | 描述 |
|------|------|------|
| GET | /api/v1/reports/export/csv/ | 导出CSV |

---

#### Task 2.5: 集成测试

**文件**:
- 创建: `backend/tests/test_integration/`

**测试场景**:
```python
def test_full_brand_query_flow():
    """完整流程: 创建品牌 → 触发采集 → 获取评分"""
    pass

def test_competitor_comparison_flow():
    """竞品对比: 品牌A vs 品牌B"""
    pass
```

---

### 阶段三: 前端开发 (4个任务)

#### Task 3.1: 品牌管理页面

**文件**:
- 创建: `frontend/app/(dashboard)/brands/page.tsx`
- 创建: `frontend/app/(dashboard)/brands/new/page.tsx`
- 创建: `frontend/app/(dashboard)/brands/[id]/page.tsx`
- 创建: `frontend/tests/test_pages/test_brands.py`

**组件结构**:
```
BrandListPage
├── BrandCard
├── AddBrandDialog
└── BrandDetailPage
    ├── BrandInfo
    ├── PlatformStatus
    └── QueryButton
```

---

#### Task 3.2: Dashboard核心看板

**文件**:
- 修改: `frontend/app/(dashboard)/dashboard/page.tsx`
- 创建: `frontend/tests/test_pages/test_dashboard.py`

**UI布局**:
```
┌─────────────────────────────────────────────────┐
│  品牌曝光度评分                                 │
│  ┌─────────┐                                    │
│  │   78    │  /100  较昨日 +3                  │
│  └─────────┘                                    │
│                                                 │
│  平台评分:                                      │
│  ┌────────┬────────┬────────┬────────┐          │
│  │  文心   │  Kimi  │  通义   │  豆包   │       │
│  └────────┴────────┴────────┴────────┘          │
└─────────────────────────────────────────────────┘
```

---

#### Task 3.3: 竞品对比页面

**文件**:
- 创建: `frontend/app/(dashboard)/compare/page.tsx`
- 创建: `frontend/tests/test_pages/test_compare.py`

---

#### Task 3.4: 报告导出页面

**文件**:
- 创建: `frontend/app/(dashboard)/reports/page.tsx`
- 创建: `frontend/tests/test_pages/test_reports.py`

---

## 4. 测试策略

### 4.1 测试金字塔

```
        ┌───────────┐
        │   E2E     │  ← 少量关键流程
        │   Tests   │
       ┌───────────┐
       │ Integration│  ← API完整流程
       │   Tests   │
      ┌───────────┐
      │  Service  │  ← 业务逻辑
      │   Tests   │
     ┌───────────┐
     │  Unit     │  ← 数据模型、工具函数
     │   Tests   │
    └───────────┘
```

### 4.2 测试覆盖率目标

| 层级 | 覆盖率目标 |
|------|-----------|
| Unit Tests | 80%+ |
| Service Tests | 70%+ |
| API Tests | 60%+ |
| E2E Tests | 关键路径 |

### 4.3 测试执行命令

```bash
# 单元测试
cd backend && pytest tests/unit/ -v --cov=app

# 服务测试
cd backend && pytest tests/services/ -v --cov=app

# API测试
cd backend && pytest tests/api/ -v

# 前端测试
cd frontend && npm test

# E2E测试
cd frontend && npx playwright test
```

---

## 5. 执行计划

### 5.1 时间安排

| 阶段 | 任务 | 工期 | 累计 |
|------|------|------|------|
| **阶段一** | 后端基础设施 | 3天 | Day 1-3 |
| ├ Task 1.1 | 品牌数据模型 | 0.5天 | |
| ├ Task 1.2 | 竞品数据模型 | 0.5天 | |
| ├ Task 1.3 | 品牌服务层 | 0.5天 | |
| ├ Task 1.4 | 竞品服务层 | 0.5天 | |
| └ Task 1.5 | 品牌API路由 | 1天 | |
| **阶段二** | 核心业务 | 4天 | Day 4-7 |
| ├ Task 2.1 | LLM适配器 | 1天 | |
| ├ Task 2.2 | 评分服务 | 1天 | |
| ├ Task 2.3 | 评分API | 0.5天 | |
| ├ Task 2.4 | 报告导出API | 0.5天 | |
| └ Task 2.5 | 集成测试 | 1天 | |
| **阶段三** | 前端开发 | 3天 | Day 8-10 |
| ├ Task 3.1 | 品牌管理页面 | 1天 | |
| ├ Task 3.2 | Dashboard看板 | 1天 | |
| ├ Task 3.3 | 竞品对比页面 | 0.5天 | |
| └ Task 3.4 | 报告导出页面 | 0.5天 | |
| **阶段四** | 集成验收 | 1天 | Day 11 |
| └ Task 4.1 | 端到端测试 | 1天 | |

**总工期**: 11个工作日

### 5.2 里程碑

| 里程碑 | 日期 | 交付物 |
|--------|------|--------|
| M1 | Day 3 | 品牌API可用 |
| M2 | Day 7 | 评分服务可用 |
| M3 | Day 10 | 前端页面完成 |
| M4 | Day 11 | MVP完成 |

---

## 附录

### A. 参考文档

- [技术详细设计 v1.0](../3-技术设计/01-GEO平台技术详细设计-v1.0.md)
- [需求规格说明书 v1.0](../2-需求规格/01-GEO平台需求规格说明书-v1.0.md)
- [评分公式详解](./评分公式说明.md)

### B. 技术栈

| 组件 | 技术 | 版本 |
|------|------|------|
| 后端框架 | FastAPI | 0.109+ |
| ORM | SQLAlchemy | 2.0+ |
| 数据库 | PostgreSQL | 15+ |
| 前端框架 | Next.js | 14 |
| 测试框架 | pytest | - |
| E2E测试 | Playwright | - |
