@wneng/create-keel 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +211 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/templates/ci-gitee/files/PULL_REQUEST_TEMPLATE.md +13 -1
- package/src/templates/ci-gitee/files/pipeline.yml +71 -0
- package/src/templates/ci-github/files/PULL_REQUEST_TEMPLATE.md +13 -1
- package/src/templates/ci-github/files/ci.yml +169 -0
- package/src/templates/contracts-events/fragment.yaml +1 -1
- package/src/templates/contracts-rest-events/fragment.yaml +1 -1
- package/src/templates/db-go-elasticsearch/files/Makefile +18 -0
- package/src/templates/db-go-elasticsearch/files/apply_templates.go +80 -0
- package/src/templates/db-go-elasticsearch/files/db-README.md +57 -0
- package/src/templates/db-go-elasticsearch/files/go.mod +7 -0
- package/src/templates/db-go-elasticsearch/files/index-template-init.json +25 -0
- package/src/templates/db-go-elasticsearch/fragment.yaml +22 -0
- package/src/templates/db-go-migrate-mysql/files/000001_init.down.sql +3 -0
- package/src/templates/db-go-migrate-mysql/files/000001_init.up.sql +35 -0
- package/src/templates/db-go-migrate-mysql/files/Makefile +33 -0
- package/src/templates/db-go-migrate-mysql/files/db-README.md +77 -0
- package/src/templates/db-go-migrate-mysql/files/go.mod +8 -0
- package/src/templates/db-go-migrate-mysql/fragment.yaml +22 -0
- package/src/templates/db-go-migrate-postgres/files/000001_init.down.sql +3 -0
- package/src/templates/db-go-migrate-postgres/files/000001_init.up.sql +32 -0
- package/src/templates/db-go-migrate-postgres/files/Makefile +31 -0
- package/src/templates/db-go-migrate-postgres/files/db-README.md +71 -0
- package/src/templates/db-go-migrate-postgres/files/go.mod +8 -0
- package/src/templates/db-go-migrate-postgres/fragment.yaml +22 -0
- package/src/templates/db-java-elasticsearch/files/EsTemplateApplier.java +86 -0
- package/src/templates/db-java-elasticsearch/files/db-README.md +63 -0
- package/src/templates/db-java-elasticsearch/files/index-template-init.json +25 -0
- package/src/templates/db-java-elasticsearch/files/pom.xml +134 -0
- package/src/templates/db-java-elasticsearch/fragment.yaml +19 -0
- package/src/templates/db-java-flyway-mysql/files/V1__init.sql +44 -0
- package/src/templates/db-java-flyway-mysql/files/application.yaml +39 -0
- package/src/templates/db-java-flyway-mysql/files/db-README.md +102 -0
- package/src/templates/db-java-flyway-mysql/files/pom.xml +172 -0
- package/src/templates/db-java-flyway-mysql/fragment.yaml +19 -0
- package/src/templates/db-java-flyway-postgres/files/V1__init.sql +40 -0
- package/src/templates/db-java-flyway-postgres/files/application.yaml +37 -0
- package/src/templates/db-java-flyway-postgres/files/db-README.md +75 -0
- package/src/templates/db-java-flyway-postgres/files/pom.xml +166 -0
- package/src/templates/db-java-flyway-postgres/fragment.yaml +19 -0
- package/src/templates/db-node-elasticsearch/files/apply-templates.cjs +60 -0
- package/src/templates/db-node-elasticsearch/files/db-README.md +76 -0
- package/src/templates/db-node-elasticsearch/files/index-template-init.json +26 -0
- package/src/templates/db-node-elasticsearch/files/package.json +26 -0
- package/src/templates/db-node-elasticsearch/fragment.yaml +19 -0
- package/src/templates/db-node-knex-mysql/files/db-README.md +90 -0
- package/src/templates/db-node-knex-mysql/files/knexfile.cjs +72 -0
- package/src/templates/db-node-knex-mysql/files/migrations-init.cjs +42 -0
- package/src/templates/db-node-knex-mysql/files/package.json +31 -0
- package/src/templates/db-node-knex-mysql/files/seeds-dev-fixtures.cjs +38 -0
- package/src/templates/db-node-knex-mysql/files/seeds-prod-dictionaries.cjs +25 -0
- package/src/templates/db-node-knex-mysql/fragment.yaml +25 -0
- package/src/templates/db-node-knex-postgres/files/db-README.md +81 -0
- package/src/templates/db-node-knex-postgres/files/knexfile.cjs +67 -0
- package/src/templates/db-node-knex-postgres/files/migrations-init.cjs +42 -0
- package/src/templates/db-node-knex-postgres/files/package.json +31 -0
- package/src/templates/db-node-knex-postgres/files/seeds-dev-fixtures.cjs +36 -0
- package/src/templates/db-node-knex-postgres/files/seeds-prod-dictionaries.cjs +26 -0
- package/src/templates/db-node-knex-postgres/fragment.yaml +25 -0
- package/src/templates/db-python-alembic-mysql/files/0001_init.py +70 -0
- package/src/templates/db-python-alembic-mysql/files/alembic.ini +47 -0
- package/src/templates/db-python-alembic-mysql/files/db-README.md +87 -0
- package/src/templates/db-python-alembic-mysql/files/env.py +71 -0
- package/src/templates/db-python-alembic-mysql/files/pyproject.toml +52 -0
- package/src/templates/db-python-alembic-mysql/files/script.py.mako +26 -0
- package/src/templates/db-python-alembic-mysql/fragment.yaml +25 -0
- package/src/templates/db-python-alembic-postgres/files/0001_init.py +62 -0
- package/src/templates/db-python-alembic-postgres/files/alembic.ini +45 -0
- package/src/templates/db-python-alembic-postgres/files/db-README.md +70 -0
- package/src/templates/db-python-alembic-postgres/files/env.py +62 -0
- package/src/templates/db-python-alembic-postgres/files/pyproject.toml +52 -0
- package/src/templates/db-python-alembic-postgres/files/script.py.mako +25 -0
- package/src/templates/db-python-alembic-postgres/fragment.yaml +25 -0
- package/src/templates/db-python-elasticsearch/files/apply_templates.py +55 -0
- package/src/templates/db-python-elasticsearch/files/db-README.md +57 -0
- package/src/templates/db-python-elasticsearch/files/index-template-init.json +25 -0
- package/src/templates/db-python-elasticsearch/files/pyproject.toml +50 -0
- package/src/templates/db-python-elasticsearch/fragment.yaml +19 -0
- package/src/templates/docs-skeleton/files/governance-change-tiers.md +135 -0
- package/src/templates/docs-skeleton/files/governance-database.md +150 -0
- package/src/templates/docs-skeleton/fragment.yaml +6 -0
- package/src/templates/root-files/files/AGENTS.md +42 -7
- package/src/templates/server-node/files/_eslintrc.cjs +5 -1
- package/src/templates/server-python/files/README.md +75 -2
- package/src/templates/server-python/files/app-init.py +11 -1
- package/src/templates/server-python/files/config.py +40 -0
- package/src/templates/server-python/files/main.py +62 -0
- package/src/templates/server-python/files/pyproject.toml +14 -1
- package/src/templates/server-python/files/test_healthz.py +36 -0
- package/src/templates/server-python/fragment.yaml +10 -1
- package/src/templates/web-react/files/_eslintrc.cjs +5 -1
- package/src/templates/web-vue/files/_eslintrc.cjs +5 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
spring:
|
|
2
|
+
application:
|
|
3
|
+
name: <%= it.options.projectName %>-server
|
|
4
|
+
datasource:
|
|
5
|
+
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3306/<%= it.options.projectName %>?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useUnicode=true}
|
|
6
|
+
username: ${SPRING_DATASOURCE_USERNAME:root}
|
|
7
|
+
password: ${SPRING_DATASOURCE_PASSWORD:}
|
|
8
|
+
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
9
|
+
jpa:
|
|
10
|
+
# Flyway 接管 schema 演化,关掉 Hibernate 的 ddl-auto 避免双向漂移
|
|
11
|
+
hibernate:
|
|
12
|
+
ddl-auto: validate
|
|
13
|
+
properties:
|
|
14
|
+
hibernate:
|
|
15
|
+
dialect: org.hibernate.dialect.MySQLDialect
|
|
16
|
+
format_sql: true
|
|
17
|
+
show-sql: false
|
|
18
|
+
open-in-view: false
|
|
19
|
+
flyway:
|
|
20
|
+
enabled: true
|
|
21
|
+
locations: classpath:db/migration
|
|
22
|
+
baseline-on-migrate: false
|
|
23
|
+
validate-on-migrate: true
|
|
24
|
+
# 修改既有迁移文件 = 破坏性变更;CI 里 out-of-order=false 会拦截
|
|
25
|
+
out-of-order: false
|
|
26
|
+
|
|
27
|
+
server:
|
|
28
|
+
port: 8080
|
|
29
|
+
|
|
30
|
+
management:
|
|
31
|
+
endpoints:
|
|
32
|
+
web:
|
|
33
|
+
exposure:
|
|
34
|
+
include: health,info,flyway
|
|
35
|
+
|
|
36
|
+
app:
|
|
37
|
+
jwt:
|
|
38
|
+
secret: ${JWT_SECRET:change-me-please-this-is-a-development-secret-only-min-32-chars}
|
|
39
|
+
expiration-minutes: 120
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# server/db/
|
|
2
|
+
|
|
3
|
+
Spring Boot + Flyway 项目的数据库入口。
|
|
4
|
+
|
|
5
|
+
> 跨项目的数据库归属规则(哪类 SQL 放哪个目录、与 `contracts/` 如何对齐)见 [`docs/governance/database.md`](../../docs/governance/database.md)。本文件只解释**本项目的工具与命令**。
|
|
6
|
+
|
|
7
|
+
## 工具与版本
|
|
8
|
+
|
|
9
|
+
| 项 | 值 |
|
|
10
|
+
|---|---|
|
|
11
|
+
| 数据库 | MySQL 8 / MariaDB 10.6+ |
|
|
12
|
+
| 迁移工具 | [Flyway](https://flywaydb.org) `10.20.0` |
|
|
13
|
+
| 驱动 | `mysql-connector-j` `9.1.0` |
|
|
14
|
+
|
|
15
|
+
工具版本在 `pom.xml` 钉死,并镜像到 `docs/03-工程规范与研发基础设施/tech-stack-server.md`。governance-lint 检测两边漂移并阻断 PR;升级时同 PR 改两个文件。
|
|
16
|
+
|
|
17
|
+
## 路径分歧(重要)
|
|
18
|
+
|
|
19
|
+
Spring Boot + Flyway 的迁移文件**不在** `server/db/migrations/`,而在 Spring Boot 的默认扫描路径:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
server/
|
|
23
|
+
├── src/main/resources/
|
|
24
|
+
│ └── db/migration/ # ← Flyway 扫描这里
|
|
25
|
+
│ ├── V1__init.sql
|
|
26
|
+
│ └── V2__add_orders.sql
|
|
27
|
+
└── db/
|
|
28
|
+
├── README.md # 本文件(保留作为 keel 框架的入口)
|
|
29
|
+
└── seeds/
|
|
30
|
+
└── dev/ # 仅本地 / 测试用,与 Flyway 无关
|
|
31
|
+
└── 0001_dev_users.sql
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
之所以接受这个分歧而不强行统一到 `server/db/migrations/`:Spring Boot 在启动时自动扫描 `classpath:db/migration`,逆这个默认会让用户每次都改 `application.yaml`。`server/db/` 仍是 keel 约定的入口(README + seeds),与其他后端语言保持视觉一致。
|
|
35
|
+
|
|
36
|
+
## 目录布局
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
server/src/main/resources/
|
|
40
|
+
├── application.yaml # spring.flyway.* 配置
|
|
41
|
+
└── db/migration/ # Flyway 迁移文件
|
|
42
|
+
└── V<N>__<description>.sql
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 文件命名规则
|
|
46
|
+
|
|
47
|
+
- 版本化迁移:`V<N>__<description>.sql`
|
|
48
|
+
- `N` 单调递增整数,不允许跳号
|
|
49
|
+
- 已合入 `main` 的文件**绝对不能修改** —— 改 schema 写 `V<N+1>__*.sql`
|
|
50
|
+
- 可重复迁移:`R__<description>.sql`(每次 schema hash 变化时重跑)
|
|
51
|
+
- 用于视图、存储过程、字典数据 upsert
|
|
52
|
+
- 撤销迁移:Flyway Community 不支持 `down`;回滚靠新写一条 `V<N+1>__revert_*.sql`
|
|
53
|
+
|
|
54
|
+
## 常用命令
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Spring Boot 启动时自动应用所有 pending 迁移(默认行为)
|
|
58
|
+
mvn spring-boot:run
|
|
59
|
+
|
|
60
|
+
# 不启动应用,单独跑迁移
|
|
61
|
+
mvn flyway:migrate
|
|
62
|
+
|
|
63
|
+
# 查看当前迁移状态
|
|
64
|
+
mvn flyway:info
|
|
65
|
+
|
|
66
|
+
# 检查迁移文件 vs DB 历史是否一致(CI 用)
|
|
67
|
+
mvn flyway:validate
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
环境变量:`SPRING_DATASOURCE_URL` / `SPRING_DATASOURCE_USERNAME` / `SPRING_DATASOURCE_PASSWORD`。
|
|
71
|
+
|
|
72
|
+
## prod vs dev seeds
|
|
73
|
+
|
|
74
|
+
Flyway 把"种子数据"分成两类:
|
|
75
|
+
|
|
76
|
+
| 类型 | 位置 | 命名 |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| 生产字典(必装) | `src/main/resources/db/migration/` | `V<N>__seed_<topic>.sql`(首次)或 `R__<topic>.sql`(每次重跑) |
|
|
79
|
+
| 开发样例 | `server/db/seeds/dev/`(不在 Flyway 路径下) | 任意;用 `mysql -e 'source ...'` 手动加载 |
|
|
80
|
+
|
|
81
|
+
字典类生产种子的真值在 `contracts/dictionaries/enums.yaml`。改字典的 PR 必须**同步**更新对应 SQL;当前是手动同步(自动派生留给 `contract-derived-seeds` 特性)。
|
|
82
|
+
|
|
83
|
+
## 改动分级(参见 `docs/governance/change-tiers.md`)
|
|
84
|
+
|
|
85
|
+
| 改动 | Tier |
|
|
86
|
+
|---|---|
|
|
87
|
+
| 新增 `V<N>__*.sql` 加表 / 加字段 | 3(contract 一致性 + CHANGELOG) |
|
|
88
|
+
| 修改既有 `V<N>__*.sql` | **绝不允许**;写新文件 |
|
|
89
|
+
| 删字段 / 改类型(破坏性) | 4(ADR + 迁移预案) |
|
|
90
|
+
| 改 dev seed | 1/2 |
|
|
91
|
+
| 改字典 `R__*.sql` 或 prod 种子 | 3(同步 contracts/dictionaries/) |
|
|
92
|
+
| 升级 Flyway / mysql-connector-j | 2,但同步改 tech-stack-server.md |
|
|
93
|
+
|
|
94
|
+
## CI 行为
|
|
95
|
+
|
|
96
|
+
每个 PR 的 backend job 跑:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
mvn -B verify # 含 mvn flyway:migrate(启动应用时)+ mvn flyway:validate
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`spring.flyway.validate-on-migrate=true` 强制每次启动时校验"代码里的迁移文件历史"与"DB 中已应用的版本"完全一致;任何已合入 `main` 的迁移被改动都会让 CI 红。
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
|
5
|
+
https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
6
|
+
<modelVersion>4.0.0</modelVersion>
|
|
7
|
+
|
|
8
|
+
<parent>
|
|
9
|
+
<groupId>org.springframework.boot</groupId>
|
|
10
|
+
<artifactId>spring-boot-starter-parent</artifactId>
|
|
11
|
+
<version>3.3.4</version>
|
|
12
|
+
<relativePath/>
|
|
13
|
+
</parent>
|
|
14
|
+
|
|
15
|
+
<groupId>com.example</groupId>
|
|
16
|
+
<artifactId><%= it.options.projectName %>-server</artifactId>
|
|
17
|
+
<version>0.1.0</version>
|
|
18
|
+
<packaging>jar</packaging>
|
|
19
|
+
<name><%= it.options.projectName %>-server</name>
|
|
20
|
+
|
|
21
|
+
<properties>
|
|
22
|
+
<java.version>21</java.version>
|
|
23
|
+
<maven.compiler.source>21</maven.compiler.source>
|
|
24
|
+
<maven.compiler.target>21</maven.compiler.target>
|
|
25
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
26
|
+
<jjwt.version>0.12.6</jjwt.version>
|
|
27
|
+
<flyway.version>10.20.0</flyway.version>
|
|
28
|
+
</properties>
|
|
29
|
+
|
|
30
|
+
<dependencies>
|
|
31
|
+
<dependency>
|
|
32
|
+
<groupId>org.springframework.boot</groupId>
|
|
33
|
+
<artifactId>spring-boot-starter-web</artifactId>
|
|
34
|
+
</dependency>
|
|
35
|
+
<dependency>
|
|
36
|
+
<groupId>org.springframework.boot</groupId>
|
|
37
|
+
<artifactId>spring-boot-starter-validation</artifactId>
|
|
38
|
+
</dependency>
|
|
39
|
+
<dependency>
|
|
40
|
+
<groupId>org.springframework.boot</groupId>
|
|
41
|
+
<artifactId>spring-boot-starter-actuator</artifactId>
|
|
42
|
+
</dependency>
|
|
43
|
+
<dependency>
|
|
44
|
+
<groupId>org.springframework.boot</groupId>
|
|
45
|
+
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
|
46
|
+
</dependency>
|
|
47
|
+
<dependency>
|
|
48
|
+
<groupId>org.springframework.boot</groupId>
|
|
49
|
+
<artifactId>spring-boot-starter-security</artifactId>
|
|
50
|
+
</dependency>
|
|
51
|
+
|
|
52
|
+
<!--
|
|
53
|
+
Flyway: 数据库迁移工具。
|
|
54
|
+
Spring Boot 启动时自动扫描 src/main/resources/db/migration/V*__*.sql
|
|
55
|
+
并按版本号顺序应用(一次性);也可通过 `mvn flyway:migrate` 手动执行。
|
|
56
|
+
版本号一旦合入 main 不允许修改;改 schema 写新文件 V<N+1>__*.sql。
|
|
57
|
+
-->
|
|
58
|
+
<dependency>
|
|
59
|
+
<groupId>org.flywaydb</groupId>
|
|
60
|
+
<artifactId>flyway-core</artifactId>
|
|
61
|
+
<version>${flyway.version}</version>
|
|
62
|
+
</dependency>
|
|
63
|
+
<dependency>
|
|
64
|
+
<groupId>org.flywaydb</groupId>
|
|
65
|
+
<artifactId>flyway-mysql</artifactId>
|
|
66
|
+
<version>${flyway.version}</version>
|
|
67
|
+
</dependency>
|
|
68
|
+
|
|
69
|
+
<dependency>
|
|
70
|
+
<groupId>com.mysql</groupId>
|
|
71
|
+
<artifactId>mysql-connector-j</artifactId>
|
|
72
|
+
<version>9.1.0</version>
|
|
73
|
+
<scope>runtime</scope>
|
|
74
|
+
</dependency>
|
|
75
|
+
|
|
76
|
+
<dependency>
|
|
77
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
78
|
+
<artifactId>jjwt-api</artifactId>
|
|
79
|
+
<version>${jjwt.version}</version>
|
|
80
|
+
</dependency>
|
|
81
|
+
<dependency>
|
|
82
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
83
|
+
<artifactId>jjwt-impl</artifactId>
|
|
84
|
+
<version>${jjwt.version}</version>
|
|
85
|
+
<scope>runtime</scope>
|
|
86
|
+
</dependency>
|
|
87
|
+
<dependency>
|
|
88
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
89
|
+
<artifactId>jjwt-jackson</artifactId>
|
|
90
|
+
<version>${jjwt.version}</version>
|
|
91
|
+
<scope>runtime</scope>
|
|
92
|
+
</dependency>
|
|
93
|
+
<dependency>
|
|
94
|
+
<groupId>org.springframework.boot</groupId>
|
|
95
|
+
<artifactId>spring-boot-starter-test</artifactId>
|
|
96
|
+
<scope>test</scope>
|
|
97
|
+
</dependency>
|
|
98
|
+
<dependency>
|
|
99
|
+
<groupId>org.springframework.security</groupId>
|
|
100
|
+
<artifactId>spring-security-test</artifactId>
|
|
101
|
+
<scope>test</scope>
|
|
102
|
+
</dependency>
|
|
103
|
+
<dependency>
|
|
104
|
+
<groupId>com.h2database</groupId>
|
|
105
|
+
<artifactId>h2</artifactId>
|
|
106
|
+
<scope>test</scope>
|
|
107
|
+
</dependency>
|
|
108
|
+
</dependencies>
|
|
109
|
+
|
|
110
|
+
<build>
|
|
111
|
+
<plugins>
|
|
112
|
+
<plugin>
|
|
113
|
+
<groupId>org.springframework.boot</groupId>
|
|
114
|
+
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
115
|
+
</plugin>
|
|
116
|
+
|
|
117
|
+
<plugin>
|
|
118
|
+
<groupId>org.flywaydb</groupId>
|
|
119
|
+
<artifactId>flyway-maven-plugin</artifactId>
|
|
120
|
+
<version>${flyway.version}</version>
|
|
121
|
+
<configuration>
|
|
122
|
+
<url>${env.SPRING_DATASOURCE_URL}</url>
|
|
123
|
+
<user>${env.SPRING_DATASOURCE_USERNAME}</user>
|
|
124
|
+
<password>${env.SPRING_DATASOURCE_PASSWORD}</password>
|
|
125
|
+
</configuration>
|
|
126
|
+
</plugin>
|
|
127
|
+
|
|
128
|
+
<plugin>
|
|
129
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
130
|
+
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
131
|
+
<version>3.5.0</version>
|
|
132
|
+
<configuration>
|
|
133
|
+
<configLocation>checkstyle.xml</configLocation>
|
|
134
|
+
<consoleOutput>true</consoleOutput>
|
|
135
|
+
<failsOnError>true</failsOnError>
|
|
136
|
+
<linkXRef>false</linkXRef>
|
|
137
|
+
</configuration>
|
|
138
|
+
<executions>
|
|
139
|
+
<execution>
|
|
140
|
+
<id>verify-checkstyle</id>
|
|
141
|
+
<phase>verify</phase>
|
|
142
|
+
<goals><goal>check</goal></goals>
|
|
143
|
+
</execution>
|
|
144
|
+
</executions>
|
|
145
|
+
</plugin>
|
|
146
|
+
|
|
147
|
+
<plugin>
|
|
148
|
+
<groupId>com.diffplug.spotless</groupId>
|
|
149
|
+
<artifactId>spotless-maven-plugin</artifactId>
|
|
150
|
+
<version>2.43.0</version>
|
|
151
|
+
<configuration>
|
|
152
|
+
<java>
|
|
153
|
+
<googleJavaFormat>
|
|
154
|
+
<version>1.22.0</version>
|
|
155
|
+
<style>AOSP</style>
|
|
156
|
+
</googleJavaFormat>
|
|
157
|
+
<removeUnusedImports/>
|
|
158
|
+
<trimTrailingWhitespace/>
|
|
159
|
+
<endWithNewline/>
|
|
160
|
+
</java>
|
|
161
|
+
</configuration>
|
|
162
|
+
<executions>
|
|
163
|
+
<execution>
|
|
164
|
+
<id>verify-spotless</id>
|
|
165
|
+
<phase>verify</phase>
|
|
166
|
+
<goals><goal>check</goal></goals>
|
|
167
|
+
</execution>
|
|
168
|
+
</executions>
|
|
169
|
+
</plugin>
|
|
170
|
+
</plugins>
|
|
171
|
+
</build>
|
|
172
|
+
</project>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: db-java-flyway-mysql
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
appliesWhen:
|
|
4
|
+
backend: java
|
|
5
|
+
database: mysql
|
|
6
|
+
priority: 40
|
|
7
|
+
files:
|
|
8
|
+
- from: files/pom.xml
|
|
9
|
+
to: server/pom.xml
|
|
10
|
+
render: true
|
|
11
|
+
- from: files/application.yaml
|
|
12
|
+
to: server/src/main/resources/application.yaml
|
|
13
|
+
render: true
|
|
14
|
+
- from: files/V1__init.sql
|
|
15
|
+
to: server/src/main/resources/db/migration/V1__init.sql
|
|
16
|
+
render: false
|
|
17
|
+
- from: files/db-README.md
|
|
18
|
+
to: server/db/README.md
|
|
19
|
+
render: true
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- V1__init.sql — 初始化迁移
|
|
2
|
+
--
|
|
3
|
+
-- 命名规则:V<N>__<description>.sql。N 单调递增;不允许跳号。
|
|
4
|
+
-- 已合入 main 的迁移文件**不可修改**——改 schema 写 V<N+1>__*.sql。
|
|
5
|
+
-- 修改既有迁移属于破坏性变更,应升 Tier 4(参见 docs/governance/change-tiers.md)。
|
|
6
|
+
--
|
|
7
|
+
-- PostgreSQL 注意:
|
|
8
|
+
-- - 主键统一用 BIGINT GENERATED ALWAYS AS IDENTITY
|
|
9
|
+
-- - 文本默认用 TEXT,仅在确需限长时用 VARCHAR(n)
|
|
10
|
+
-- - 时间列用 TIMESTAMPTZ,统一存 UTC
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS roles (
|
|
13
|
+
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
14
|
+
code VARCHAR(64) NOT NULL UNIQUE,
|
|
15
|
+
name VARCHAR(128) NOT NULL,
|
|
16
|
+
description TEXT NULL,
|
|
17
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
18
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
22
|
+
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
23
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
24
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
25
|
+
display_name VARCHAR(128) NULL,
|
|
26
|
+
role_id BIGINT NOT NULL REFERENCES roles (id),
|
|
27
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
28
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
29
|
+
deleted_at TIMESTAMPTZ NULL
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_users_role_id ON users (role_id);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users (deleted_at);
|
|
34
|
+
|
|
35
|
+
-- 字典数据:与 contracts/dictionaries/enums.yaml 对齐。
|
|
36
|
+
-- ON CONFLICT DO NOTHING 保证多次跑幂等;改字典的 PR 必须同步改这里 + contracts/CHANGELOG.md。
|
|
37
|
+
INSERT INTO roles (code, name, description) VALUES
|
|
38
|
+
('admin', '系统管理员', '可执行所有管理操作'),
|
|
39
|
+
('user', '普通用户', '默认注册角色')
|
|
40
|
+
ON CONFLICT (code) DO NOTHING;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
spring:
|
|
2
|
+
application:
|
|
3
|
+
name: <%= it.options.projectName %>-server
|
|
4
|
+
datasource:
|
|
5
|
+
url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/<%= it.options.projectName %>}
|
|
6
|
+
username: ${SPRING_DATASOURCE_USERNAME:postgres}
|
|
7
|
+
password: ${SPRING_DATASOURCE_PASSWORD:}
|
|
8
|
+
driver-class-name: org.postgresql.Driver
|
|
9
|
+
jpa:
|
|
10
|
+
hibernate:
|
|
11
|
+
ddl-auto: validate
|
|
12
|
+
properties:
|
|
13
|
+
hibernate:
|
|
14
|
+
dialect: org.hibernate.dialect.PostgreSQLDialect
|
|
15
|
+
format_sql: true
|
|
16
|
+
show-sql: false
|
|
17
|
+
open-in-view: false
|
|
18
|
+
flyway:
|
|
19
|
+
enabled: true
|
|
20
|
+
locations: classpath:db/migration
|
|
21
|
+
baseline-on-migrate: false
|
|
22
|
+
validate-on-migrate: true
|
|
23
|
+
out-of-order: false
|
|
24
|
+
|
|
25
|
+
server:
|
|
26
|
+
port: 8080
|
|
27
|
+
|
|
28
|
+
management:
|
|
29
|
+
endpoints:
|
|
30
|
+
web:
|
|
31
|
+
exposure:
|
|
32
|
+
include: health,info,flyway
|
|
33
|
+
|
|
34
|
+
app:
|
|
35
|
+
jwt:
|
|
36
|
+
secret: ${JWT_SECRET:change-me-please-this-is-a-development-secret-only-min-32-chars}
|
|
37
|
+
expiration-minutes: 120
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# server/db/
|
|
2
|
+
|
|
3
|
+
Spring Boot + Flyway 项目的数据库入口。
|
|
4
|
+
|
|
5
|
+
> 跨项目的数据库归属规则(哪类 SQL 放哪个目录、与 `contracts/` 如何对齐)见 [`docs/governance/database.md`](../../docs/governance/database.md)。本文件只解释**本项目的工具与命令**。
|
|
6
|
+
|
|
7
|
+
## 工具与版本
|
|
8
|
+
|
|
9
|
+
| 项 | 值 |
|
|
10
|
+
|---|---|
|
|
11
|
+
| 数据库 | PostgreSQL 14+ |
|
|
12
|
+
| 迁移工具 | [Flyway](https://flywaydb.org) `10.20.0` |
|
|
13
|
+
| 驱动 | `postgresql` (JDBC) `42.7.4` |
|
|
14
|
+
|
|
15
|
+
工具版本在 `pom.xml` 钉死,并镜像到 `docs/03-工程规范与研发基础设施/tech-stack-server.md`。governance-lint 检测两边漂移并阻断 PR;升级时同 PR 改两个文件。
|
|
16
|
+
|
|
17
|
+
## 路径分歧(重要)
|
|
18
|
+
|
|
19
|
+
Spring Boot + Flyway 的迁移文件**不在** `server/db/migrations/`,而在 Spring Boot 的默认扫描路径:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
server/
|
|
23
|
+
├── src/main/resources/
|
|
24
|
+
│ └── db/migration/ # ← Flyway 扫描这里
|
|
25
|
+
│ ├── V1__init.sql
|
|
26
|
+
│ └── V2__add_orders.sql
|
|
27
|
+
└── db/
|
|
28
|
+
├── README.md # 本文件(保留作为 keel 框架的入口)
|
|
29
|
+
└── seeds/
|
|
30
|
+
└── dev/ # 仅本地 / 测试用
|
|
31
|
+
└── 0001_dev_users.sql
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
之所以接受这个分歧而不强行统一到 `server/db/migrations/`:Spring Boot 在启动时自动扫描 `classpath:db/migration`,逆这个默认会让用户每次都改 `application.yaml`。
|
|
35
|
+
|
|
36
|
+
## 文件命名规则
|
|
37
|
+
|
|
38
|
+
- 版本化迁移:`V<N>__<description>.sql`(N 单调递增,不跳号;已合入 `main` 不可修改)
|
|
39
|
+
- 可重复迁移:`R__<description>.sql`(每次 schema hash 变化时重跑,用于视图、字典 upsert)
|
|
40
|
+
- 撤销迁移:Flyway Community 不支持 `down`;回滚靠新写一条 `V<N+1>__revert_*.sql`
|
|
41
|
+
|
|
42
|
+
## 常用命令
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mvn spring-boot:run # 启动应用,自动跑 pending 迁移
|
|
46
|
+
mvn flyway:migrate # 仅跑迁移
|
|
47
|
+
mvn flyway:info # 查看当前状态
|
|
48
|
+
mvn flyway:validate # 校验代码 vs DB 历史一致(CI 用)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
环境变量:`SPRING_DATASOURCE_URL` / `SPRING_DATASOURCE_USERNAME` / `SPRING_DATASOURCE_PASSWORD`。
|
|
52
|
+
|
|
53
|
+
## prod vs dev seeds
|
|
54
|
+
|
|
55
|
+
| 类型 | 位置 | 命名 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| 生产字典(必装) | `src/main/resources/db/migration/` | `V<N>__seed_<topic>.sql` 或 `R__<topic>.sql` |
|
|
58
|
+
| 开发样例 | `server/db/seeds/dev/` | 任意;用 `psql -f <file>` 手动加载 |
|
|
59
|
+
|
|
60
|
+
字典类生产种子的真值在 `contracts/dictionaries/enums.yaml`。改字典的 PR 必须**同步**更新对应 SQL;当前是手动同步。
|
|
61
|
+
|
|
62
|
+
## 改动分级(参见 `docs/governance/change-tiers.md`)
|
|
63
|
+
|
|
64
|
+
| 改动 | Tier |
|
|
65
|
+
|---|---|
|
|
66
|
+
| 新增 `V<N>__*.sql` 加表 / 加字段 | 3(contract 一致性 + CHANGELOG) |
|
|
67
|
+
| 修改既有 `V<N>__*.sql` | **绝不允许**;写新文件 |
|
|
68
|
+
| 删字段 / 改类型(破坏性) | 4(ADR + 迁移预案) |
|
|
69
|
+
| 改 dev seed | 1/2 |
|
|
70
|
+
| 改字典 `R__*.sql` 或 prod 种子 | 3(同步 contracts/dictionaries/) |
|
|
71
|
+
| 升级 Flyway / postgresql 驱动 | 2,但同步改 tech-stack-server.md |
|
|
72
|
+
|
|
73
|
+
## CI 行为
|
|
74
|
+
|
|
75
|
+
每个 PR 的 backend job 跑 `mvn -B verify`,含 `flyway:migrate` + `flyway:validate`;任何已合入 `main` 的迁移被改动都会让 CI 红。
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
|
5
|
+
https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
6
|
+
<modelVersion>4.0.0</modelVersion>
|
|
7
|
+
|
|
8
|
+
<parent>
|
|
9
|
+
<groupId>org.springframework.boot</groupId>
|
|
10
|
+
<artifactId>spring-boot-starter-parent</artifactId>
|
|
11
|
+
<version>3.3.4</version>
|
|
12
|
+
<relativePath/>
|
|
13
|
+
</parent>
|
|
14
|
+
|
|
15
|
+
<groupId>com.example</groupId>
|
|
16
|
+
<artifactId><%= it.options.projectName %>-server</artifactId>
|
|
17
|
+
<version>0.1.0</version>
|
|
18
|
+
<packaging>jar</packaging>
|
|
19
|
+
<name><%= it.options.projectName %>-server</name>
|
|
20
|
+
|
|
21
|
+
<properties>
|
|
22
|
+
<java.version>21</java.version>
|
|
23
|
+
<maven.compiler.source>21</maven.compiler.source>
|
|
24
|
+
<maven.compiler.target>21</maven.compiler.target>
|
|
25
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
26
|
+
<jjwt.version>0.12.6</jjwt.version>
|
|
27
|
+
<flyway.version>10.20.0</flyway.version>
|
|
28
|
+
</properties>
|
|
29
|
+
|
|
30
|
+
<dependencies>
|
|
31
|
+
<dependency>
|
|
32
|
+
<groupId>org.springframework.boot</groupId>
|
|
33
|
+
<artifactId>spring-boot-starter-web</artifactId>
|
|
34
|
+
</dependency>
|
|
35
|
+
<dependency>
|
|
36
|
+
<groupId>org.springframework.boot</groupId>
|
|
37
|
+
<artifactId>spring-boot-starter-validation</artifactId>
|
|
38
|
+
</dependency>
|
|
39
|
+
<dependency>
|
|
40
|
+
<groupId>org.springframework.boot</groupId>
|
|
41
|
+
<artifactId>spring-boot-starter-actuator</artifactId>
|
|
42
|
+
</dependency>
|
|
43
|
+
<dependency>
|
|
44
|
+
<groupId>org.springframework.boot</groupId>
|
|
45
|
+
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
|
46
|
+
</dependency>
|
|
47
|
+
<dependency>
|
|
48
|
+
<groupId>org.springframework.boot</groupId>
|
|
49
|
+
<artifactId>spring-boot-starter-security</artifactId>
|
|
50
|
+
</dependency>
|
|
51
|
+
|
|
52
|
+
<dependency>
|
|
53
|
+
<groupId>org.flywaydb</groupId>
|
|
54
|
+
<artifactId>flyway-core</artifactId>
|
|
55
|
+
<version>${flyway.version}</version>
|
|
56
|
+
</dependency>
|
|
57
|
+
<dependency>
|
|
58
|
+
<groupId>org.flywaydb</groupId>
|
|
59
|
+
<artifactId>flyway-database-postgresql</artifactId>
|
|
60
|
+
<version>${flyway.version}</version>
|
|
61
|
+
</dependency>
|
|
62
|
+
|
|
63
|
+
<dependency>
|
|
64
|
+
<groupId>org.postgresql</groupId>
|
|
65
|
+
<artifactId>postgresql</artifactId>
|
|
66
|
+
<version>42.7.4</version>
|
|
67
|
+
<scope>runtime</scope>
|
|
68
|
+
</dependency>
|
|
69
|
+
|
|
70
|
+
<dependency>
|
|
71
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
72
|
+
<artifactId>jjwt-api</artifactId>
|
|
73
|
+
<version>${jjwt.version}</version>
|
|
74
|
+
</dependency>
|
|
75
|
+
<dependency>
|
|
76
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
77
|
+
<artifactId>jjwt-impl</artifactId>
|
|
78
|
+
<version>${jjwt.version}</version>
|
|
79
|
+
<scope>runtime</scope>
|
|
80
|
+
</dependency>
|
|
81
|
+
<dependency>
|
|
82
|
+
<groupId>io.jsonwebtoken</groupId>
|
|
83
|
+
<artifactId>jjwt-jackson</artifactId>
|
|
84
|
+
<version>${jjwt.version}</version>
|
|
85
|
+
<scope>runtime</scope>
|
|
86
|
+
</dependency>
|
|
87
|
+
<dependency>
|
|
88
|
+
<groupId>org.springframework.boot</groupId>
|
|
89
|
+
<artifactId>spring-boot-starter-test</artifactId>
|
|
90
|
+
<scope>test</scope>
|
|
91
|
+
</dependency>
|
|
92
|
+
<dependency>
|
|
93
|
+
<groupId>org.springframework.security</groupId>
|
|
94
|
+
<artifactId>spring-security-test</artifactId>
|
|
95
|
+
<scope>test</scope>
|
|
96
|
+
</dependency>
|
|
97
|
+
<dependency>
|
|
98
|
+
<groupId>com.h2database</groupId>
|
|
99
|
+
<artifactId>h2</artifactId>
|
|
100
|
+
<scope>test</scope>
|
|
101
|
+
</dependency>
|
|
102
|
+
</dependencies>
|
|
103
|
+
|
|
104
|
+
<build>
|
|
105
|
+
<plugins>
|
|
106
|
+
<plugin>
|
|
107
|
+
<groupId>org.springframework.boot</groupId>
|
|
108
|
+
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
109
|
+
</plugin>
|
|
110
|
+
|
|
111
|
+
<plugin>
|
|
112
|
+
<groupId>org.flywaydb</groupId>
|
|
113
|
+
<artifactId>flyway-maven-plugin</artifactId>
|
|
114
|
+
<version>${flyway.version}</version>
|
|
115
|
+
<configuration>
|
|
116
|
+
<url>${env.SPRING_DATASOURCE_URL}</url>
|
|
117
|
+
<user>${env.SPRING_DATASOURCE_USERNAME}</user>
|
|
118
|
+
<password>${env.SPRING_DATASOURCE_PASSWORD}</password>
|
|
119
|
+
</configuration>
|
|
120
|
+
</plugin>
|
|
121
|
+
|
|
122
|
+
<plugin>
|
|
123
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
124
|
+
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
125
|
+
<version>3.5.0</version>
|
|
126
|
+
<configuration>
|
|
127
|
+
<configLocation>checkstyle.xml</configLocation>
|
|
128
|
+
<consoleOutput>true</consoleOutput>
|
|
129
|
+
<failsOnError>true</failsOnError>
|
|
130
|
+
<linkXRef>false</linkXRef>
|
|
131
|
+
</configuration>
|
|
132
|
+
<executions>
|
|
133
|
+
<execution>
|
|
134
|
+
<id>verify-checkstyle</id>
|
|
135
|
+
<phase>verify</phase>
|
|
136
|
+
<goals><goal>check</goal></goals>
|
|
137
|
+
</execution>
|
|
138
|
+
</executions>
|
|
139
|
+
</plugin>
|
|
140
|
+
|
|
141
|
+
<plugin>
|
|
142
|
+
<groupId>com.diffplug.spotless</groupId>
|
|
143
|
+
<artifactId>spotless-maven-plugin</artifactId>
|
|
144
|
+
<version>2.43.0</version>
|
|
145
|
+
<configuration>
|
|
146
|
+
<java>
|
|
147
|
+
<googleJavaFormat>
|
|
148
|
+
<version>1.22.0</version>
|
|
149
|
+
<style>AOSP</style>
|
|
150
|
+
</googleJavaFormat>
|
|
151
|
+
<removeUnusedImports/>
|
|
152
|
+
<trimTrailingWhitespace/>
|
|
153
|
+
<endWithNewline/>
|
|
154
|
+
</java>
|
|
155
|
+
</configuration>
|
|
156
|
+
<executions>
|
|
157
|
+
<execution>
|
|
158
|
+
<id>verify-spotless</id>
|
|
159
|
+
<phase>verify</phase>
|
|
160
|
+
<goals><goal>check</goal></goals>
|
|
161
|
+
</execution>
|
|
162
|
+
</executions>
|
|
163
|
+
</plugin>
|
|
164
|
+
</plugins>
|
|
165
|
+
</build>
|
|
166
|
+
</project>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: db-java-flyway-postgres
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
appliesWhen:
|
|
4
|
+
backend: java
|
|
5
|
+
database: postgres
|
|
6
|
+
priority: 40
|
|
7
|
+
files:
|
|
8
|
+
- from: files/pom.xml
|
|
9
|
+
to: server/pom.xml
|
|
10
|
+
render: true
|
|
11
|
+
- from: files/application.yaml
|
|
12
|
+
to: server/src/main/resources/application.yaml
|
|
13
|
+
render: true
|
|
14
|
+
- from: files/V1__init.sql
|
|
15
|
+
to: server/src/main/resources/db/migration/V1__init.sql
|
|
16
|
+
render: false
|
|
17
|
+
- from: files/db-README.md
|
|
18
|
+
to: server/db/README.md
|
|
19
|
+
render: true
|