本地私有开发规范
本文档面向 私有部署(private) 场景下的本地开发、构建与调试,区别于 SaaS 多租户模式。
1. 环境要求
| 工具 | 版本要求 | 说明 |
|---|---|---|
| Java | 17+ | 建议 Eclipse Adoptium / Microsoft JDK |
| Kotlin | 1.9.24 | 由 Gradle 插件管理 |
| Gradle | 8.13+ | 使用项目自带的 gradlew 包装器 |
| Node.js | 18+ | 仅用于前端开发 |
| pnpm / npm | 最新稳定版 | 前端依赖管理 |
| MySQL | 8.0+ / PostgreSQL | 数据库 |
| Git | 2.40+ | 版本控制 |
Windows 特别注意
- 请使用 PowerShell 执行 Gradle 命令。
JAVA_HOME必须显式指向 JDK 17 安装目录。- 避免在
.gitignore忽略的目录(如.gradle/)下执行构建命令。
# PowerShell 示例
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-17.0.13.11-hotspot"
& "E:\develop-space\dimebia-com\gradlew" build -x test
2. 项目结构
dimebia-com/
├── core/ # MIT License - 核心领域层
│ ├── model/ # JPA 实体
│ ├── repository/ # 数据访问层(JPA + jOOQ)
│ ├── service/ # 业务逻辑
│ ├── account/ # 账户管理
│ ├── billing/ # 计费引擎
│ ├── reconciliation/ # 对账引擎
│ ├── tax/ # 税务计算
│ ├── plugin/ # 支付插件系统
│ ├── invoice/ # 发票管理
│ ├── iso20022/ # ISO 20022 消息
│ ├── dto/ # 数据传输对象
│ ├── util/ # 工具类
│ ├── exception/ # 异常处理
│ └── audit/ # 审计日志
├── saas/ # Commercial License - SaaS 扩展
│ ├── config/ # 租户配置
│ ├── security/ # JWT、认证
│ ├── notification/ # 邮件、短信、Webhook
│ ├── report/ # 报表服务
│ └── admin/ # 管理后台
├── boot/ # MIT License - 应用启动模块
│ ├── src/main/kotlin/.../controller/ # REST 控制器
│ ├── src/main/kotlin/.../configuration/ # 配置类
│ ├── src/main/resources/ # 配置文件、Flyway 迁移
│ └── src/main/resources/webapp/ # 前端构建产物(自动复制)
├── admin-ui/ # MIT License - Web 管理界面
│ ├── src/
│ │ ├── lib/
│ │ │ ├── api/ # API 客户端
│ │ │ ├── components/ # Svelte UI 组件
│ │ │ ├── pages/ # 页面组件
│ │ │ ├── stores/ # Svelte stores
│ │ │ └── types/ # TypeScript 类型
│ │ └── routes/ # SvelteKit 路由
│ ├── package.json
│ ├── svelte.config.js
│ ├── vite.config.ts
│ └── tailwind.config.ts
├── openspec/ # 技术规范与变更提案
│ ├── changes/ # 进行中的变更
│ │ └── archive/ # 已归档的变更
│ └── specs/ # 已发布的技术规范
├── docs/ # 文档
├── docker/ # Docker 配置
└── build.gradle.kts # Gradle 构建脚本
模块依赖关系
boot → saas → core
- core:纯领域逻辑,不依赖任何上层模块。
- saas:SaaS 多租户扩展,依赖 core。
- boot:应用入口、Web 层、配置,依赖 saas 和 core。
3. 开发命令
后端(Kotlin / Gradle)
# 编译所有模块(跳过测试)
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-17.0.13.11-hotspot"
& "E:\develop-space\dimebia-com\gradlew" build -x test
# 仅编译 Kotlin 源码
& "E:\develop-space\dimebia-com\gradlew" compileKotlin
# 运行测试
& "E:\develop-space\dimebia-com\gradlew" test
# 构建生产 JAR(shadow)
& "E:\develop-space\dimebia-com\gradlew" :boot:shadowJar
# 前端构建并复制到后端资源目录
& "E:\develop-space\dimebia-com\gradlew" :boot:copyFrontendToBackend
前端(Svelte / Vite)
# 安装依赖
cd E:\develop-space\dimebia-com\admin-ui
pnpm install
# 开发模式(热重载)
pnpm run dev
# 生产构建
pnpm run build
# 预览生产构建
pnpm run preview
Docker
# 构建镜像
docker build -f docker/Dockerfile -t dimebia:latest .
# 启动服务
docker-compose -f docker/docker-compose.yml up -d
4. 代码规范
4.1 Kotlin 后端
| 项目 | 规范 |
|---|---|
| 包名 | 全小写,无下划线,如 com.alaikis.dimebia.service |
| 类名 | PascalCase,如 DeveloperService |
| 函数/变量 | camelCase,如 generateDeveloper() |
| 常量 | UPPER_SNAKE_CASE,如 MAX_RETRY_COUNT |
| 文件编码 | UTF-8,LF 换行(Git 会自动转换 CRLF) |
| 导入顺序 | 标准库 → 第三方库 → 项目内部 |
| 空安全 | 优先使用非空类型,必要时使用 ? |
| 数据类 | 优先使用 data class 表示 DTO/Entity |
| 单例 | 使用 object 声明工具类 |
| 依赖注入 | 构造参数注入,避免字段注入 |
| 日志 | 使用 SLF4J,private val logger = LoggerFactory.getLogger(XXX::class.java) |
Controller 层规范
- 所有 Controller 必须标注
@Controller和@Mapping。 - 方法返回
Map<String, Any>,统一响应格式:mapOf("code" to 200,"message" to "success","data" to result) - 异常捕获:在 Controller 层捕获异常,返回
code: 500和错误信息。 - 鉴权:使用
SecurityContext获取当前用户信息。
Service 层规范
- 标记为
@Component以便 Solon DI 装配。 - 业务逻辑必须放在 Service 层,Controller 只做参数校验和响应包装。
- 事务边界:默认方法级事务,复杂场景使用
@Transactional。
Repository 层规范
- 简单 CRUD 使用 JPA
EntityManager。 - 复杂查询使用 jOOQ。
- 禁止使用 JPA Criteria API(项目规范)。
4.2 前端(Svelte / TypeScript)
| 项目 | 规范 |
|---|---|
| 组件名 | PascalCase,如 Card.svelte |
| 文件编码 | UTF-8 |
| 样式 | Tailwind CSS utility-first |
| 图标 | lucide-svelte |
| 状态管理 | Svelte stores(src/lib/stores/) |
| API 调用 | 统一通过 src/lib/api/client.ts |
| 类型定义 | 放在 src/lib/types/ |
组件规范
- Props:使用
export let声明。 - 事件:使用
createEventDispatcher或直接传递回调。 - 生命周期:使用
onMount、onDestroy。 - 响应式:使用
$:reactive statements。
API 调用规范
- 所有 API 请求必须通过
src/lib/api/client.ts中的api对象。 - 不要在组件中直接使用
fetch。 - 认证失败自动 refresh token 逻辑已在
client.ts中实现。
5. 数据库规范
5.1 迁移脚本
- 使用 Flyway 管理数据库版本。
- 迁移脚本放在:
core/src/main/resources/db/migration/(核心表)boot/src/main/resources/db/migration/(启动模块表)
- 命名规范:
V{版本号}__{描述}.sql,如V1__create_core_tables.sql。 - 版本号递增,不可重复。
5.2 字段命名
- 数据库字段:
snake_case,如created_time、user_id。 - JPA 实体字段:
camelCase,通过@Column(name = "...")映射。 - 主键:
id BIGINT PRIMARY KEY AUTO_INCREMENT(MySQL)。 - 租户字段:
tenant_id VARCHAR(64) NOT NULL。 - 时间字段:
created_time DATETIME、updated_time DATETIME。
5.3 索引规范
- 外键字段必须建立索引。
- 高频查询条件字段建立索引。
- 索引脚本放在
V2__create_indexes.sql。
6. 安全规范
6.1 认证
- 使用 JWT(HMAC-SHA256)进行认证。
- Access Token 过期时间:默认 86400 秒(24 小时)。
- Refresh Token 过期时间:默认 604800 秒(7 天)。
- JWT 密钥必须通过环境变量
APP_JWT_SECRET配置,长度至少 32 字符。 - 禁止在代码或配置文件中硬编码 JWT 密钥。
6.2 密码
- 使用 BCrypt 加密,强度 10。
- 密码最小长度:6 字符。
6.3 API 密钥
- Developer 密钥使用 32 位随机字符串(
A-Za-z0-9)。 - 生成时返回完整 SK,后续列表只显示掩码(前 4 位 + 后 4 位)。
- 密钥可撤销(state 置为 0),保留审计记录。
6.4 租户隔离
- SaaS 模式下,所有查询必须带上
tenant_id过滤。 - 使用
@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")实现自动过滤。 TenantAwareEntityListener自动设置tenant_id。
6.5 速率限制
- 用户级:100 请求/分钟。
- IP 级:50 请求/分钟。
- 使用令牌桶算法实现。
7. 部署规范
7.1 环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
DB_URL | 是 | JDBC 连接 URL,如 jdbc:mysql://127.0.0.1:3306/dimebia |
DB_USERNAME | 是 | 数据库用户名 |
DB_PASSWORD | 是 | 数据库密码 |
DB_DRIVER | 否 | JDBC 驱动类名 |
JPA_DDL_AUTO | 否 | Hibernate DDL 模式,私有部署推荐 none |
APP_JWT_SECRET | 是 | JWT 签名密钥,至少 32 字符 |
DEPLOYMENT_MODE | 否 | private 或 saas,默认 private |
7.2 生产构建
# 1. 前端构建并复制到后端
& "E:\develop-space\dimebia-com\gradlew" :boot:copyFrontendToBackend
# 2. 构建 shadow JAR
& "E:\develop-space\dimebia-com\gradlew" :boot:shadowJar
# 3. 运行
java -DDB_URL="jdbc:mysql://127.0.0.1:3306/dimebia" `
-DDB_USERNAME="dimebia" `
-DDB_PASSWORD="your_password" `
-DAPP_JWT_SECRET="your-secret-key-at-least-32-chars" `
-jar boot/build/libs/boot-0.0.1-SNAPSHOT.jar
7.3 Docker 部署
docker build -f docker/Dockerfile -t dimebia:latest .
docker run -p 8080:8080 \
-e DB_URL="jdbc:mysql://host.docker.internal:3306/dimebia" \
-e DB_USERNAME="dimebia" \
-e DB_PASSWORD="your_password" \
-e APP_JWT_SECRET="your-secret-key-at-least-32-chars" \
dimebia:latest
8. 多仓协作规范
8.1 主仓与 SDK 仓
- 主仓:
dimebia.com,包含核心代码、OpenAPI 契约。 - SDK 仓:
dimebia-<lang>,由各语言 SDK 组成。 - 文档站:
docs.dimebia.com,即本文档站点。
8.2 契约同步
- OpenAPI 契约的唯一真相源在 主仓
docs/openapi/。 - SDK 与文档站通过 CI 订阅主仓 release 事件同步。
- 修改
docs/openapi/后,需在 PR 描述中提醒各 SDK 仓 tech lead 同步。
8.3 禁止事项
- 禁止将 SDK 或文档仓的改动提交到主仓。
- 禁止手动编辑
.impetus.yaml,使用impetus-state脚本管理状态。 - 禁止提交密钥、密码等敏感信息到版本控制。
9. 许可证
| 模块 | 许可证 |
|---|---|
| core | MIT |
| boot | MIT |
| admin-ui | MIT |
| saas | Commercial License(联系 license@dimebia.com) |
10. 常见问题
Q: 私有部署是否需要租户(tenant)概念?
A: 私有部署模式下,系统以单租户运行,tenant_id 仍会写入数据库(用于审计和数据隔离),但不会有多租户路由逻辑。
Q: 如 何切换部署模式?
A: 设置环境变量 DEPLOYMENT_MODE=private 或 DEPLOYMENT_MODE=saas。默认值为 private。
Q: 数据库迁移脚本会自动执行吗?
A: 是的。Flyway 会在应用启动时自动检测并执行未运行的迁移脚本。
Q: 前端构建产物需要提交到 Git 吗?
A: 需要。boot/src/main/resources/webapp/ 目录需要提交到 Git,确保生产环境 JAR 包含最新前端资源。
11. 更新日志
| 日期 | 版本 | 说明 |
|---|---|---|
| 2026-08-18 | 1.0.0 | 初始版本 |