Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 76 additions & 67 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,101 +2,110 @@

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## 框架定位

Compose Server 是一个现代化、模块化的 Kotlin 企业级服务端开发**框架**,而非脚手架。它通过 Gradle 多模块方式,提供安全、数据库、缓存、对象存储、支付、AI 等企业级能力,支持按需集成到任意 Spring Boot 项目中。

## 构建和测试命令

这是一个基于 Gradle 的 Kotlin 多模块项目。

### 基本构建命令

- `./gradlew build` - 构建整个项目
- `./gradlew clean` - 清理构建输出
- `./gradlew publishToMavenLocal` - 发布到本地 Maven 仓库
- `./gradlew versionCatalogUpdate` - 更新版本目录中的依赖版本

### 测试命令

- `./gradlew test` - 运行所有测试
- `./gradlew :模块名:test` - 运行特定模块的测试
- `./gradlew :shared:test` - 运行共享模块测试
- `./gradlew :rds:shared:test` - 运行 RDS 共享模块测试

### 代码质量检查

- `./gradlew spotlessCheck` - 检查代码格式
- `./gradlew spotlessApply` - 自动修复代码格式

### 单个模块构建

- `./gradlew :模块名:build` - 构建特定模块
- `./gradlew :shared:build` - 构建共享模块

## 项目架构

### 模块化结构

项目采用多模块设计,主要模块包括:
本框架采用多模块设计,主要模块包括:

- **shared** - 共享基础组件,包含通用工具类、异常处理、类型定义等
- **shared** - 核心基础组件,包含通用工具类、异常处理、类型定义、统一响应、分页等
- **meta** - 元数据和注解处理器
- **rds** - 数据库相关模块
- `rds:shared` - 数据库共享组件
- `rds:crud` - CRUD 操作封装
- `rds:jimmer-ext-postgres` - Jimmer ORM PostgreSQL 扩展
- `rds:flyway-migration-postgresql` - Flyway 数据库迁移
- **security** - 安全相关模块
- `security:spring` - Spring Security 集成
- `security:oauth2` - OAuth2 认证
- `security:crypto` - 加密解密功能
- **oss** - 对象存储模块
- `oss:shared` - 对象存储共享组件
- `oss:minio` - MinIO 集成
- `oss:aliyun-oss` - 阿里云 OSS 集成
- `oss:huawei-obs` - 华为云 OBS 集成
- **pay** - 支付模块(微信支付等)
- **cacheable** - 缓存组件
- **data** - 数据处理模块
- `data:extract` - 数据提取(EasyExcel 等)
- `data:crawler` - 数据爬虫
- **depend** - 特定依赖处理模块
- **rds** - 数据库相关(Jimmer ORM、CRUD、PostgreSQL 扩展、Flyway 迁移)
- **surveillance** - 监控组件
- **security** - 安全相关(Spring Security、OAuth2、加密解密)
- **oss** - 对象存储(MinIO、阿里云 OSS、华为云 OBS)
- **pay** - 支付模块(微信支付 V3)
- **cacheable** - 多级缓存(Redis、Caffeine)
- **data** - 数据处理(EasyExcel、爬虫、行政区划等)
- **depend** - 特定依赖处理
- **testtoolkit** - 测试工具包
- **gradle-plugin** - Gradle 插件
- **ksp** - Kotlin Symbol Processing 相关
- **sms** - 短信发送模块
- **mcp** - AI 相关模块
- **ksp** - Kotlin Symbol Processing
- **sms** - 短信服务(腾讯云短信,短信抽象层)
- **mcp** - AI 能力(LangChain4j、Ollama、智谱 AI)

> 所有模块均可独立集成,推荐组合见下表。

### 推荐模块组合

| 使用场景 | 推荐模块组合 |
|----------------|----------------------------------------|
| 基础 Web API | shared + security-spring |
| 数据库操作 | shared + rds-shared + rds-crud |
| 文件存储 | shared + oss-shared + oss-minio |
| 微信支付 | shared + pay |
| 数据导入导出 | shared + data-extract |
| AI 能力 | shared + mcp |

## 技术栈

- **Kotlin** 2.2.x
- **Spring Boot** 3.5.x
- **Jimmer** 0.9.x
- **Gradle** 9.x
- **PostgreSQL**、**Redis**、**Caffeine**、**MinIO**、**阿里云 OSS**、**华为云 OBS** 等

## 依赖管理

