Documentation
¶
Overview ¶
Package issue manages contract-validated project issues.
Index ¶
- Constants
- Variables
- type CreateParams
- type EffortAssessment
- type Issue
- type IssueMetadata
- type QueryPage
- type QueryParams
- type Recovery
- type RecoveryExcerpt
- type RecoveryExecution
- type RecoveryFinish
- type RecoveryIssue
- type RecoveryLink
- type RecoveryParams
- type Store
- func (s *Store) Close() error
- func (s *Store) Create(ctx context.Context, params CreateParams) (Issue, error)
- func (s *Store) Get(ctx context.Context, projectReference, key string) (Issue, error)
- func (s *Store) List(ctx context.Context, projectReference string) ([]Issue, error)
- func (s *Store) Query(ctx context.Context, params QueryParams) (QueryPage, error)
- func (s *Store) Recover(ctx context.Context, params RecoveryParams) (Recovery, error)
- func (s *Store) SetTrackerClientFactory(factory func(context.Context, string, tracker.Config) (tracker.Client, error))
- func (s *Store) Transition(ctx context.Context, projectReference, key, targetState string) (Issue, error)
- func (s *Store) TransitionAs(ctx context.Context, projectReference, key, targetState, actorID string) (Issue, error)
- func (s *Store) TransitionWithDecisionAs(ctx context.Context, ...) (Issue, error)
- func (s *Store) Update(ctx context.Context, params UpdateParams) (Issue, error)
- type UpdateParams
- type ValidationError
- type ValidationFailure
- type WorkStart
Constants ¶
const ( DefaultRecoveryTextLimit = 2000 MaxRecoveryTextLimit = 8000 )
const ( StatePendingApproval = "pending-approval" StateChangesRequested = "changes-requested" StateDeclined = "declined" ApprovalDecisionApproved = "approved" ApprovalDecisionChangesRequested = "changes-requested" ApprovalDecisionDeclined = "declined" )
const ( // DefaultQueryLimit is the metadata query page size used when a caller omits it. DefaultQueryLimit = 20 // MaxQueryLimit bounds the metadata returned by one query page. MaxQueryLimit = 100 // OversizedEffortThreshold is the largest effort value before decomposition // should normally be considered for non-feature issues. OversizedEffortThreshold = 8 )
const ( EffortStatusUnestimated = "unestimated" EffortStatusWithinLimit = "within-limit" EffortStatusOversized = "oversized" EffortStatusOversizedFeature = "oversized-feature" )
Variables ¶
var ( ErrProjectNotFound = errors.New("project not found") ErrProjectArchived = errors.New("project is archived") ErrIssueNotFound = errors.New("issue not found") ErrIssueTypeNotFound = errors.New("issue type is not declared by the active contract") ErrPriorityNotFound = errors.New("priority is not declared by the active contract") ErrIssueStateNotFound = errors.New("workflow state is not declared by the active contract") ErrInvalidTransition = errors.New("workflow transition is not allowed") ErrApprovalDecisionRequired = errors.New("an explicit approval decision is required") ErrInvalidApprovalDecision = errors.New("approval decision is invalid for this transition") ErrApprovalWorkBlocked = errors.New("issue work is blocked by the approval workflow") ErrInvalidIssueQuery = errors.New("invalid issue query") )
var ErrInvalidRecovery = errors.New("invalid issue recovery query")
Functions ¶
This section is empty.
Types ¶
type CreateParams ¶
type CreateParams struct {
Project string
Type string
Title string
Description string
Priority string
Fields map[string]any
Actor string
Effort *int
}
CreateParams defines a new issue in a project's active era.
type EffortAssessment ¶ added in v0.8.0
type EffortAssessment struct {
Status string `json:"status"`
DecompositionRecommended bool `json:"decompositionRecommended"`
}
EffortAssessment reports the advisory sizing signal derived from an issue's type and optional effort. It never rejects or changes an issue.
func AssessEffort ¶ added in v0.8.0
func AssessEffort(issueType string, effort *int) EffortAssessment
AssessEffort classifies effort values for the harness and reporting views. Features may remain above the threshold, but are distinguished from other oversized work so callers can warn without automatically splitting them.
type Issue ¶
type Issue struct {
Tracker *tracker.Link `json:"tracker,omitempty"`
ID int64
ProjectID int64
EraID int64
Number int
Key string
Type string
Title string
Description string
Priority string
Effort *int
State string
Fields map[string]any
Revision int
CreatedAt time.Time
UpdatedAt time.Time
ArchivedAt *time.Time
}
Issue is the current persisted issue snapshot.
type IssueMetadata ¶ added in v0.6.0
type IssueMetadata struct {
ID int64
ProjectID int64
EraID int64
Number int
Key string
Type string
Title string
Priority string
Effort *int
State string
Revision int
CreatedAt time.Time
UpdatedAt time.Time
}
IssueMetadata is the bounded projection returned by Query. It intentionally excludes descriptions and custom fields; callers can use Key and Revision to retrieve and identify a complete issue snapshot when needed.
type QueryPage ¶ added in v0.6.0
type QueryPage struct {
Issues []IssueMetadata
Limit int
After int
HasMore bool
NextAfter *int
}
QueryPage is one deterministic ascending issue-number page. NextAfter is nil when HasMore is false.
type QueryParams ¶ added in v0.6.0
type QueryParams struct {
Project string
Type string
State string
Priority string
Limit int
After int
}
QueryParams selects a bounded metadata-only issue page. After is an exclusive issue-number cursor. Pages are deliberately not snapshot-isolated: concurrent writes can affect subsequent pages.
type Recovery ¶ added in v0.7.0
type Recovery struct {
Project struct {
Name string `json:"name"`
Key string `json:"key"`
Revision int `json:"revision"`
Status string `json:"status"`
} `json:"project"`
Issue RecoveryIssue `json:"issue"`
Description RecoveryExcerpt `json:"description"`
Fields RecoveryExcerpt `json:"fields"`
Authorization string `json:"authorization"`
Notice string `json:"notice"`
TextLimit int `json:"textLimit"`
Links struct {
Items []RecoveryLink `json:"items"`
Limit int `json:"limit"`
After int64 `json:"after"`
HasMore bool `json:"hasMore"`
NextAfter *int64 `json:"nextAfter"`
} `json:"links"`
Executions struct {
Items []RecoveryExecution `json:"items"`
Limit int `json:"limit"`
Before int64 `json:"before"`
HasMore bool `json:"hasMore"`
NextBefore *int64 `json:"nextBefore"`
} `json:"executions"`
Omissions []string `json:"omissions"`
}
Recovery combines bounded recorded sources in one read snapshot. It does not decide whether work is authorized, complete, blocked, or safe to resume.
type RecoveryExcerpt ¶ added in v0.7.0
type RecoveryExcerpt struct {
Field string `json:"field"`
Text string `json:"text"`
TotalBytes int `json:"totalBytes"`
ReturnedBytes int `json:"returnedBytes"`
Truncated bool `json:"truncated"`
}
RecoveryExcerpt is a verbatim UTF-8 prefix, never a semantic summary. Field identifies the path in the full record returned by its source command.
type RecoveryExecution ¶ added in v0.7.0
type RecoveryExecution struct {
ID int64 `json:"id"`
StartedAt string `json:"startedAt"`
Actor string `json:"actor"`
Executor RecoveryExcerpt `json:"executor"`
Ownership RecoveryExcerpt `json:"ownership"`
Purpose string `json:"purpose"`
IndependentReviewer bool `json:"independentReviewer"`
ReviewerRoleStatus string `json:"reviewerRoleStatus,omitempty"`
Finish *RecoveryFinish `json:"finish"`
FullRecord []string `json:"fullRecord"`
}
type RecoveryFinish ¶ added in v0.7.0
type RecoveryFinish struct {
Outcome string `json:"outcome"`
FinishedAt string `json:"finishedAt"`
Evidence RecoveryExcerpt `json:"evidence"`
}
type RecoveryIssue ¶ added in v0.7.0
type RecoveryIssue struct {
ID int64 `json:"id"`
Key string `json:"key"`
Revision int `json:"revision"`
EraID int64 `json:"eraId"`
Archived bool `json:"archived"`
Type string `json:"type"`
State string `json:"state"`
Effort *int `json:"effort"`
EffortAssessment EffortAssessment `json:"effortAssessment"`
Terminal *bool `json:"terminal"`
ContractID string `json:"contractId"`
ContractVersion int `json:"contractVersion"`
Title RecoveryExcerpt `json:"title"`
FullRecord []string `json:"fullRecord"`
}
type RecoveryLink ¶ added in v0.7.0
type RecoveryLink struct {
ID int64 `json:"id"`
Kind string `json:"kind"`
Source string `json:"source"`
Target string `json:"target"`
Issue RecoveryIssue `json:"issue"`
}
type RecoveryParams ¶ added in v0.7.0
type RecoveryParams struct {
Project, Key string
Limit, TextLimit int
AfterLink, BeforeExecution int64
}
RecoveryParams bounds direct context; cursors are independent of each other. Links ascend by ID, executions descend by ID (zero starts at the newest).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store owns issue persistence in the shared Pitcrew database.
func OpenReadOnly ¶ added in v0.6.0
OpenReadOnly opens an existing, fully migrated issue store without applying technical migrations. It is used by metadata-only query paths.
func (*Store) Query ¶ added in v0.6.0
Query returns a bounded metadata-only page for one project. Filters are exact contract identifiers validated against the project's active contract. It intentionally includes every persisted issue snapshot in the project, matching List's historical scope.
func (*Store) Recover ¶ added in v0.7.0
Recover does not initialize storage or migrate it when used with OpenReadOnly. SQL limits row counts and free-text excerpts transferred out of SQLite. Identifiers and full-record references remain complete, so total output bytes are not capped. CAST AS BLOB counts embedded NUL bytes too; partial UTF-8 runes are removed at the boundary.
func (*Store) SetTrackerClientFactory ¶ added in v0.30.0
func (s *Store) SetTrackerClientFactory(factory func(context.Context, string, tracker.Config) (tracker.Client, error))
SetTrackerClientFactory replaces only the remote boundary for embedded callers and tests.
func (*Store) Transition ¶
func (s *Store) Transition(ctx context.Context, projectReference, key, targetState string) (Issue, error)
Transition moves an issue along one transition declared by its contract.
func (*Store) TransitionAs ¶
func (s *Store) TransitionAs(ctx context.Context, projectReference, key, targetState, actorID string) (Issue, error)
TransitionAs moves an issue and attributes the mutation to actorID.
func (*Store) TransitionWithDecisionAs ¶ added in v0.24.0
func (s *Store) TransitionWithDecisionAs(ctx context.Context, projectReference, key, targetState, approvalDecision, actorID string) (Issue, error)
TransitionWithDecisionAs records an explicit decision when resolving an issue from the shared pending-approval state. Actor identity remains attribution, not authorization.
type UpdateParams ¶
type UpdateParams struct {
Project string
Key string
Title *string
Description *string
Priority *string
Fields map[string]any
Actor string
// Effort is nil when unchanged, points to nil when cleared, or points to a value when set.
Effort **int
}
UpdateParams defines a partial issue update.
type ValidationError ¶
type ValidationError struct {
Code string `json:"code"`
Path string `json:"path,omitempty"`
Message string `json:"message"`
}
ValidationError describes one invalid issue value.
func ValidateSnapshot ¶
func ValidateSnapshot(definition contract.Contract, issueTypeID, priority, state string, fields map[string]any) []ValidationError
ValidateSnapshot validates a proposed persisted issue against one immutable contract definition. It is used by upgrade preflight without mutating data.
type ValidationFailure ¶
type ValidationFailure struct {
Errors []ValidationError
}
ValidationFailure reports all detected issue validation errors.
func (*ValidationFailure) Error ¶
func (e *ValidationFailure) Error() string
type WorkStart ¶ added in v0.23.0
type WorkStart struct {
From string `json:"from"`
To string `json:"to"`
Status string `json:"status"`
Reason string `json:"reason,omitempty"`
Error string `json:"error,omitempty"`
}
WorkStart records the issue-state result at an execution's start. A continued result explicitly requires later reconciliation; it never claims a transition.
func StartWorkInTransaction ¶ added in v0.23.0
func StartWorkInTransaction(ctx context.Context, tx *sql.Tx, project, key, target, actorID string) (WorkStart, error)
StartWorkInTransaction validates and persists one contract-declared edge before the caller records work. Only the ordinary in-progress convention is inferred; approval workflow decisions are never inferred, granted, or bypassed as part of starting an execution.