# ProjectMoneyX 系统详细设计说明书

## 1. 架构概览与技术选型

ProjectMoneyX 定位为 Firefly III 的前置数据治理层。系统核心目标是屏蔽多源账单（如支付宝、微信）的底层差异，通过清洗、去重、映射，最终生成规范化的账单数据。

### 1.1 技术栈基准

* **前端 (Frontend)**: Vue3 + TypeScript + Vuetify (提供规范的 Material Design 风格，适合本地管理后台界面)。
* **后端 (Backend)**: Golang + GIN (高性能、轻量级的 Web 框架，适合提供 API 与静态服务)。
* **数据层 (Database)**: SQLite + GORM (满足本地优先、保护隐私的需求，GORM 提供便捷的结构体映射能力)。
* **部署架构**: Docker 容器化部署 / 跨平台二进制单体可执行文件（整合静态前端资源与后端服务）。

### 1.2 系统分层架构图

系统采用经典的领域驱动设计（DDD）分层思想，严格隔离各平台差异：

```mermaid
graph TD
    subgraph "展现层 (Vue3 + TS + Vuetify)"
        UI_Upload[导入中心/文件上传]
        UI_Preview[数据清洗预览]
        UI_Match[去重与链路确认]
        UI_Rule[规则与映射管理]
        UI_Task[导入任务与审计]
    end

    subgraph "接入层 (GIN Framework)"
        API_File[文件上传 API]
        API_Data[数据流转 API]
        API_Config[系统配置 API]
    end

    subgraph "业务逻辑层 (Core Domain)"
        subgraph "Adapter 解析层 (插件化)"
            Parser_Alipay[支付宝解析器]
            Parser_WeChat[微信解析器]
            Parser_Bank[银行解析器]
        end
        
        Norm_Engine[Normalize 标准化引擎]
        Match_Engine[Match 去重与链路合并引擎]
        Rule_Engine[Rule 规则映射引擎]
        Export_Engine[Export 导出推送引擎]
    end

    subgraph "数据持久层 (GORM + SQLite)"
        DB_Source[(SourceFiles)]
        DB_Raw[(RawRecords)]
        DB_Trans[(Transactions)]
        DB_Rule[(Rules & Dedup)]
    end

    subgraph "外部系统 (External)"
        Firefly[Firefly III API]
        DataImporter[Data Importer]
    end

    %% 关联关系
    UI_Upload --> API_File
    UI_Preview & UI_Match & UI_Rule & UI_Task --> API_Data
    
    API_File --> Parser_Alipay
    API_File --> Parser_WeChat
    API_File --> Parser_Bank

    Parser_Alipay & Parser_WeChat & Parser_Bank --> Norm_Engine
    Norm_Engine --> Match_Engine
    Match_Engine --> Rule_Engine
    Rule_Engine --> Export_Engine
    
    Export_Engine --> Firefly
    Export_Engine --> DataImporter

    Norm_Engine -.-> DB_Raw
    Match_Engine -.-> DB_Trans
    Rule_Engine -.-> DB_Rule

```

---

## 2. 核心业务与数据流转设计

数据从原始文件到导入 Firefly III，经历了标准的 ETL（Extract, Transform, Load）过程。以下是核心数据管道时序图：

```mermaid
sequenceDiagram
    autonumber
    actor User as 用户
    participant Web as 前端 (Vue3)
    participant API as 后端接口 (GIN)
    participant Adapter as Adapter层
    participant Norm as 标准化引擎
    participant Match as 去重引擎
    participant Rule as 规则引擎
    participant DB as SQLite (GORM)
    participant Export as 导出引擎

    User->>Web: 上传账单文件 (如微信CSV)
    Web->>API: POST /api/v1/import/file
    API->>Adapter: 路由至对应平台 Parser
    Adapter->>DB: 存储原始文件元信息 (source_files)
    Adapter->>Norm: 解析每一行记录
    Norm->>Norm: 提取公共字段、规范化处理
    Norm->>DB: 批量入库 (raw_records & transactions 待清洗态)
    
    API->>Match: 触发基础与模糊去重
    Match->>Match: 1. 严格唯一性检查<br/>2. 多因子相似评分<br/>3. 跨源转账合并
    Match->>DB: 更新交易状态与合并关系 (dedup_relations)
    
    API->>Rule: 触发规则映射引擎
    Rule->>Rule: 执行分类/商户/账户映射
    Rule->>DB: 落盘映射结果 (category_mapped 等)
    
    API-->>Web: 返回清洗与映射预览结果
    User->>Web: 确认无误，发起导入
    Web->>API: POST /api/v1/export/task
    API->>Export: 执行推送流程
    Export->>External System: 调用 Data Importer / FF3 API
    Export->>DB: 记录导入结果 (import_tasks/results)
    API-->>Web: 返回导入状态

```