- 统一使用 Gradle Version Catalog(`gradle/libs.versions.toml`)管理依赖版本
- 所有模块版本、groupId 通过根项目统一管理
- 推荐通过 `publishToMavenLocal` 集成本地开发版本


### 技术栈
## 代码约定

- **语言**: Kotlin (JVM)
- **框架**: Spring Boot 3.5.3
- **ORM**: Jimmer 0.9.97
- **构建工具**: Gradle 9.x
- **数据库**: PostgreSQL (主要)
- **缓存**: Redis, Caffeine
- **对象存储**: MinIO, 阿里云 OSS, 华为云 OBS
- 所有模块使用 `kotlinspring-convention` 插件,集成 Spring Boot 与 Kotlin 规范
- 包名格式:`io.github.truenine.composeserver.模块名`

### 依赖管理
- 代码格式化:使用 Spotless,提交前请运行 `./gradlew spotlessApply`
- 数据库迁移:使用 Flyway,脚本位于 `rds/flyway-migration-数据库类型/src/main/resources/db/migration/`,命名规则 `V版本号__描述.sql`

- 使用 Gradle Version Catalog (`gradle/libs.versions.toml`) 统一管理依赖版本
- 通过 build-logic 自定义 Gradle 插件和约定,使用 pluginManagement includeBuild 引入
- 所有模块版本通过 `project` 版本号统一管理
- 所有 groupId 通过 `group` 版本号统一管理
## 集成与最佳实践

### 代码约定
1. **依赖引入**
在业务项目的 `build.gradle.kts` 中按需添加依赖,例如:
```kotlin
implementation("io.github.truenine:composeserver-shared:latest")
implementation("io.github.truenine:composeserver-rds-shared:latest")
implementation("io.github.truenine:composeserver-security-spring:latest")
```
2. **自动配置**
启用自动配置注解(如有):
```kotlin
@SpringBootApplication
@EnableComposeServer
class YourApplication
```
3. **统一响应、异常、分页等**
推荐使用框架内置的统一响应、异常处理、分页等能力,详见 `shared` 模块。

- 所有模块使用 `kotlinspring-convention` 插件,集成 Spring Boot 和 Kotlin 配置
- 测试类命名为 `TestEntrance`
- 使用 Spotless 进行代码格式化
- 包名遵循 `io.github.truenine.composeserver.模块名` 格式
4. **测试与发布**
- 修改代码后先格式化,再运行测试,最后构建或发布到本地 Maven 仓库
- 推荐使用 `./gradlew test`、`./gradlew build`、`./gradlew publishToMavenLocal`

### 开发工作流
## 其他说明

