# Java API 技术规范

## 运行环境
- JDK 17

## 框架选型
- Spring Boot 3.3.6 (spring-boot-starter-parent)
- ORM：MyBatis-Plus
- Lombok

## 架构约束
- API 采用多模块 Maven 项目结构，父项目统一管理依赖版本
- 项目名： geo-bps
- 包名前缀：com.geomative.bps.*
- 子模块划分：
  - `api-admin` 后台管理入口模块：需登录鉴权，引入 `website`、`device`、`library`、`permission` 等模块
  - `api-portal` 前端门户入口模块：无需登录，仅引入对外开放的业务模块
  - `device` 设备管理模块
  - `website` 网站管理后台
  - `library` 资料库模块
  - `permission` 权限管理模块
  - `common` 公共模块：工具类、基础配置、统一响应格式、全局异常处理等共享代码

- 项目路径：`apps/geo-bps-api/`
- groupId：`com.geomative.bsp`
- artifactId：`geo-bps-api`
- 项目整体结构：
```
apps/geo-bps-api/
├── pom.xml                 # 父 POM，统一依赖版本管理
├── api-admin/              # 后台管理入口，Spring Security 鉴权配置
├── api-portal/             # 前端门户入口，公开接口无需授权
├── business/               # 业务模块聚合器（pom packaging）
│   ├── pom.xml
│   ├── permission/         # 权限管理模块
│   ├── website/            # 网站业务模块（被两个入口共享）
│   ├── device/             # 设备管理模块
│   └── library/            # 资料库模块
└── common/                 # 公共工具、基础配置、统一响应体
```

## 编码规范

### 命名规范
- 类名使用 UpperCamelCase，如 `DeviceService`、`UserDO`
- 方法名、变量名使用 lowerCamelCase，如 `getUserById`、`deviceList`
- 常量全部大写，单词间用下划线，如 `MAX_RETRY_COUNT`
- 包名全部小写，如 `com.example.device.domain`
- 抽象类命名以 `Abstract` 开头；异常类命名以 `Exception` 结尾；测试类命名以被测类名开头、`Test` 结尾
- POJO 类中布尔类型变量不加 `is` 前缀，避免序列化问题
- 领域对象命名后缀约定：
  - 数据库映射对象：`XxxDO`
  - 数据传输对象：`XxxDTO`
  - 视图对象：`XxxVO`
  - 查询对象：`XxxQuery`
  - 命令对象：`XxxCommand`

### 注释规范
- 所有 public 类、方法必须有 Javadoc 注释
- 方法注释需说明功能、参数含义、返回值、可能抛出的异常
- 代码逻辑复杂处需有行内注释说明意图，而非描述代码本身
- 禁止保留无意义的注释和注释掉的废弃代码

### 异常处理
- 不允许捕获 `Exception` 等大类异常后不做任何处理（空 catch）
- 业务异常统一使用自定义异常类，继承 `RuntimeException`
- 不允许用异常控制正常业务流程
- finally 块中不允许使用 return

### 日志规范
- 使用 SLF4J + Logback，禁止直接使用 `System.out.println`
- 日志变量声明：`private static final Logger log = LoggerFactory.getLogger(XxxClass.class);`
- 日志输出使用占位符，禁止字符串拼接：`log.info("userId: {}", userId)`
- 异常日志必须输出完整堆栈：`log.error("message", e)`

### 集合与并发
- 初始化集合时指定初始容量，如 `new ArrayList<>(16)`
- 禁止在 foreach 循环中对集合进行 add/remove 操作
- 线程池不允许使用 `Executors` 创建，需通过 `ThreadPoolExecutor` 显式配置参数

### 其他
- 所有方法入参需做非空校验，使用 `Objects.requireNonNull` 或断言
- 魔法值（Magic Number）禁止直接出现在代码中，需定义为常量
- 返回值为集合类型时，不允许返回 null，应返回空集合

### DDD 分层架构
- 采用领域驱动设计（DDD）分层架构，每个子模块内部结构如下：

```
{module}/
├── interfaces/          # 接口层：Controller、DTO、Assembler
├── application/         # 应用层：ApplicationService、Command、Query
├── domain/              # 领域层：Entity、ValueObject、DomainService、Repository接口、DomainEvent
└── infrastructure/      # 基础设施层：Repository实现、Mapper、持久化对象(PO)、外部服务适配
```

## 数据库
- PostgreSQL 12.14 (Debian 12.14-1.pgdg110+1)

### 审计字段规范
- 所有业务表必须包含以下审计字段：
  - `created_at` TIMESTAMP NOT NULL — 创建时间，INSERT 时自动填充
  - `created_by` VARCHAR(64) NULL — 创建人（用户ID或用户名），字符类型
  - `updated_at` TIMESTAMP NOT NULL — 最后修改时间，INSERT 和 UPDATE 时自动填充
  - `updated_by` VARCHAR(64) NULL — 最后修改人（用户ID或用户名），字符类型
  - `deleted` TINYINT NOT NULL DEFAULT 0 — 删除状态，0=未删除，1=已删除

### 主键规范
- 所有业务表主键类型为 VARCHAR(64)，由应用层生成（如雪花算法、UUID 字符串等），不使用数据库自增或 UUID 类型

### PostgreSQL Schema 分模块
- 不同子模块的表使用不同的 PostgreSQL schema 进行隔离：
  - `perm` — permission 模块（admin_users、revoked_tokens、admin_menus、admin_roles 等）
  - `web` — website 模块（nav_menus、branches、sub_branches、pages、page_contents、page_seo、fixed_page_contents、enabled_locales 等）
  - `dev` — device 模块（quotations、access_logs、configurator_steps 等）
  - `lib` — library 模块（knowledge_articles 等）
  - `common` — 公共表（contact_submissions、system_config 等）
- MyBatis-Plus 通过 `@TableName(schema = "xxx")` 或全局配置指定 schema
- MyBatis-Plus 配置：
  - 通过 `MetaObjectHandler` 自动填充 `created_at`、`updated_at`
  - 通过 `@TableLogic` 注解标记 `deleted` 字段实现逻辑删除
  - 查询默认过滤 `deleted=1` 的记录

## 部署
- 集成 Nginx 作为前置代理
  - `api-admin`：Nginx 直接流量穿透，转发至单实例后台管理服务
  - `api-portal`：Nginx 4层负载均衡（TCP/stream模块），支持多实例横向扩展