---

## 3. 关键模块详细设计

### 3.1 适配器层 (Adapter) 插件化设计

由于各平台格式多变，后端在 Golang 中必须抽象出统一的 `BillParser` 接口：

```go
type BillParser interface {
    GetPlatform() string // 返回平台标识，如 "alipay", "wechat"
    Parse(file io.Reader) ([]*RawRecord, error)
    Normalize(raw *RawRecord) (*Transaction, error)
}

```

#### 针对支付宝与微信的差异化适配策略

根据账单数据特征指南：

* **支付宝对齐策略**：支付宝拥有最为丰富的 22 种交易分类（餐饮美食、交通出行等）。将其定义为**系统全局基础分类基准 (`Category_Raw` 基准)**。
* **微信推断策略**：微信的“交易类型”多为支付动作（如扫二维码付款、微信红包），无实际消费语义。在微信的 Adapter `Normalize` 实现中，需引入**基于“商品”字段的关键词推断机制**，提取词根后强行映射回支付宝的 22 种分类中，再流转至后续处理链路。

### 3.2 去重与链路合并模块 (Match Engine)

基于 PRD 的要求，设计三层递进去重状态机：

1. **基础去重 (Hash & ID Match)**：利用 `source_platform` + `source_record_id` 进行 O(1) 级别的哈希拦截。
2. **模糊去重 (Multi-Factor Scoring)**：
针对缺失唯一 ID 的跨表记录，采用多因子评分算法：

$$Score = W_{time} \cdot f(\Delta t) + W_{amount} \cdot f(\Delta amt) + W_{merchant} \cdot Sim(M_1, M_2)$$



*(时间容差设为默认 $\pm5$ 分钟，金额容差限额针对手续费特定配置)。*
3. **链路合并 (Transfer Linkage)**：
识别 `direction` 为出金和入金的两笔高分记录，若来源为 `CCB(建行)`，对手方为 `Alipay`，且时间金额一致，则自动将 `direction` 改写为 `Transfer`，关联 `parent_order_id`。

### 3.3 规则引擎层 (Rule Engine)

采用两段式规则映射，ProjectMoneyX 负责对齐语义与业务分类。

* **执行顺序**：对手方归一化 -> 账户映射 -> 标签打标 -> 最终分类映射。
* **存储结构**：采用 JSON 序列化存储条件表达式，在 Go 中使用类似 `govaluate` 或自定义简单的 AST 引擎解析。

---

## 4. 数据库结构设计 (GORM)

基于核心交易模型的要求，以下为关系实体（ER）设计：

```mermaid
erDiagram
    SOURCE_FILES ||--o{ RAW_RECORDS : contains
    RAW_RECORDS ||--|| TRANSACTIONS : normalizes_to
    TRANSACTIONS ||--o{ DEDUP_RELATIONS : has
    IMPORT_TASKS ||--o{ TRANSACTIONS : processes
    
    SOURCE_FILES {
        string id PK
        string file_name
        string file_hash "文件指纹防重复上传"
        string source_platform
        datetime import_time
    }
    
    TRANSACTIONS {
        string transaction_id PK "系统唯一ID"
        string source_platform "alipay/wechat/ccb等"
        string source_record_id "原始流水号"
        datetime trade_time "统一UTC+8时区时间"
        decimal amount "高精度金额,绝对值"
        string currency "CNY/USD等"
        string direction "收入/支出/转账/退款"
        string counterparty "交易对手"
        string merchant_name "商户名"
        string category_raw "原始分类"
        string category_mapped "映射后分类"
        string order_id "订单号"
        string parent_order_id "父链路号"
        string status "待清洗/待导入/已导入/失败"
    }

    RULES {
        int id PK
        string rule_type "分类/账户/商户别名"
        string match_condition "JSON格式匹配规则"
        string target_value "映射目标值"
        int priority "优先级排序"
    }

```

---

## 5. 核心接口设计规范 (GIN API)

系统遵循 RESTful 风格，采用 JSON 通信规范：

* `POST /api/v1/files/upload`：账单文件上传，采用 `multipart/form-data`，返回解析批次 `batch_id`。
* `GET /api/v1/transactions`：分页获取当前批次的标准化交易记录，支持按状态（如：疑似重复、待确认）过滤。
* `POST /api/v1/rules/evaluate`：触发重新评估本地规则（当用户修改分类映射规则后调用）。
* `POST /api/v1/export/run`：一键触发推送逻辑，下发 `batch_id` 至 Data Importer 或 Firefly III。
