docs(project): document tri-state DTO semantics in domain.go

This commit is contained in:
2026-05-01 09:46:45 +08:00
parent ce88c4b4a7
commit 5f63fb5e52
+30
View File
@@ -144,7 +144,11 @@ type IssueService interface {
} }
// ===== 输入 DTO ===== // ===== 输入 DTO =====
//
// 约定(适用于全部 Update*Input):指针字段为 nil 表示"未提供,保持原值";
// 非 nil 表示"用解引用值替换"。Filter 类型使用零值(""、nil)表示"不过滤"。
// CreateProjectInput 携带创建 Project 必需的字段。Visibility 留空时由 Service 默认 private。
type CreateProjectInput struct { type CreateProjectInput struct {
Slug string Slug string
Name string Name string
@@ -152,29 +156,39 @@ type CreateProjectInput struct {
Visibility Visibility Visibility Visibility
} }
// UpdateProjectInput 是 Project 的 patch 输入:每个非 nil 字段表示要替换的值;
// nil 字段保持现有值不变。Slug / Owner / ArchivedAt 不在此处修改。
type UpdateProjectInput struct { type UpdateProjectInput struct {
Name *string Name *string
Description *string Description *string
Visibility *Visibility Visibility *Visibility
} }
// CreateRequirementInput 创建一条需求。OwnerID 为 nil 时由 Service 默认为调用者。
type CreateRequirementInput struct { type CreateRequirementInput struct {
Title string Title string
Description string Description string
OwnerID *uuid.UUID OwnerID *uuid.UUID
} }
// UpdateRequirementInput 同 UpdateProjectInput 的 patch 语义。Phase / Status 不在此处修改,
// 走专用方法 ChangePhase / Close / Reopen 以便 audit 区分。
type UpdateRequirementInput struct { type UpdateRequirementInput struct {
Title *string Title *string
Description *string Description *string
OwnerID *uuid.UUID OwnerID *uuid.UUID
} }
// RequirementFilter 控制 List 时的过滤维度。Phase / Status 留零值("" / Status(""))表示
// 不限制;非零值必须落在对应枚举集合内(IsValid 校验在 Service 层做)。
type RequirementFilter struct { type RequirementFilter struct {
Phase Phase Phase Phase
Status Status Status Status
} }
// CreateIssueInput 创建 Issue。RequirementNumber == nil 表示游离 Issue(不挂载到任何
// Requirement);非 nil 时 Service 会校验 1) 该 Requirement 与目标 Project 同属,
// 2) 未关闭。
type CreateIssueInput struct { type CreateIssueInput struct {
Title string Title string
Description string Description string
@@ -182,12 +196,28 @@ type CreateIssueInput struct {
AssigneeID *uuid.UUID AssigneeID *uuid.UUID
} }
// UpdateIssueInput 是 Issue 的 patch 输入。RequirementNumber 为指针的指针,承载三种状态:
//
// nil —— 未提供(不修改 issue.requirement_id)
// *x == nil —— 已提供,但要求"取消挂载"(issue.requirement_id 置 NULL)
// *x != nil —— 已提供,要求"挂载到本项目下 number=**x 的 Requirement"
//
// HTTP 层用 json.RawMessage 区分 "字段缺省 vs 显式 null vs 数字",再翻译为本三态。
type UpdateIssueInput struct { type UpdateIssueInput struct {
Title *string Title *string
Description *string Description *string
RequirementNumber **int RequirementNumber **int
} }
// IssueFilter 控制 List 时的过滤。Requirement 字段三态(与 sqlc requirement_filter
// narg 对应):
//
// nil —— 不按 requirement 过滤
// *Requirement == 0 —— 仅游离(requirement_id IS NULL)—— 0 是 sentinel,因为
// Issue.Number 自增从 1 起
// *Requirement > 0 —— 仅匹配 number == *Requirement 的 Requirement
//
// AssigneeID nil 表示不按 assignee 过滤;Status 留零值表示不按状态过滤。
type IssueFilter struct { type IssueFilter struct {
Status Status Status Status
Requirement *int Requirement *int