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
6 changes: 6 additions & 0 deletions .claude/skills/java-codegen-from-db/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ LLM **必须**把 schema 概述、命名推断和模板推荐呈现给用户,

如果目标文件已存在,生成 `*.codegen.bak` 备份,告诉用户怎么回滚(`mv x.bak x`)。

### 5.4 释放连接

工作流结束或用户决定中止时,调用 **`db_disconnect`** with
`{"connection_id": "<connection_id>"}`。释放后的 ID 不应继续用于查询或生成。

---

## 错误处理与重试规则
Expand Down Expand Up @@ -252,6 +257,7 @@ LLM **必须**把 schema 概述、命名推断和模板推荐呈现给用户,
codegen_render_dto (×1 per 表, 仅 sb35-java21)

[写盘] (内置于上述工具,Phase 3 后拆出 file_write_to_project)
[收尾] db_disconnect (会话结束时释放连接)
```

## 设计原则
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Repository metadata

on:
issues:
types: [opened, edited, reopened]

permissions:
contents: read

jobs:
issue-policy:
name: Issue title and body policy
runs-on: ubuntu-latest
steps:
- name: Checkout validation script
uses: actions/checkout@v4

- name: Validate Issue metadata
env:
ISSUE_EVENT: ${{ github.event_path }}
run: python scripts/validate_commit_title.py --issue-event "$ISSUE_EVENT"
6 changes: 5 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ PYTHONPATH=src uv run python scripts/verify_java_compile.py
:test_tube: test(generator): 覆盖可空枚举字段
```

正文依次写 `背景`、`变更`、`验证`、`实验`、`风险`。PR 标题和首个提交标题必须相同风格;PR 额外关联 Issue 并填写审查清单。
Bug Issue 依次写 `版本与环境`、`问题与预期行为`、`最小复现`、`验收标准`、`非目标、风险与安全`;
功能或架构 Issue 使用 `问题与用户价值`、`建议方案与替代方案`、`验收标准`、`架构、兼容性与测试计划`、
`非目标与风险`。PR 必须按模板中的七个固定章节填写,且每节有实际内容;实现完成和验证完成各发一条
包含结论、取舍、命令/结果、风险和下一步的回帖。Issue 编辑会触发轻量元数据检查,不能使用空章节、
连续 `??`、替代字符或字面量 `\\r\\n` 代替 Markdown 换行。
7 changes: 4 additions & 3 deletions README.es-ES.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ En el cliente LLM, di "**Genera código Spring Boot a partir de las tres tablas
5. Llamará a `ai_recommend_template` para recomendar → detectará RBAC y recomendará `MybatisPlus-Mixed`
6. Usará `codegen_build_context` + 5 `codegen_render_*` para generar por capas, devolviendo code-diff en cada capa
7. Tras la confirmación del usuario, escribirá en disco
8. Al finalizar la sesión, llamará a `db_disconnect(connection_id)` para liberar la conexión

## Capacidades principales (Fase 1 → 5)

Expand Down Expand Up @@ -126,11 +127,11 @@ En el cliente LLM, di "**Genera código Spring Boot a partir de las tres tablas
- Logs estructurados: `DBJAVAGENIX_LOG_FORMAT=json` permite salida de JSON en una sola línea, ideal para Loki/ELK
- [Manual de despliegue](docs/deployment.md): 3 modos de despliegue + 6 escenarios de troubleshooting

## Resumen de herramientas (33 en total)
## Resumen de herramientas (34 en total)

