chore(repo): reinitialize repository

This commit is contained in:
2026-03-18 11:29:54 +08:00
commit 24871e213a
288 changed files with 44369 additions and 0 deletions
@@ -0,0 +1,211 @@
package httpapi
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"inbox/internal/base/timeutil"
"inbox/internal/domain/lane"
"inbox/internal/domain/lanesync"
"inbox/internal/domain/task"
"inbox/internal/domain/topic"
"inbox/internal/domain/workspace"
sqlitestore "inbox/internal/store/sqlite"
)
func TestDashboardWorkflowBoardIncludesLanesAndTasks(t *testing.T) {
clock := timeutil.FixedClock{Time: time.Date(2026, 3, 16, 11, 0, 0, 0, time.UTC)}
store, err := sqlitestore.OpenInMemory(clock)
if err != nil {
t.Fatalf("OpenInMemory() error = %v", err)
}
defer store.Close()
ctx := context.Background()
project, err := store.CreateProject(ctx, workspace.Project{
Slug: "demo",
Name: "Demo",
RootPath: t.TempDir(),
DefaultBranch: "main",
Status: "active",
})
if err != nil {
t.Fatalf("CreateProject() error = %v", err)
}
ws, err := store.CreateWorkspace(ctx, workspace.Workspace{
ProjectID: project.ID,
Slug: "main",
Name: "Main",
RootPath: t.TempDir(),
BaseBranch: "main",
WorktreeBranch: "worktree/main",
RuntimeBackend: "host",
Status: "active",
})
if err != nil {
t.Fatalf("CreateWorkspace() error = %v", err)
}
record, err := store.CreateTopic(ctx, topic.Record{
WorkspaceID: ws.ID,
Slug: "signup-flow",
Title: "Signup Flow",
Space: topic.SpaceWorkflow,
Status: "execution",
})
if err != nil {
t.Fatalf("CreateTopic() error = %v", err)
}
laneRecord, err := store.CreateLane(ctx, lane.Record{
WorkspaceID: ws.ID,
TopicID: record.ID,
Name: "UI Chain",
Slug: "ui-chain",
Status: lane.StatusRunning,
BaseBranch: "main",
BranchName: "lane/main/ui-lane",
HeadCommit: "abc123def4567890",
WorktreePath: "/tmp/ui-chain",
ContainerName: "lane-main-ui-lane",
CreatedByRoleName: "leader",
})
if err != nil {
t.Fatalf("CreateLane() error = %v", err)
}
upstreamLane, err := store.CreateLane(ctx, lane.Record{
WorkspaceID: ws.ID,
TopicID: record.ID,
Name: "Foundation",
Slug: "foundation",
Status: lane.StatusSucceeded,
BaseBranch: "main",
BranchName: "lane/main/foundation",
HeadCommit: "1234567890abcdef",
WorktreePath: "/tmp/foundation",
ContainerName: "lane-main-foundation",
CreatedByRoleName: "leader",
})
if err != nil {
t.Fatalf("CreateLane(upstream) error = %v", err)
}
rootTask, err := store.CreateTask(ctx, task.Record{
WorkspaceID: ws.ID,
TopicID: record.ID,
LaneID: laneRecord.ID,
Title: "Build UI",
BodyMarkdown: "Implement the UI lane.",
Status: task.StatusRunning,
TaskOrder: 1,
Priority: 10,
CreatedByRoleName: "leader",
}, nil)
if err != nil {
t.Fatalf("CreateTask(root) error = %v", err)
}
if _, err := store.CreateTask(ctx, task.Record{
WorkspaceID: ws.ID,
TopicID: record.ID,
LaneID: laneRecord.ID,
Title: "Verify UI",
BodyMarkdown: "Verify the UI lane.",
Status: task.StatusDraft,
TaskOrder: 2,
Priority: 5,
CreatedByRoleName: "leader",
}, []task.Dependency{{DependsOnTaskID: rootTask.ID}}); err != nil {
t.Fatalf("CreateTask(dependent) error = %v", err)
}
if _, err := store.CreateLaneSync(ctx, lanesync.Record{
WorkspaceID: ws.ID,
TopicID: record.ID,
DownstreamLaneID: laneRecord.ID,
UpstreamLaneID: upstreamLane.ID,
TaskID: rootTask.ID,
UpstreamCommit: "1234567890abcdef",
MergeCommit: "fedcba0987654321",
Status: lanesync.StatusApplied,
}); err != nil {
t.Fatalf("CreateLaneSync() error = %v", err)
}
handler := NewHandler(store, clock)
req := httptest.NewRequest(http.MethodGet, "/api/v2/dashboard/workflow/board?workspace="+ws.Slug+"&topic="+record.Slug, nil)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("GET workflow board status = %d body=%s", rec.Code, rec.Body.String())
}
var payload struct {
Board struct {
Lanes []struct {
Name string `json:"name"`
Status string `json:"status"`
HeadCommit string `json:"head_commit"`
LastSync *struct {
Status string `json:"status"`
UpstreamLaneID string `json:"upstream_lane_id"`
} `json:"last_sync"`
SyncHistory []struct {
Status string `json:"status"`
} `json:"sync_history"`
} `json:"lanes"`
Tasks []struct {
Title string `json:"title"`
Status string `json:"status"`
LaneID string `json:"lane_id"`
Dependencies []struct {
DependsOnTaskID string `json:"depends_on_task_id"`
} `json:"dependencies"`
} `json:"tasks"`
} `json:"board"`
}
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
t.Fatalf("decode workflow board: %v", err)
}
if len(payload.Board.Lanes) != 2 {
t.Fatalf("unexpected lanes payload: %#v", payload.Board.Lanes)
}
var uiLane *struct {
Name string `json:"name"`
Status string `json:"status"`
HeadCommit string `json:"head_commit"`
LastSync *struct {
Status string `json:"status"`
UpstreamLaneID string `json:"upstream_lane_id"`
} `json:"last_sync"`
SyncHistory []struct {
Status string `json:"status"`
} `json:"sync_history"`
}
for idx := range payload.Board.Lanes {
if payload.Board.Lanes[idx].Name == "UI Chain" {
uiLane = &payload.Board.Lanes[idx]
break
}
}
if uiLane == nil {
t.Fatalf("expected UI Chain in lanes payload, got %#v", payload.Board.Lanes)
}
if uiLane.HeadCommit != "abc123def4567890" {
t.Fatalf("expected head commit in lanes payload, got %#v", uiLane)
}
if uiLane.LastSync == nil || uiLane.LastSync.Status != "applied" || uiLane.LastSync.UpstreamLaneID != upstreamLane.ID {
t.Fatalf("expected latest lane sync in payload, got %#v", uiLane)
}
if len(uiLane.SyncHistory) != 1 {
t.Fatalf("expected sync history in payload, got %#v", uiLane)
}
if len(payload.Board.Tasks) != 2 {
t.Fatalf("unexpected tasks payload: %#v", payload.Board.Tasks)
}
if payload.Board.Tasks[0].LaneID != laneRecord.ID {
t.Fatalf("expected lane id on task payload, got %#v", payload.Board.Tasks[0])
}
if payload.Board.Tasks[1].Dependencies[0].DependsOnTaskID != rootTask.ID {
t.Fatalf("expected dependency on root task, got %#v", payload.Board.Tasks[1])
}
}