1. 修改代码后运行 `./gradlew spotlessApply` 格式化代码
2. 运行 `./gradlew test` 确保测试通过
3. 运行 `./gradlew build` 构建项目
4. 使用 `./gradlew publishToMavenLocal` 发布到本地测试
- 本项目为**框架库**,不包含脚手架或项目初始化功能
- 所有模块均已发布至 Maven Central,详见 [README.md] 或 [Maven Central](https://central.sonatype.com/search?q=g:io.github.truenine)
- 详细 API、集成示例、变更日志等请参考 [README.md] 和官方文档

### 数据库迁移
---

- 使用 Flyway 进行数据库版本管理
- 迁移脚本位于 `rds/flyway-migration-postgresql/src/main/resources/db/migration/`
- 命名规则:`V版本号__描述.sql`
如需为本项目贡献代码或扩展模块,请遵循上述规范和最佳实践。
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ tasks.withType<Jar> {
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter(libs.versions.org.junit.junit5.get())
useJUnitJupiter(libs.versions.org.junit.jupiter.get())
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions docs/GLOBAL_CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Claude Code 专用 AI 规则(2025-07 版)

## 通用规范
- 所有回复必须使用简体中文。

## SQL 规范
- SQL 语句全部小写(关键字、标识符)。
- 命名风格统一使用下划线命名法(snake_case)。
- 严禁拼接 SQL 字符串,必须使用参数化查询,防止 SQL 注入。
- 表、字段、索引等命名需简洁明了,避免缩写。
- 禁止在代码中硬编码数据库连接信息,需使用配置文件或安全管理方式。
- 建议为重要业务表和字段添加注释,便于维护。

## 通用代码规范
- 文档注释必须由英文书写。
- 优先采用提前返回(early return),减少嵌套。
- 禁止行尾注释,注释需单独成行。
- 统一使用 2 空格缩进,仅用空格,不用 Tab。
- 禁止全量 import,必须显式导入所需内容。
- 编程语言优先选择编译型语言,避免动态语言,以便尽早发现错误。
- 应积极采用日志记录方式协助诊断问题,并合理控制日志级别,避免无效或过量日志输出。

## markdown 规范
- Markdown 文件需扁平、紧凑,严禁嵌套列表。
- 采用分级标题+扁平条目归类结构,避免多层嵌套,整体风格清晰、紧凑、分组明确。
- 内容应准确、简明,避免歧义和冗余。
- 结构应清晰,分组合理,便于查阅。
- 统一术语和表达风格,避免同义词混用。
- 注重可读性,适当分段,避免长段落堆砌。
- 人类以阅读为主,AI 需确保文档对人类友好、易于理解。

## 依赖与技术规范
- 仅推荐和采用最新技术,所有建议和代码实现前必须查阅最新官方文档,确保内容为 2025 年及以后主流方案。
- 禁止试图通过降级依赖版本来解决问题,遇到依赖或兼容性问题时,必须优先查阅最新技术文档或最佳实践,积极采用主流和前沿方案。
36 changes: 18 additions & 18 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ cn-dev33-sa-token-redis = "1.44.0"
cn-hutool = "5.8.39"
com-alibaba-cloud = "2023.0.3.3"
com-baomidou-mybatis-plus = "3.5.12"
com-diffplug-spotless = "7.0.4"
com-diffplug-spotless = "7.1.0"
com-fasterxml-jackson = "2.19.1"
com-flywaydb-flyway = "11.10.1"
com-flywaydb-flyway = "11.10.2"
com-github-tschuchortdev-kotlin-compile-testing = "1.6.0"
com-google-devtools-ksp = "2.2.0-2.0.2"
com-mapstruct = "1.6.3"
Expand All @@ -25,18 +25,18 @@ net-sf-sevenzipjbinding = "16.02-2.01"
nl-littlerobots-version-catalog-updat-gradle-plugin = "1.0.0"
org-apache-commons-exec = "1.5.0"
org-apache-logging-log4j = "2.24.3"
org-assertj = "3.27.2"
org-babyfish-jimmer = "0.9.97"
org-assertj = "4.0.0-M1"
org-babyfish-jimmer = "0.9.99"
org-gradle = "9.0.0-rc-2"
org-hibernate-orm = "6.6.15.Final"
org-jetbrains-dokka = "2.0.0"
org-jetbrains-kotlin = "2.2.0"
org-jetbrains-kotlinx-coroutines = "1.10.2"
org-jetbrains-kotlinx-datetime = "0.7.0-0.6.x-compat"
org-jetbrains-kotlinx-datetime = "0.7.1-0.6.x-compat"
org-jetbrains-kotlinx-io = "0.8.0"
org-jetbrains-kotlinx-serialization = "1.9.0"
org-junit-junit5 = "6.0.0-M1"
org-junit-platform = "1.13.1"
org-liquibase = "4.32.0"
org-junit-jupiter = "6.0.0-M1"
org-liquibase = "4.33.0"
org-slf4j = "2.1.0-alpha1"
org-springframework-ai = "1.0.0"
org-springframework-batch = "5.2.2"
Expand All @@ -49,7 +49,7 @@ org-springframework-modulith = "1.4.1"
org-springframework-security = "6.5.1"
org-testcontainers = "1.21.3"
org-testng = "7.11.0"
project = "0.0.4"
project = "0.0.5"

[libraries]
cn-dev33-sa-token-redis-jackson = { module = "cn.dev33:sa-token-redis-jackson", version.ref = "cn-dev33-sa-token" }
Expand Down Expand Up @@ -106,7 +106,7 @@ com-querydsl-querydsl-jpa = { module = "com.querydsl:querydsl-jpa", version.ref
com-squareup-javapoet = "com.squareup:javapoet:1.13.0"
com-squareup-kotlinpoet-jvm = { module = "com.squareup:kotlinpoet-jvm", version.ref = "com-squareup-kotlinpoet" }
com-squareup-kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "com-squareup-kotlinpoet" }
com-squareup-okhttp3-okhttp = "com.squareup.okhttp3:okhttp:5.0.0"
com-squareup-okhttp3-okhttp = "com.squareup.okhttp3:okhttp:5.1.0"
com-squareup-okio-okio = { module = "com.squareup.okio:okio", version.ref = "com-squareup-okio" }
com-squareup-okio-okio-jvm = { module = "com.squareup.okio:okio-jvm", version.ref = "com-squareup-okio" }
com-squareup-retrofit2-retrofit = "com.squareup.retrofit2:retrofit:3.0.0"
Expand All @@ -126,7 +126,7 @@ dev-langchain4j-langchain4j-pgvector = { module = "dev.langchain4j:langchain4j-p
dev-langchain4j-langchain4j-reactor = { module = "dev.langchain4j:langchain4j-reactor", version.ref = "dev-langchain4j" }
dev-langchain4j-langchain4j-spring-boot-starter = { module = "dev.langchain4j:langchain4j-spring-boot-starter", version.ref = "dev-langchain4j" }
dev-langchain4j-langchain4j-zhipu-ai = "dev.langchain4j:langchain4j-zhipu-ai:0.36.2"
io-github-bonigarcia-webdrivermanager = "io.github.bonigarcia:webdrivermanager:6.1.0"
io-github-bonigarcia-webdrivermanager = "io.github.bonigarcia:webdrivermanager:6.1.1"
io-github-truenine-composeserver-cacheable = { module = "io.github.truenine:composeserver-cacheable", version.ref = "project" }
io-github-truenine-composeserver-data-crawler = { module = "io.github.truenine:composeserver-data-crawler", version.ref = "project" }
io-github-truenine-composeserver-data-extract = { module = "io.github.truenine:composeserver-data-extract", version.ref = "project" }
Expand Down Expand Up @@ -161,7 +161,7 @@ io-jsonwebtoken-jjwt-api = "io.jsonwebtoken:jjwt-api:0.12.6"
io-minio-minio = "io.minio:minio:8.5.17"
io-mockk-mockk = "io.mockk:mockk:1.14.4"
io-netty-netty-handler = { module = "io.netty:netty-handler", version.ref = "io-netty" }
io-projectreactor-kotlin-reactor-kotlin-extensions = "io.projectreactor.kotlin:reactor-kotlin-extensions:1.2.3"
io-projectreactor-kotlin-reactor-kotlin-extensions = "io.projectreactor.kotlin:reactor-kotlin-extensions:1.3.0-RC1"
io-projectreactor-reactor-test = "io.projectreactor:reactor-test:3.8.0-M4"
io-spring-gradle-dependency-management-plugin = "io.spring.gradle:dependency-management-plugin:1.1.7"
io-swagger-core-v3-swagger-annotations-jakarta = "io.swagger.core.v3:swagger-annotations-jakarta:2.2.34"
Expand Down Expand Up @@ -232,12 +232,12 @@ org-jetbrains-kotlinx-kotlinx-io-core = { module = "org.jetbrains.kotlinx:kotlin
org-jetbrains-kotlinx-kotlinx-io-core-jvm = { module = "org.jetbrains.kotlinx:kotlinx-io-core-jvm", version.ref = "org-jetbrains-kotlinx-io" }
org-jetbrains-kotlinx-kotlinx-serialization-bom = { module = "org.jetbrains.kotlinx:kotlinx-serialization-bom", version.ref = "org-jetbrains-kotlinx-serialization" }
org-jetbrains-kotlinx-kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "org-jetbrains-kotlinx-serialization" }
org-jsoup-jsoup = "org.jsoup:jsoup:1.20.1"
org-junit-jupiter-junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "org-junit-junit5" }
org-junit-jupiter-junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "org-junit-junit5" }
org-junit-jupiter-junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "org-junit-junit5" }
org-junit-platform-junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "org-junit-platform" }
org-junit-vintage-junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "org-junit-junit5" }
org-jsoup-jsoup = "org.jsoup:jsoup:1.21.1"
org-junit-jupiter-junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "org-junit-jupiter" }
org-junit-jupiter-junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "org-junit-jupiter" }
org-junit-jupiter-junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "org-junit-jupiter" }
org-junit-platform-junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "org-junit-jupiter" }
org-junit-vintage-junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "org-junit-jupiter" }
org-lionsoul-ip2region = "org.lionsoul:ip2region:2.7.0"
org-liquibase-liquibase-core = { module = "org.liquibase:liquibase-core", version.ref = "org-liquibase" }
org-mapstruct-mapstruct = { module = "org.mapstruct:mapstruct", version.ref = "com-mapstruct" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-rc-1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-rc-2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
4 changes: 3 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ pluginManagement {
}
}

rootProject.name = "compose-server"
plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" }

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

rootProject.name = "compose-server"

fun Pair<String, List<String>>.useFile() {
second.forEach { n ->
include("$first:$n")
Expand Down