初始化
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
---
|
||||
inclusion: manual
|
||||
---
|
||||
|
||||
# 代码开发风格文档
|
||||
|
||||
本项目为 Python 3.12 纯后台定时任务服务,基于 asyncio + SQLAlchemy + APScheduler,应用主目录为 `app/`。
|
||||
|
||||
## 项目结构
|
||||
|
||||
- `app/config/` — 配置层:Pydantic Settings 统一配置
|
||||
- `app/core/` — 核心基础设施:双数据源连接、日志
|
||||
- `app/ai/` — AI 能力层:LLM 模型枚举、场景配置、Prompt 模板
|
||||
- `app/models/` — ORM 模型层:分 pg/ 和 mysql/ 两个子包
|
||||
- `app/services/` — 业务逻辑层:清洗、补充、恢复、下架等异步服务
|
||||
- `app/scheduler/` — 调度层:APScheduler 定时任务注册
|
||||
|
||||
## 命名约定
|
||||
|
||||
### 文件命名
|
||||
- 全部小写,下划线分隔,如 `job_clean_service.py`、`dict_cache_service.py`
|
||||
- ORM 模型文件与表名对应(去掉 `bg_` 或 `app_` 前缀),如 `job.py` 对应 `bg_job`
|
||||
|
||||
### 类命名
|
||||
- ORM 模型用 PascalCase 业务名,无后缀,如 `Job`、`Company`、`AppJobData`
|
||||
- 字典缓存用 `DictCacheService`
|
||||
- 枚举类以大写命名,如 `LLM`
|
||||
- 场景配置类以 `Model` 结尾,如 `JobCleanModel`、`CompanyCleanModel`
|
||||
|
||||
### 变量与函数命名
|
||||
- 函数和变量使用 snake_case,如 `run_job_clean`、`data_id`
|
||||
- 私有函数以单下划线开头,如 `_do_clean`、`_build_user_message`
|
||||
- 常量使用全大写下划线,如 `JOB_STRUCTURE_SYSTEM`
|
||||
- 全局单例小写,如 `dict_cache`、`_id_gen`
|
||||
|
||||
## 类型注解
|
||||
|
||||
- 所有函数参数和返回值必须有类型注解
|
||||
- ORM 模型字段使用 `Mapped[T]` + `mapped_column()` 声明
|
||||
- 可选字段使用 `Optional[T]` 或 `T | None`
|
||||
- 集合类型使用 `list[T]`、`dict[K, V]`(Python 3.12 内置泛型)
|
||||
|
||||
## 注释规范
|
||||
|
||||
- 模块级注释使用文件顶部的 docstring,说明模块用途
|
||||
- 函数注释使用 docstring,简洁描述功能
|
||||
- 复杂逻辑用行内注释 `#` 说明
|
||||
- ORM 模型字段通过 `comment` 参数说明含义
|
||||
|
||||
## 数据库使用规范
|
||||
|
||||
### 双数据源
|
||||
- PostgreSQL 会话通过 `PgSession()` 获取,用于 `app_job_data` 表操作
|
||||
- MySQL 会话通过 `MysqlSession()` 获取,用于业务表操作
|
||||
- 每次操作用 `async with XxxSession() as session` 获取会话,手动 `await session.commit()`
|
||||
|
||||
### SQL 风格
|
||||
- 简单操作使用 `sqlalchemy.text()` 原生 SQL,保持直观
|
||||
- 批量插入使用 `insert(Model).values(...)` 或 `insert(Model), [dict...]`
|
||||
- 锁定使用 `FOR UPDATE SKIP LOCKED`(PG)防阻塞
|
||||
|
||||
### 不做分布式事务
|
||||
- PG 和 MySQL 独立操作,不跨库事务
|
||||
- 失败靠僵尸恢复机制重试
|
||||
|
||||
## 异步规范
|
||||
|
||||
- 所有数据库操作、AI 调用使用 `async/await`
|
||||
- 并发控制使用 `asyncio.Semaphore`
|
||||
- 互斥操作使用 `asyncio.Lock()`(如公司查找或创建)
|
||||
- 批量任务使用 `asyncio.gather(*tasks, return_exceptions=True)`
|
||||
|
||||
## AI 调用规范
|
||||
|
||||
- 业务代码从 `app.ai.model_config` 引用场景配置类,不直接使用 `LLM` 枚举
|
||||
- AI 调用统一通过 `app.services.ai_tool.ai_chat_json()` 封装(异步调用 + JSON 清洗 + 解析)
|
||||
- AI 调用失败不影响主流程(第二次/第三次 AI 调用独立 try-catch)
|
||||
- 修改模型或参数只需改 `model_config.py`
|
||||
|
||||
## 日志规范
|
||||
|
||||
- 使用 `from app.core.logger import log`
|
||||
- 批次任务:记录锁定数量和完成汇总
|
||||
- 单条处理:记录关键结果(入库成功/丢弃/跳过),格式 `[id=xxx] 描述`
|
||||
- 异常:`log.error` 记录异常详情
|
||||
- 非关键失败:`log.warning` 记录但不中断
|
||||
|
||||
## 配置规范
|
||||
|
||||
- 所有可调参数放在 `settings.py`,通过 `.env` 文件覆盖
|
||||
- 运行时参数(batch_size、concurrency、interval、expire_days)必须可配置
|
||||
- 数据库密码通过 `urllib.parse.quote` 编码后拼入 URL
|
||||
|
||||
## 代码格式规范
|
||||
|
||||
### 紧凑风格
|
||||
- 避免过度换行,保持代码紧凑易读
|
||||
- f-string 拼接优先写在一行
|
||||
- 方法参数列表较多时,可适当换行但保持紧凑
|
||||
|
||||
### 模块组织
|
||||
- 每个 service 文件对外暴露一个 `run_xxx()` 异步函数作为入口
|
||||
- 内部逻辑拆分为 `_xxx` 私有函数
|
||||
- import 按标准库 → 第三方库 → 项目内部 顺序排列
|
||||
Reference in New Issue
Block a user