ticket

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package ticket computes and applies ticket-source synchronization plans: comparing a requirement's rollup CANARY status against its owning non-flatfile source's remote status (proposing "transition" actions), and codifying flatfile-to-ticket promotion as paired "create_issue" + "remap" actions. Plan computation (ComputePlan) is pure and side-effect free; JiraClient (jira.go) is the only piece that talks to the network, and only when the CLI layer (pkg/cmds/ticket) is told to --apply. CANARY: REQ=CP-279; FEATURE="TicketSync"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_CBIN_306_ComputePlan_FlatfileCreateAndRemapPairing,TestCANARY_CBIN_306_ComputePlan_FlatfileNoNonFlatfileSource_NoAction,TestCANARY_CBIN_306_ComputePlan_JiraStatusMismatch_Transition,TestCANARY_CBIN_306_ComputePlan_MatchingStatus_NoAction,TestCANARY_CBIN_306_ComputePlan_EmptyRemoteStatus_AllTransitionsProposed,TestCANARY_CBIN_306_ComputePlan_StatusMapOverrideHonored,TestCANARY_CBIN_306_ComputePlan_RollupIsWorstOfTokens,TestCANARY_CBIN_306_ComputePlan_UnresolvedPrefixSkipped,TestCANARY_CBIN_306_ComputePlan_DeterministicOrdering,TestCANARY_CBIN_306_RollupStatus; UPDATED=2026-08-29 CANARY: REQ=ENG-3958; FEATURE="TicketDestination"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_ENG_3958_ComputePlan_CreateIssueStampsDestinationProject,TestCANARY_ENG_3958_ComputePlan_CreateIssueProjectEmptyWhenDestinationUnset; UPDATED=2026-08-29

Index

Constants

This section is empty.

Variables

View Source
var DefaultStatusMap = map[string]string{
	"STUB":    "To Do",
	"IMPL":    "In Progress",
	"TESTED":  "Done",
	"BENCHED": "Done",
}

DefaultStatusMap is the CANARY-status -> remote-status-name mapping used when a source's StatusMap doesn't override a given status.

Functions

func FetchRemoteStatus

func FetchRemoteStatus(c *JiraClient, project string) (map[string]string, error)

FetchRemoteStatus pages through JIRA's search endpoint (GET /rest/api/3/search) for every issue in project, returning a map of issue key -> current status name. Used only under `--apply`, immediately before ComputePlan, so transition actions are proposed against real remote state.

func RollupStatus

func RollupStatus(tokens []*storage.Token) string

RollupStatus returns the worst (least advanced) status among tokens per STUB < IMPL < TESTED < BENCHED. Tokens with an unrecognized status are ignored. An empty slice, or a slice with no recognized statuses, returns "".

Types

type Action

type Action struct {
	Type        string `json:"type"`              // create_issue | transition | remap
	ReqID       string `json:"req_id,omitempty"`  // the CANARY requirement ID this action concerns
	Issue       string `json:"issue,omitempty"`   // remote issue key; "" on a pending remap until applied
	To          string `json:"to,omitempty"`      // JIRA status name (transition target)
	Summary     string `json:"summary,omitempty"` // for create_issue
	Description string `json:"description,omitempty"`
	Source      string `json:"source"`            // owning source's Name
	Project     string `json:"project,omitempty"` // create_issue only: the destination source's Project (empty if unset)
}

Action is one proposed (or, once applied, completed) ticket-sync operation.

func ComputePlan

func ComputePlan(tokens []*storage.Token, reg *sources.Registry, remoteStatus map[string]string) ([]Action, error)

ComputePlan computes the deterministic, pure set of proposed sync actions.

tokens are grouped by ReqID; reg resolves each requirement's owning source; remoteStatus maps a non-flatfile issue key to its current remote status name (nil or empty means "unknown" — every eligible transition is then proposed, since no remote state contradicts it).

Rules:

  • A requirement owned by a non-flatfile source gets a "transition" action when its rollup status (RollupStatus: worst of its tokens, STUB<IMPL<TESTED<BENCHED), mapped through the source's StatusMap (falling back to DefaultStatusMap), differs from remoteStatus[reqID].
  • A requirement owned by a flatfile source gets a paired "create_issue"
  • "remap" action, but only when the registry configures at least one non-flatfile source — otherwise there's nothing to promote it to. The create_issue's Summary is "<ReqID>: <primary feature>"; Description is a bounded feature/aspect/status/file list. The paired remap's Issue is left "" — the apply step fills in the created key.
  • A requirement whose prefix resolves to no configured source is skipped.

Ordering is deterministic: requirements are visited in sorted ReqID order; a flatfile requirement's create_issue action is immediately followed by its paired remap action.

type JiraClient

type JiraClient struct {
	BaseURL string
	Email   string
	Token   string

	// HTTPClient lets tests point the client at an httptest server with a
	// short timeout; nil defaults to a client with a bounded timeout.
	HTTPClient *http.Client
}

JiraClient talks to the JIRA Cloud REST API (v3) using basic auth (email + API token). Every method is safe for concurrent use. CANARY: REQ=CP-279; FEATURE="TicketSync"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_CBIN_306_JiraClient_CreateIssue,TestCANARY_CBIN_306_JiraClient_CreateIssue_ErrorStatus,TestCANARY_CBIN_306_JiraClient_TransitionIssue_ResolvesIDByName,TestCANARY_CBIN_306_JiraClient_TransitionIssue_NoMatch,TestCANARY_CBIN_306_FetchRemoteStatus_Paged; UPDATED=2026-08-29

func (*JiraClient) CreateIssue

func (c *JiraClient) CreateIssue(project, issueType, summary, description string) (string, error)

CreateIssue creates a new issue of issueType in project with summary and description (wrapped as an ADF paragraph), returning the created issue's key (e.g. "CP-12").

func (*JiraClient) TransitionIssue

func (c *JiraClient) TransitionIssue(key, toStatusName string) error

TransitionIssue moves key to the transition whose target status name (transitions[].to.name) matches toStatusName case-insensitively.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL