feat: enhance homepage version management with database persistence#757
Conversation
Reviewer's Guide添加基于数据库的首页最新已发布版本信息检索;重构版本介绍查询逻辑以直接使用存储在 带数据库回退逻辑的系统版本增强检索顺序图sequenceDiagram
actor User
participant HomePageController
participant SessionLocal
participant DB
participant HomePageRepository
participant HomePageService
User->>HomePageController: GET /home/version
HomePageController->>SessionLocal: create Session
SessionLocal-->>HomePageController: db_session
HomePageController->>HomePageRepository: get_latest_version_introduction(db_session)
HomePageRepository->>DB: query version_notes where is_published == true
DB-->>HomePageRepository: latest published note
HomePageRepository-->>HomePageController: (version, version_info) or (None, None)
HomePageController->>SessionLocal: db_session.close()
alt latest version from DB found
HomePageController-->>User: success(version, version_info)
else no DB version or DB error
HomePageController->>HomePageService: load_version_introduction(settings.SYSTEM_VERSION)
HomePageService-->>HomePageController: version_info or None
alt JSON version info found
HomePageController-->>User: success(version=settings.SYSTEM_VERSION, version_info)
else no DB and no JSON info
HomePageController->>HomePageController: build empty introduction/introduction_en
HomePageController-->>User: success(version=settings.SYSTEM_VERSION, empty_version_info)
end
end
基于
|
| Change | Details | Files |
|---|---|---|
| 添加仓储辅助方法,通过反射从数据库中获取最新已发布的版本介绍,并组装本地化的介绍负载。 |
|
api/app/repositories/home_page_repository.py |
重构指定版本介绍的获取逻辑,改为使用新的 schema 字段和时间戳格式,而不是关联 version_note_items。 |
|
api/app/repositories/home_page_repository.py |
| 更新系统版本 API endpoint,在存在环境变量和空结构回退的前提下,优先使用基于数据库的最新已发布版本信息。 |
|
api/app/controllers/home_page_controller.py |
Tips and commands
Interacting with Sourcery
- 触发新评审: 在 pull request 中评论
@sourcery-ai review。 - 继续讨论: 直接回复 Sourcery 的评审评论。
- 从评审评论生成 GitHub issue: 在评审评论下回复,请求 Sourcery 从该评论创建 issue。你也可以直接回复
@sourcery-ai issue来从该评论创建 issue。 - 生成 pull request 标题: 在 pull request 标题任意位置写上
@sourcery-ai即可随时生成标题。也可以在 pull request 中评论@sourcery-ai title来(重新)生成标题。 - 生成 pull request 总结: 在 pull request 正文任意位置写上
@sourcery-ai summary,即可在该位置生成 PR 总结。也可以在 pull request 中评论@sourcery-ai summary来(重新)生成总结。 - 生成 Reviewer's Guide: 在 pull request 中评论
@sourcery-ai guide来(重新)生成 Reviewer's Guide。 - 一次性标记解决所有 Sourcery 评论: 在 pull request 中评论
@sourcery-ai resolve,将所有 Sourcery 评论标记为已解决。适用于你已经处理完所有评论且不想继续看到它们的情况。 - 一次性取消所有 Sourcery 评审: 在 pull request 中评论
@sourcery-ai dismiss来取消所有现有的 Sourcery 评审。尤其适合希望以一次全新的评审重新开始的场景——别忘了再评论@sourcery-ai review来触发新的评审!
Customizing Your Experience
前往你的 dashboard 以:
- 启用或禁用评审功能,例如 Sourcery 自动生成的 pull request 总结、Reviewer's Guide 等。
- 修改评审语言。
- 添加、删除或编辑自定义评审指令。
- 调整其他评审设置。
Getting Help
Original review guide in English
Reviewer's Guide
Adds database-backed retrieval of the latest published homepage version information, refactors version introduction lookup to use fields stored in version_notes directly, and updates the version API endpoint to prefer DB data with a JSON-based fallback and safe defaults.
Sequence diagram for enhanced system version retrieval with DB fallback
sequenceDiagram
actor User
participant HomePageController
participant SessionLocal
participant DB
participant HomePageRepository
participant HomePageService
User->>HomePageController: GET /home/version
HomePageController->>SessionLocal: create Session
SessionLocal-->>HomePageController: db_session
HomePageController->>HomePageRepository: get_latest_version_introduction(db_session)
HomePageRepository->>DB: query version_notes where is_published == true
DB-->>HomePageRepository: latest published note
HomePageRepository-->>HomePageController: (version, version_info) or (None, None)
HomePageController->>SessionLocal: db_session.close()
alt latest version from DB found
HomePageController-->>User: success(version, version_info)
else no DB version or DB error
HomePageController->>HomePageService: load_version_introduction(settings.SYSTEM_VERSION)
HomePageService-->>HomePageController: version_info or None
alt JSON version info found
HomePageController-->>User: success(version=settings.SYSTEM_VERSION, version_info)
else no DB and no JSON info
HomePageController->>HomePageController: build empty introduction/introduction_en
HomePageController-->>User: success(version=settings.SYSTEM_VERSION, empty_version_info)
end
end
ER diagram for version_notes based homepage version data
erDiagram
version_notes {
int id PK
varchar version
varchar code_name
varchar code_name_en
date release_date
varchar upgrade_position
varchar upgrade_position_en
json core_upgrades
json core_upgrades_en
bool is_published
}
version_note_items {
int id PK
int note_id FK
int sort_order
varchar title
text content
}
version_notes ||--o{ version_note_items : has
Class diagram for updated homepage version management
classDiagram
class HomePageController {
+get_system_version() ApiResponse
}
class HomePageRepository {
+get_latest_version_introduction(db Session) (str, Dict)
+get_version_introduction(db Session, version str) Dict
}
class HomePageService {
+load_version_introduction(version str) Dict
}
class VersionNotes {
+id: int
+version: str
+code_name: str
+code_name_en: str
+release_date: date
+upgrade_position: str
+upgrade_position_en: str
+core_upgrades: list
+core_upgrades_en: list
+is_published: bool
}
class SessionLocal {
+__call__() Session
}
class Session {
+bind: Engine
+engine: Engine
+query(table)
+close()
}
HomePageController ..> HomePageRepository : uses
HomePageController ..> HomePageService : uses
HomePageController ..> SessionLocal : creates_session
HomePageRepository ..> Session : db_access
HomePageRepository ..> VersionNotes : reflects_table
File-Level Changes
| Change | Details | Files |
|---|---|---|
| Add repository helper to fetch the latest published version introduction from the database using reflection and assemble localized introduction payloads. |
|
api/app/repositories/home_page_repository.py |
| Refactor retrieval of a specific version introduction to use new schema fields and timestamp format instead of joining version_note_items. |
|
api/app/repositories/home_page_repository.py |
| Update the system version API endpoint to prefer DB-based latest published version info with environment-based and empty-structure fallbacks. |
|
api/app/controllers/home_page_controller.py |
Tips and commands
Interacting with Sourcery
- Trigger a new review: Comment
@sourcery-ai reviewon the pull request. - Continue discussions: Reply directly to Sourcery's review comments.
- Generate a GitHub issue from a review comment: Ask Sourcery to create an
issue from a review comment by replying to it. You can also reply to a
review comment with@sourcery-ai issueto create an issue from it. - Generate a pull request title: Write
@sourcery-aianywhere in the pull
request title to generate a title at any time. You can also comment
@sourcery-ai titleon the pull request to (re-)generate the title at any time. - Generate a pull request summary: Write
@sourcery-ai summaryanywhere in
the pull request body to generate a PR summary at any time exactly where you
want it. You can also comment@sourcery-ai summaryon the pull request to
(re-)generate the summary at any time. - Generate reviewer's guide: Comment
@sourcery-ai guideon the pull
request to (re-)generate the reviewer's guide at any time. - Resolve all Sourcery comments: Comment
@sourcery-ai resolveon the
pull request to resolve all Sourcery comments. Useful if you've already
addressed all the comments and don't want to see them anymore. - Dismiss all Sourcery reviews: Comment
@sourcery-ai dismisson the pull
request to dismiss all existing Sourcery reviews. Especially useful if you
want to start fresh with a new review - don't forget to comment
@sourcery-ai reviewto trigger a new review!
Customizing Your Experience
Access your dashboard to:
- Enable or disable review features such as the Sourcery-generated pull request
summary, the reviewer's guide, and others. - Change the review language.
- Add, remove or edit custom review instructions.
- Adjust other review settings.
Getting Help
- Contact our support team for questions or feedback.
- Visit our documentation for detailed guides and information.
- Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.
There was a problem hiding this comment.
Hey - 我发现了两个问题,并且给出了一些整体性的反馈:
- 在
get_latest_version_introduction中,你使用了datetime和time却没有导入它们(不同于get_version_introduction中的做法),这会导致NameError;建议在该函数中添加相同的导入,或者把时间戳转换逻辑集中到一个共享的辅助函数中。 - 新增的数据库访问路径(
get_latest_version_introduction和get_system_version)中使用了print/traceback.print_exc()以及宽泛的except Exception;建议改用统一的日志记录机制,并将异常范围收窄到预期的失败场景,这样更易于维护。 version_info字典的构建逻辑(introduction/introduction_en 字段和时间戳转换)在get_latest_version_introduction、get_version_introduction和 controller 的兜底逻辑之间是重复的;建议提取一个共享的辅助函数,避免逻辑分叉,也方便后续修改。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `get_latest_version_introduction` you use `datetime` and `time` without importing them (unlike in `get_version_introduction`), which will raise a `NameError`; consider adding the same import there or centralizing the timestamp conversion helper.
- The new database access paths (`get_latest_version_introduction` and `get_system_version`) use `print`/`traceback.print_exc()` and broad `except Exception` blocks; it would be cleaner to use your standard logging facilities and narrow the exceptions to expected failure cases.
- The construction of the `version_info` dict (introduction/introduction_en fields and timestamp conversion) is duplicated between `get_latest_version_introduction`, `get_version_introduction`, and the controller fallback; consider extracting a shared helper to avoid divergence and make future changes easier.
## Individual Comments
### Comment 1
<location path="api/app/controllers/home_page_controller.py" line_range="43-52" />
<code_context>
+ try:
+ db = SessionLocal()
+ try:
+ print(f"[DEBUG] 开始从数据库获取最新版本...")
+ current_version, version_info = HomePageRepository.get_latest_version_introduction(db)
+ if current_version:
+ print(f"[DEBUG] 数据库获取成功:version={current_version}")
+ else:
+ print(f"[DEBUG] 数据库获取失败:current_version=None")
+ finally:
+ db.close()
+ except Exception as e:
+ print(f"[DEBUG] 数据库查询异常:{e}")
+ pass
+
</code_context>
<issue_to_address>
**suggestion:** Direct `print`-based debugging in the controller will clutter stdout and is hard to manage in production.
In `get_system_version`, replace the `[DEBUG]` print statements with the existing logging framework (e.g., `logger.info` / `logger.warning`) so logs can be managed and filtered properly. If these were only for local troubleshooting, they should be removed before merging.
</issue_to_address>
### Comment 2
<location path="api/app/controllers/home_page_controller.py" line_range="61-66" />
<code_context>
+
+ # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息
+ if not version_info:
+ version_info = {
+ "introduction": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []},
+ "introduction_en": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []}
+ }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Fallback `releaseDate` type differs from the integer timestamp used in the DB-backed paths.
Repository methods now use an integer timestamp (ms) for `releaseDate`, but this fallback sets it to an empty string. This type mismatch can break callers expecting a number. Please return a numeric value (e.g., `0`) or `None` here to keep `releaseDate`’s type consistent across all code paths.
```suggestion
# 3️⃣ 如果数据库和 JSON 都没有,返回基本信息
# 注意:releaseDate 保持为整型时间戳(ms),避免与数据库返回的类型不一致
if not version_info:
version_info = {
"introduction": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []},
"introduction_en": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []}
}
```
</issue_to_address>帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- In
get_latest_version_introductionyou usedatetimeandtimewithout importing them (unlike inget_version_introduction), which will raise aNameError; consider adding the same import there or centralizing the timestamp conversion helper. - The new database access paths (
get_latest_version_introductionandget_system_version) useprint/traceback.print_exc()and broadexcept Exceptionblocks; it would be cleaner to use your standard logging facilities and narrow the exceptions to expected failure cases. - The construction of the
version_infodict (introduction/introduction_en fields and timestamp conversion) is duplicated betweenget_latest_version_introduction,get_version_introduction, and the controller fallback; consider extracting a shared helper to avoid divergence and make future changes easier.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `get_latest_version_introduction` you use `datetime` and `time` without importing them (unlike in `get_version_introduction`), which will raise a `NameError`; consider adding the same import there or centralizing the timestamp conversion helper.
- The new database access paths (`get_latest_version_introduction` and `get_system_version`) use `print`/`traceback.print_exc()` and broad `except Exception` blocks; it would be cleaner to use your standard logging facilities and narrow the exceptions to expected failure cases.
- The construction of the `version_info` dict (introduction/introduction_en fields and timestamp conversion) is duplicated between `get_latest_version_introduction`, `get_version_introduction`, and the controller fallback; consider extracting a shared helper to avoid divergence and make future changes easier.
## Individual Comments
### Comment 1
<location path="api/app/controllers/home_page_controller.py" line_range="43-52" />
<code_context>
+ try:
+ db = SessionLocal()
+ try:
+ print(f"[DEBUG] 开始从数据库获取最新版本...")
+ current_version, version_info = HomePageRepository.get_latest_version_introduction(db)
+ if current_version:
+ print(f"[DEBUG] 数据库获取成功:version={current_version}")
+ else:
+ print(f"[DEBUG] 数据库获取失败:current_version=None")
+ finally:
+ db.close()
+ except Exception as e:
+ print(f"[DEBUG] 数据库查询异常:{e}")
+ pass
+
</code_context>
<issue_to_address>
**suggestion:** Direct `print`-based debugging in the controller will clutter stdout and is hard to manage in production.
In `get_system_version`, replace the `[DEBUG]` print statements with the existing logging framework (e.g., `logger.info` / `logger.warning`) so logs can be managed and filtered properly. If these were only for local troubleshooting, they should be removed before merging.
</issue_to_address>
### Comment 2
<location path="api/app/controllers/home_page_controller.py" line_range="61-66" />
<code_context>
+
+ # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息
+ if not version_info:
+ version_info = {
+ "introduction": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []},
+ "introduction_en": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []}
+ }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Fallback `releaseDate` type differs from the integer timestamp used in the DB-backed paths.
Repository methods now use an integer timestamp (ms) for `releaseDate`, but this fallback sets it to an empty string. This type mismatch can break callers expecting a number. Please return a numeric value (e.g., `0`) or `None` here to keep `releaseDate`’s type consistent across all code paths.
```suggestion
# 3️⃣ 如果数据库和 JSON 都没有,返回基本信息
# 注意:releaseDate 保持为整型时间戳(ms),避免与数据库返回的类型不一致
if not version_info:
version_info = {
"introduction": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []},
"introduction_en": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []}
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息 | ||
| if not version_info: | ||
| version_info = { | ||
| "introduction": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []}, | ||
| "introduction_en": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []} | ||
| } |
There was a problem hiding this comment.
suggestion (bug_risk): 兜底逻辑里的 releaseDate 类型与数据库路径中使用的整型时间戳不一致。
当前仓库方法对 releaseDate 使用的是整型时间戳(毫秒),但这里的兜底逻辑却把它设为一个空字符串。这种类型不一致会导致期望数字的调用方出现问题。请在这里返回数值类型(例如 0)或 None,以保证所有代码路径中 releaseDate 的类型保持一致。
| # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息 | |
| if not version_info: | |
| version_info = { | |
| "introduction": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []}, | |
| "introduction_en": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []} | |
| } | |
| # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息 | |
| # 注意:releaseDate 保持为整型时间戳(ms),避免与数据库返回的类型不一致 | |
| if not version_info: | |
| version_info = { | |
| "introduction": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []}, | |
| "introduction_en": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []} | |
| } |
Original comment in English
suggestion (bug_risk): Fallback releaseDate type differs from the integer timestamp used in the DB-backed paths.
Repository methods now use an integer timestamp (ms) for releaseDate, but this fallback sets it to an empty string. This type mismatch can break callers expecting a number. Please return a numeric value (e.g., 0) or None here to keep releaseDate’s type consistent across all code paths.
| # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息 | |
| if not version_info: | |
| version_info = { | |
| "introduction": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []}, | |
| "introduction_en": {"codeName": "", "releaseDate": "", "upgradePosition": "", "coreUpgrades": []} | |
| } | |
| # 3️⃣ 如果数据库和 JSON 都没有,返回基本信息 | |
| # 注意:releaseDate 保持为整型时间戳(ms),避免与数据库返回的类型不一致 | |
| if not version_info: | |
| version_info = { | |
| "introduction": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []}, | |
| "introduction_en": {"codeName": "", "releaseDate": 0, "upgradePosition": "", "coreUpgrades": []} | |
| } |
Summary by Sourcery
从数据库中持久化并提供首页版本信息,并在需要时回退到基于环境变量的 JSON 配置。
新功能:
增强改进:
Original summary in English
Summary by Sourcery
Persist and serve homepage version information from the database with a fallback to environment-based JSON configuration.
New Features:
Enhancements: