# skillhub 后端时间字段台账 ## 1. 扫描范围 本台账基于 `server/skillhub-app`、`server/skillhub-auth`、`server/skillhub-domain`、`server/skillhub-infra`、`server/skillhub-storage` 的当前生产代码与 Flyway migration。 目标已经从“摸底问题分布”转为“记录当前真实进展与剩余尾项”。 ## 2. 当前代码分布 ### 2.1 生产代码中的 `LocalDateTime` 已基本清空 当前生产代码里只剩 1 处兼容解析保留 `LocalDateTime`: - `ApiTokenService` - 用于兼容旧接口传入的裸时间字符串 - 当前明确按 UTC 解释后转成 `Instant` 此前集中使用 `LocalDateTime` 的主链区域已完成迁移或收口: - 认证与账号: - `api_token` - `account_merge_request` - `user_account` - `identity_binding` - `role` - `user_role_binding` - `local_credential` - 核心领域: - `namespace` - `namespace_member` - `skill` - `skill_version` - `skill_file` - `skill_tag` - `skill_version_stats` - `skill_report` - `skill_star` - `skill_rating` - 服务层: - `AccountMergeService` - `LocalAuthService` - `SkillPublishService` - `SkillGovernanceService` - `ReviewService` - `PromotionService` - `SkillReportService` - DTO 与接口输出: - `NamespaceResponse` - `MemberResponse` - `SkillSummaryResponse` - `SkillVersionResponse` - `SkillVersionDetailResponse` - `TagResponse` - `AdminUserSummaryResponse` - `AdminSkillReportSummaryResponse` 结论: - 主系统核心“事件发生时间”已经基本收口成 UTC 绝对时间 - 当前剩余工作主要是兼容策略、数据库尾项复核和防回归约束 ### 2.2 `Instant` 已成为主流绝对时间类型 当前已稳定使用 `Instant` 的代表区域: - 审计: - `AuditLog` - `AuditLogItemResponse` - 通知: - `UserNotification` - 审核流程: - `ReviewTask` - `PromotionRequest` - `ReviewTaskResponse` - `PromotionResponseDto` - 幂等: - `IdempotencyRecord` - `IdempotencyInterceptor` - `IdempotencyCleanupTask` - 技能主链: - `Skill` - `SkillVersion` - `SkillTag` - `SkillFile` - `SkillVersionStats` - 认证主链: - `ApiToken` - `AccountMergeRequest` - `UserAccount` - `IdentityBinding` - `Role` - `UserRoleBinding` - `LocalCredential` ## 3. 数据库层分布 ### 3.1 已完成的 `TIMESTAMPTZ` 迁移 - `V12__governance_notifications.sql` - `user_notification.created_at / read_at` - `V24__api_token_timestamptz.sql` - `api_token.expires_at / last_used_at / revoked_at / created_at` - `V25__account_merge_request_timestamptz.sql` - `account_merge_request.token_expires_at / completed_at / created_at` - `V26__skill_version_timestamptz.sql` - `skill_version.published_at / created_at / yanked_at` - `V16__skill_hidden_at_timestamptz.sql` - `skill.hidden_at` - `V17__skill_created_updated_timestamptz.sql` - `skill.created_at / updated_at` - `V18__namespace_timestamptz.sql` - `namespace.created_at / updated_at` - `namespace_member.created_at / updated_at` - `V19__skill_secondary_timestamptz.sql` - `skill_tag.created_at / updated_at` - `skill_file.created_at` - `skill_version_stats.updated_at` - `V20__social_and_skill_report_timestamptz.sql` - `skill_star.created_at` - `skill_rating.created_at / updated_at` - `skill_report.created_at / handled_at` - `V21__user_account_timestamptz.sql` - `user_account.created_at / updated_at` - `V22__auth_supporting_tables_timestamptz.sql` - `identity_binding.created_at / updated_at` - `role.created_at` - `user_role_binding.created_at` - `local_credential.locked_until / created_at / updated_at` - `V23__review_and_idempotency_timestamptz.sql` - `review_task.submitted_at / reviewed_at` - `promotion_request.submitted_at / reviewed_at` - `idempotency_record.created_at / expires_at` - `V42__audit_log_created_at_timestamptz.sql` - `audit_log.created_at` ### 3.2 当前状态 - 主链核心事件时间列已基本完成 `TIMESTAMPTZ` 收口 - 初始建表 migration 中仍然能看到旧 `TIMESTAMP` 定义,但已由后续 Flyway 升级覆盖 - 后续重点不是“大批量迁移”,而是查漏补缺和约束新增 ## 4. 已解决的高风险热点 ### 4.1 兼容层时区解释冲突 此前: - `ClawHubCompatController` 按 `ZoneOffset.UTC` 转 epoch - `ClawHubRegistryFacade` 按系统默认时区解释 当前: - 已统一按 UTC 解释绝对时间 - `ClawHubRegistryFacade` 的 `LocalDateTime` epoch 转换重载已移除 ### 4.2 服务层散落的 `now()` 此前热点包括: - `ApiTokenService` - `AccountMergeService` - `LocalAuthService` - `SkillPublishService` - `SkillGovernanceService` - `ReviewService` - `PromotionService` - `SkillReportService` - 多个实体 `@PrePersist` / `@PreUpdate` 当前: - 服务层当前时间已基本统一为注入 `Clock` - 实体回调已基本统一为显式 UTC ## 5. 分批迁移进展 ### Batch 1:基础设施与治理链路 已完成: - UTC `Clock` Bean - Hibernate UTC 配置 - Jackson UTC 配置 - `ApiResponseFactory` - `IdempotencyInterceptor` - `IdempotencyCleanupTask` - 审计、通知、审核、幂等链路 ### Batch 2:认证与账号链路 已完成: - `ApiToken` / `ApiTokenService` - `AccountMergeRequest` / `AccountMergeService` - `LocalCredential` - `UserAccount` - `IdentityBinding` - `Role` - `UserRoleBinding` - `LocalAuthService` ### Batch 3:技能核心领域 已完成: - `Skill` - `SkillVersion` - `SkillFile` - `SkillTag` - `SkillVersionStats` - `Namespace` - `NamespaceMember` - `SkillPublishService` - `SkillGovernanceService` - `ReviewService` - `PromotionService` - `SkillReport` - `SkillStar` - `SkillRating` ### Batch 4:DTO 与 API 契约收口 已完成: - `NamespaceResponse` - `MemberResponse` - `SkillSummaryResponse` - `SkillVersionResponse` - `SkillVersionDetailResponse` - `TagResponse` - `AdminUserSummaryResponse` - `AdminSkillReportSummaryResponse` - `TokenController` 的 UTC 输出收口 ## 6. 当前剩余尾项 - `ApiTokenService` 仍保留对裸 `LocalDateTime` 字符串的兼容解析 - 需要补静态扫描或 ArchUnit 约束,防止新增 `LocalDateTime.now()` - 需要做一轮跨时区回归,把 `UTC` / `Asia/Shanghai` 纳入关键测试