| Categoría | Herramienta |
|------|------|
| Conexión / Consulta | db_connect_test / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| Conexión / Consulta | db_connect_test / db_disconnect / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| Estructura de tabla | db_table_describe / db_table_columns / db_table_primary_keys / db_table_foreign_keys / db_table_indexes |
| Algoritmos de grafo de schema | schema_topo_order / schema_cluster_tables / schema_check_cycles |
| Generación de código (atómica) | codegen_build_context / codegen_render_entity / codegen_render_dao / codegen_render_service / codegen_render_controller / codegen_render_dto / codegen_render_mapper |
Expand Down Expand Up @@ -162,7 +163,7 @@ Consulta [`iteration-plan/01-target-architecture.md`](iteration-plan/01-target-a
```
[ Capa Skills ] Define "cómo hacerlo" — .claude/skills/*.md Flujo de 5 fases explícito
↓
[ Capa MCP ] Proporciona "qué se puede hacer" — 33 herramientas Contexto transferido explícitamente
[ Capa MCP ] Proporciona "qué se puede hacer" — 34 herramientas Contexto transferido explícitamente
↓
[ Capa Apps ] Hace los resultados "visibles" — 4 componentes de UI (mermaid/dashboard/code-diff/tree)
```
Expand Down
7 changes: 4 additions & 3 deletions README.ja-JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ LLM クライアントで、例えば **「myapp データベースの sys_user
5. `ai_recommend_template` でテンプレートを推薦し、RBAC を検出して `MybatisPlus-Mixed` を提案する
6. `codegen_build_context` + 5 つの `codegen_render_*` でレイヤーごとに生成し、各レイヤーの code-diff を返す
7. ユーザーの確認後にファイルへ書き込む
8. セッション終了時に `db_disconnect(connection_id)` を呼び出して接続を解放する

## 主な機能(Phase 1 → 5)

Expand Down Expand Up @@ -130,11 +131,11 @@ LLM クライアントで、例えば **「myapp データベースの sys_user
- 構造化ログ: `DBJAVAGENIX_LOG_FORMAT=json` で Loki / ELK に適した 1 行 JSON を出力
- [デプロイガイド](docs/deployment.md): 3 つのデプロイ方式 + 6 つのトラブルシューティング事例

## ツール一覧(33 個)
## ツール一覧(34 個)

| カテゴリ | ツール |
|------|------|
| 接続 / クエリ | db_connect_test / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| 接続 / クエリ | db_connect_test / db_disconnect / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| テーブル構造 | db_table_describe / db_table_columns / db_table_primary_keys / db_table_foreign_keys / db_table_indexes |
| スキーマグラフアルゴリズム | schema_topo_order / schema_cluster_tables / schema_check_cycles |
| コード生成(アトミック) | codegen_build_context / codegen_render_entity / codegen_render_dao / codegen_render_service / codegen_render_controller / codegen_render_dto / codegen_render_mapper |
Expand Down Expand Up @@ -166,7 +167,7 @@ LLM クライアントで、例えば **「myapp データベースの sys_user
```
[ Skills 層 ] 「方法」を定義 — .claude/skills/*.md 明示的な 5 段階ワークフロー
↓
[ MCP 層 ] 「できること」を提供 — 33 ツール context を明示的に受け渡し
[ MCP 層 ] 「できること」を提供 — 34 ツール context を明示的に受け渡し
↓
[ Apps 層 ] 結果を「見える化」 — 4 つの UI コンポーネント(mermaid/dashboard/code-diff/tree)
```
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ graph LR
Skills[".claude/skills/<br/>java-codegen-from-db<br/>springboot-migration"]
Skills -->|按需调用| MCP

subgraph MCP[MCP Server 33 工具]
subgraph MCP[MCP Server 34 工具]
direction TB
DB[db_* 连接 / 查询 / 描述]
Atom[codegen_build_context<br/>codegen_render_entity/dao/service/<br/>controller/dto/mapper]
Expand Down Expand Up @@ -90,6 +90,7 @@ SQL Server 的类型映射保留为后续扩展准备,但尚未实现运行时
5. 调用 `ai_recommend_template` 推荐 → 检测到 RBAC,推 `MybatisPlus-Mixed`
6. 用 `codegen_build_context` + 6 个 `codegen_render_*` 分层生成,每层返回 code-diff
7. 用户确认后写盘
8. 会话结束时调用 `db_disconnect(connection_id)` 释放连接

## 核心能力 (Phase 1 → 5)

Expand Down Expand Up @@ -130,11 +131,11 @@ SQL Server 的类型映射保留为后续扩展准备,但尚未实现运行时
- 结构化日志: `DBJAVAGENIX_LOG_FORMAT=json` 可输出单行 JSON,适合 Loki/ELK
- [部署手册](docs/deployment.md): 3 种部署模式 + 6 个排障场景

## 工具总览 (33 个)
## 工具总览 (34 个)

| 类别 | 工具 |
|------|------|
| 连接 / 查询 | db_connect_test / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| 连接 / 查询 | db_connect_test / db_disconnect / db_query_databases / db_query_tables / db_query_table_exists / db_query_execute |
| 表结构 | db_table_describe / db_table_columns / db_table_primary_keys / db_table_foreign_keys / db_table_indexes |
| Schema 图算法 | schema_topo_order / schema_cluster_tables / schema_check_cycles |
| 代码生成 (atomic) | codegen_build_context / codegen_render_entity / codegen_render_dao / codegen_render_service / codegen_render_controller / codegen_render_dto / codegen_render_mapper |
Expand Down Expand Up @@ -166,7 +167,7 @@ SQL Server 的类型映射保留为后续扩展准备,但尚未实现运行时
```
[ Skills 层 ] 定义"怎么做" — .claude/skills/*.md 显式 5 阶段工作流
↓
[ MCP 层 ] 提供"能做什么" — 33 个原子工具 context 显式传递
[ MCP 层 ] 提供"能做什么" — 34 个原子工具 context 显式传递
↓
[ Apps 层 ] 让结果"看得见" — 4 个 UI 组件 (mermaid/dashboard/code-diff/tree)
```
Expand All @@ -187,7 +188,7 @@ SQL Server 的类型映射保留为后续扩展准备,但尚未实现运行时
| [docs/screenshots/README.md](docs/screenshots/README.md) | MCP Apps 4 组件客户端兼容性 |
| [docs/algorithms-overview.md](docs/algorithms-overview.md) | v0.2.1 schema 图算法 (topo / cluster / cycle) |
| [docs/design-patterns-catalog.md](docs/design-patterns-catalog.md) | 生成器与生成代码中的设计模式 |
| [docs/adr/](docs/adr/) | 14 个 ADR (架构 / 原子 / 渐进 / 规则 / 不引依赖 / schema 算法 / 规范配置 / MCP v3 / 1h 缓存 / agentic / 多方言 / SDK 契约 / 工具契约 / 元数据契约) |
| [docs/adr/](docs/adr/) | 15 个 ADR (架构 / 原子 / 渐进 / 规则 / 不引依赖 / schema 算法 / 规范配置 / MCP v3 / 1h 缓存 / agentic / 多方言 / SDK 契约 / 工具契约 / 元数据契约 / 连接生命周期) |
| [.claude/skills/java-codegen-from-db/SKILL.md](.claude/skills/java-codegen-from-db/SKILL.md) | 主 Skill: 代码生成 5 阶段工作流 |
| [.claude/skills/springboot-migration/SKILL.md](.claude/skills/springboot-migration/SKILL.md) | 第二 Skill: Spring Boot 2.7→3.x 迁移 |

Expand Down
9 changes: 5 additions & 4 deletions docs/adr/011-multi-dialect-strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ postgresql:
- 36 个 unit test 覆盖 mysql/postgres 两套映射,跨方言隔离测试防串
- D3 用真实 PG container 验证 information_schema 上报的字符串确实命中
我们的 key (这是配置驱动方案做不到的)
- `template_context.py` 之后会渐进迁移到调用 `get_dialect(...).java_type_for()`,
本 ADR 不强制一次性切换
- `template_context.py`、MCP `db_table_describe` 已统一调用
`get_dialect(...).java_type_for()`;未注册运行时方言仍保留旧 YAML 回退,避免把
SQL Server/Oracle 的配置映射误报为连接能力

**坏**:
- `dialect.py` 文件略大 (~300 行,主要是两张映射表),但都是数据
- `template_context.py` 现在有重复的 MySQL 映射,**v0.3.1 计划重构** — 不在这个
ADR 范围内,先把 PG 跑起来,old code 保留向后兼容
- MCP 描述工具对已注册方言不再维护独立的 Java 类型表;Java 类型对应 imports
也由 `DialectAdapter.java_imports_for()` 统一提供

**实测**:
- D3 PG 16 实测 23 个 PG 类型全部命中预期 Java 类型
Expand Down
44 changes: 44 additions & 0 deletions docs/adr/015-connection-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ADR-015: MCP 连接生命周期与显式释放

- **状态**: Accepted
- **日期**: 2026-09-09
- **关联 Issue**: #209
- **关联实现**: `src/dbjavagenix/database/mcp_tools.py`

## 背景

`ConnectionManager` 已经能够按 connection ID 关闭连接,但公共 MCP 合同只
暴露 `db_connect_test`。长生命周期客户端无法在探索完成、重试失败或切换数据库
时主动释放连接,连接对象和脱敏配置会一直保留到 server 进程退出。

## 决定

新增 `db_disconnect(connection_id)` 作为显式连接生命周期工具:

1. handler 只负责校验参数、调用 `ConnectionManager.close_connection()` 和序列化
响应,不复制连接状态或驱动逻辑。
2. 成功关闭返回 `success=true`;未知、空值和重复关闭统一返回
`success=false`、`error=connection_not_found`。
3. 关闭异常返回 `disconnect_failed`,异常文本经过现有凭据脱敏边界后再返回。
4. 工具加入 canonical MCP 列表和 progressive discovery 元数据;默认 progressive
可见集合不变,客户端可通过 `search_tools("disconnect")` 发现它。
5. 客户端在会话结束时调用该工具;不引入连接池、TTL、后台回收或自动关闭策略。

## 备选方案

- 仅依赖进程退出时的 `__del__`:无法覆盖长会话中的提前释放和异常重试,已拒绝。
- 增加后台 TTL:可能误杀仍在使用的连接,并引入不可预测的时序,已拒绝。
- 在 handler 内直接操作驱动连接:会重复生命周期逻辑,绕过 `ConnectionManager`,已拒绝。

## 影响

- 连接建立和查询 API 保持兼容,旧客户端无需立即改造。
- 释放后的 connection ID 不可继续使用;后续查询收到既有的连接不存在错误。
- 显式释放降低长生命周期会话的资源占用,但不承诺性能收益或自动回收。

## 验证

- 单元测试覆盖工具 schema、成功关闭后的连接与配置清理、未知/空值/重复 ID、
异常脱敏以及 canonical server dispatch。
- 使用 SQLite in-memory manager 和 monkeypatch 验证,不伪造真实 MySQL/PostgreSQL
连接释放结果。
45 changes: 45 additions & 0 deletions docs/adr/016-async-database-boundary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ADR-016: 将同步数据库调用移出 MCP 事件循环

- **状态**: Accepted
- **日期**: 2026-09-09
- **关联 Issue**: #211
- **关联实现**: `src/dbjavagenix/database/connection_manager.py`

## 背景

MCP handler 使用 `async def`,但数据库驱动和元数据 introspector 仍是同步实现。
网络等待或大型 SQLite 查询会占住事件循环,使同一会话的健康检查、取消和其他连接请求
延迟。SQLite 默认还会拒绝跨线程使用连接;多个 worker 直接共享一个连接也可能交叉使用
cursor。

## 决定

1. 在 MCP 数据库边界统一使用 `asyncio.to_thread`;保留同步 `ConnectionManager` API,
供 CLI、测试和外部调用方继续使用。
2. `ConnectionManager` 为每个 connection ID 建立可重入锁,锁覆盖健康探测、cursor
生命周期、SQL 执行和关闭;不同连接不共享这把锁。
3. SQLite 连接启用 `check_same_thread=False`,但只有在上述连接锁保护下交给 worker。
4. 异步 analyzer 通过 worker 中的短生命周期 event loop 执行,输入输出合同保持不变。
5. 取消异步 handler 不强杀底层驱动调用;worker 返回后由 context manager 关闭 cursor,
连接仍可被显式 `db_disconnect` 释放。

## 备选方案

- 替换原生异步 MySQL/PostgreSQL 驱动:迁移成本高且会改变方言、事务和依赖边界,暂不采用。
- 只在 handler 外包线程、不加连接锁:会留下 SQLite thread-affinity 和 cursor 交叉风险,
不采用。
- 为每个请求建立新连接:增加连接开销并破坏现有 connection ID 生命周期,不采用。

## 影响

- 同步公共 API、SQL、事务提交/回滚、权限和 MCP 文本/Raw Response 保持不变。
- 同一连接的数据库阶段串行,不同连接可以并行等待;不宣称生产吞吐提升。
- worker 调度带来少量开销;驱动额外的线程绑定限制需要在真实 MySQL/PostgreSQL 环境
单独验证。

## 验证

- 受控 60ms 阻塞 driver + heartbeat 证明事件循环仍获调度。
- fake cursor 实验覆盖同连接最大并发为 1、跨连接同时进入和 close 等待 SQL body 完成。
- SQLite in-memory worker 查询和现有 SQLite MCP/codegen 合同继续通过;真实网络数据库
线程模型不在本地实验范围内。
2 changes: 2 additions & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@

### v0.3 (数据库元数据契约)
- [ADR-014: 统一数据库元数据描述契约](014-metadata-introspection-contract.md)
- [ADR-015: MCP 连接生命周期与显式释放](015-connection-lifecycle.md)
- [ADR-016: 将同步数据库调用移出 MCP 事件循环](016-async-database-boundary.md)
7 changes: 7 additions & 0 deletions docs/algorithms-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ CycleResult(
- 多解时按字典序选择
- 这让单测可以严格断言

### 输入规范化

MCP 包装和三个纯算法共享同一输入边界:只接受数组中的非空字符串,表名和
`[child, parent]` 外键边按首次出现去重;非法容器、空值和非二元外键被忽略。
因此 `users, users` 只会在结果中出现一次,重复外键也不会影响入度、聚类或环
检测。外部表引用和自引用仍按各算法原有规则处理。

### 无外部依赖
只用 `collections` 和 `dataclasses` (Python stdlib)。
对比:如果用 networkx,镜像大小 +10MB,启动延迟 +1-2 秒。
Expand Down
6 changes: 3 additions & 3 deletions docs/demo-script.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
```

**说**:
> "33 个工具就绪,modules 全部 OK。注意 progressive 模式 — 初始只暴露 6 个 always-visible 工具,启动 token 从 3300 降到 985。"
> "34 个工具就绪,modules 全部 OK。注意 progressive 模式 — 初始只暴露 6 个 always-visible 工具,启动 token 从 3300 降到 985。"

### [0:45] 任务输入 (10 秒)

Expand Down Expand Up @@ -99,7 +99,7 @@
**做**: `server_metrics` 看一下累积调用。

**说**:
> "整个流程透明可观测,33 个工具,5 阶段 Skill 编排,4 个 MCP App 组件。代码在 [github.com/ZhaoXingPeng/DBJavaGenix](https://github.com/ZhaoXingPeng/DBJavaGenix),完整迭代方案在 iteration-plan/ 目录。"
> "整个流程透明可观测,34 个工具,5 阶段 Skill 编排,4 个 MCP App 组件。会话结束后调用 db_disconnect 释放连接。代码在 [github.com/ZhaoXingPeng/DBJavaGenix](https://github.com/ZhaoXingPeng/DBJavaGenix),完整迭代方案在 iteration-plan/ 目录。"

---

Expand All @@ -116,7 +116,7 @@

打开 README.md 的 mermaid 架构图,讲三层:
- **Skills**: `.claude/skills/java-codegen-from-db/SKILL.md` — 看一眼"5 阶段工作流"
- **MCP 33 工具**: 强调 atomic 拆分 (db_codegen_generate → 7 个原子工具) 与 schema 图算法
- **MCP 34 工具**: 强调 atomic 拆分 (db_codegen_generate → 7 个原子工具) 与 schema 图算法,以及显式 db_disconnect 生命周期
- **Apps**: 4 个 UI 组件,客户端按 _meta 渲染

提一句:
Expand Down
1 change: 1 addition & 0 deletions docs/dependency-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ dbjavagenix migration-guide /path/to/project
- **用户优先**: 优先使用用户现有配置风格
- **版本兼容**: 确保依赖版本间的兼容性
- **最小干预**: 只在必要时添加或修改依赖
- **调用隔离**: 每次分析从默认依赖目录开始,Spring Boot 版本调整不会泄漏到后续项目

### 3. 自动修复机制
- Maven 项目: 自动修改 pom.xml 文件
Expand Down
Loading