feat(workspace): http handler with workspace/worktree/gitops endpoints

This commit is contained in:
2026-05-02 08:36:45 +08:00
parent e31710f04e
commit 78e74c9734
3 changed files with 720 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
// dto.go 定义 workspace 模块 HTTP 层的请求 / 响应结构以及与领域模型的映射函数。
// 设计取舍:
// - 请求 DTO 用 JSON tag 与前端约定的 snake_case 对齐;可选 patch 字段用 *T 区分"不传"和"显式置空"。
// - 响应 DTO 不暴露 secret/main_path 等敏感或内部字段,避免泄漏。
package workspace
import (
"time"
"github.com/google/uuid"
"github.com/yan1h/agent-coding-workflow/internal/infra/git"
)
// ===== Request DTO =====
type createWorkspaceReq struct {
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
GitRemoteURL string `json:"git_remote_url"`
DefaultBranch string `json:"default_branch"`
Credential credentialBody `json:"credential"`
}
type updateWorkspaceReq struct {
Name *string `json:"name"`
Description *string `json:"description"`
DefaultBranch *string `json:"default_branch"`
}
type credentialBody struct {
Kind string `json:"kind"`
Username string `json:"username"`
Secret string `json:"secret"`
}
type createWorktreeReq struct {
Branch string `json:"branch"`
BaseBranch string `json:"base_branch"`
}
type commitReq struct {
Message string `json:"message"`
Push *bool `json:"push"`
AddAll *bool `json:"add_all"`
}
// ===== Response DTO =====
type workspaceResp struct {
ID uuid.UUID `json:"id"`
ProjectID uuid.UUID `json:"project_id"`
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
GitRemoteURL string `json:"git_remote_url"`
DefaultBranch string `json:"default_branch"`
SyncStatus string `json:"sync_status"`
LastSyncedAt *time.Time `json:"last_synced_at"`
LastSyncError string `json:"last_sync_error"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func toWorkspaceResp(w *Workspace) workspaceResp {
return workspaceResp{
ID: w.ID, ProjectID: w.ProjectID, Slug: w.Slug, Name: w.Name,
Description: w.Description, GitRemoteURL: w.GitRemoteURL, DefaultBranch: w.DefaultBranch,
SyncStatus: string(w.SyncStatus), LastSyncedAt: w.LastSyncedAt, LastSyncError: w.LastSyncError,
CreatedAt: w.CreatedAt, UpdatedAt: w.UpdatedAt,
}
}
type worktreeResp struct {
ID uuid.UUID `json:"id"`
WorkspaceID uuid.UUID `json:"workspace_id"`
Branch string `json:"branch"`
Path string `json:"path"`
Status string `json:"status"`
ActiveHolder string `json:"active_holder"`
AcquiredAt *time.Time `json:"acquired_at"`
LastUsedAt time.Time `json:"last_used_at"`
CreatedAt time.Time `json:"created_at"`
}
func toWorktreeResp(w *Worktree) worktreeResp {
return worktreeResp{
ID: w.ID, WorkspaceID: w.WorkspaceID, Branch: w.Branch, Path: w.Path,
Status: string(w.Status), ActiveHolder: w.ActiveHolder, AcquiredAt: w.AcquiredAt,
LastUsedAt: w.LastUsedAt, CreatedAt: w.CreatedAt,
}
}
type credentialResp struct {
Kind string `json:"kind"`
Username string `json:"username"`
Fingerprint string `json:"fingerprint"`
}
func toCredentialResp(c *Credential) credentialResp {
return credentialResp{Kind: string(c.Kind), Username: c.Username, Fingerprint: c.Fingerprint}
}
type fileStatusResp struct {
Path string `json:"path"`
IndexX string `json:"index_x"`
WorktreeY string `json:"worktree_y"`
}
func toFileStatusResp(f git.FileStatus) fileStatusResp {
return fileStatusResp{Path: f.Path, IndexX: string(f.IndexX), WorktreeY: string(f.WorktreeY)}
}
type commitResp struct {
SHA string `json:"sha"`
}