You've already forked agentic-coding-workflow
bugfix
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
// Package changerequest models the change_requests entity and the server-side
|
||||
// merge gate. A change request links a project/workspace/(requirement|issue)
|
||||
// and a source->target branch to an external (Gitea) pull request, carrying a
|
||||
// review verdict + CI state. The crux is Service.Merge, which hard-blocks the
|
||||
// host-side merge unless review_verdict=='approved' (and optionally
|
||||
// ci_state=='success'): an agent can open and merge PRs via MCP, but cannot
|
||||
// self-approve — approval is HTTP/web-only by policy.
|
||||
//
|
||||
// Layout mirrors internal/workspace (single package, service + repository +
|
||||
// handler + sqlc) to keep the aggregate cohesive.
|
||||
package changerequest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// State mirrors the change_requests.state CHECK constraint.
|
||||
type State string
|
||||
|
||||
// State enum values.
|
||||
const (
|
||||
StateOpen State = "open"
|
||||
StateMerged State = "merged"
|
||||
StateClosed State = "closed"
|
||||
)
|
||||
|
||||
// Verdict mirrors the change_requests.review_verdict CHECK constraint.
|
||||
type Verdict string
|
||||
|
||||
// Verdict enum values.
|
||||
const (
|
||||
VerdictPending Verdict = "pending"
|
||||
VerdictApproved Verdict = "approved"
|
||||
VerdictChangesRequested Verdict = "changes_requested"
|
||||
VerdictRejected Verdict = "rejected"
|
||||
)
|
||||
|
||||
// IsValid reports whether v is in the enum set.
|
||||
func (v Verdict) IsValid() bool {
|
||||
switch v {
|
||||
case VerdictPending, VerdictApproved, VerdictChangesRequested, VerdictRejected:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CIState mirrors the change_requests.ci_state CHECK constraint.
|
||||
type CIState string
|
||||
|
||||
// CIState enum values.
|
||||
const (
|
||||
CIUnknown CIState = "unknown"
|
||||
CIPending CIState = "pending"
|
||||
CISuccess CIState = "success"
|
||||
CIFailure CIState = "failure"
|
||||
)
|
||||
|
||||
// ChangeRequest is the change_requests row projection.
|
||||
type ChangeRequest struct {
|
||||
ID uuid.UUID
|
||||
ProjectID uuid.UUID
|
||||
WorkspaceID uuid.UUID
|
||||
RequirementID *uuid.UUID
|
||||
IssueID *uuid.UUID
|
||||
Number int
|
||||
Title string
|
||||
Description string
|
||||
SourceBranch string
|
||||
TargetBranch string
|
||||
State State
|
||||
ReviewVerdict Verdict
|
||||
CIState CIState
|
||||
Provider string
|
||||
ExternalID *int64
|
||||
ExternalURL string
|
||||
MergeCommitSHA string
|
||||
ReviewedBy *uuid.UUID
|
||||
ReviewedAt *time.Time
|
||||
CreatedBy uuid.UUID
|
||||
MergedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// Caller mirrors workspace.Caller: the user context driving auth + audit.
|
||||
type Caller struct {
|
||||
UserID uuid.UUID
|
||||
IsAdmin bool
|
||||
SessionID *uuid.UUID
|
||||
}
|
||||
|
||||
// CreateInput carries the fields to open a change request (and host PR).
|
||||
type CreateInput struct {
|
||||
SourceBranch string
|
||||
TargetBranch string // empty => workspace default branch
|
||||
Title string
|
||||
Description string
|
||||
RequirementID *uuid.UUID
|
||||
IssueID *uuid.UUID
|
||||
}
|
||||
|
||||
// Service is the change-request application service.
|
||||
type Service interface {
|
||||
Create(ctx context.Context, c Caller, wsID uuid.UUID, in CreateInput) (*ChangeRequest, error)
|
||||
Get(ctx context.Context, c Caller, id uuid.UUID) (*ChangeRequest, error)
|
||||
GetByNumber(ctx context.Context, c Caller, projectSlug string, number int) (*ChangeRequest, error)
|
||||
ListByWorkspace(ctx context.Context, c Caller, wsID uuid.UUID) ([]*ChangeRequest, error)
|
||||
// Review records a human verdict (owner/admin only). It is intentionally NOT
|
||||
// exposed as an MCP tool so agents cannot self-approve their own PRs.
|
||||
Review(ctx context.Context, c Caller, id uuid.UUID, verdict Verdict, note string) (*ChangeRequest, error)
|
||||
// Merge is the gate: requires review_verdict=='approved' (+ ci success when
|
||||
// RequireCIPass), then merges the host PR and persists merged state.
|
||||
Merge(ctx context.Context, c Caller, id uuid.UUID, method string) (*ChangeRequest, error)
|
||||
// SyncStatus refreshes ci_state/state from the host (provider.GetPR).
|
||||
SyncStatus(ctx context.Context, c Caller, id uuid.UUID) (*ChangeRequest, error)
|
||||
}
|
||||
Reference in New Issue
Block a user