ctemcycle

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2026 License: GPL-3.0 Imports: 3 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MetricMTTRHours          = "mttr_hours"
	MetricFindingsOpened     = "findings_opened"
	MetricFindingsResolved   = "findings_resolved"
	MetricPClassChurn        = "p_class_churn"       // count of priority transitions during the cycle
	MetricValidationCoverage = "validation_coverage" // % of closed findings with validation evidence
	MetricScopeDriftSize     = "scope_drift_size"
)

Cycle-level metric types used in the `ctem_cycle_metrics` table. These are the minimum set the review phase produces; the handler can add more without changing this contract — metric_type is just a string in the table.

Variables

This section is empty.

Functions

This section is empty.

Types

type Charter

type Charter struct {
	BusinessPriorities []string `json:"business_priorities"`
	RiskAppetite       string   `json:"risk_appetite"`
	InScopeServices    []string `json:"in_scope_services"`
	Objectives         []string `json:"objectives"`
}

Charter holds the business context for a CTEM cycle.

type Cycle

type Cycle struct {
	// contains filtered or unexported fields
}

Cycle represents a CTEM assessment cycle.

func NewCycle

func NewCycle(tenantID shared.ID, name string, createdBy shared.ID) (*Cycle, error)

NewCycle creates a new CTEM cycle in planning status.

func ReconstituteCycle

func ReconstituteCycle(data CycleData) *Cycle

ReconstituteCycle recreates from persistence.

func (*Cycle) Activate

func (c *Cycle) Activate() error

Activate transitions from planning to active. This should trigger scope snapshot creation externally.

func (*Cycle) Charter

func (c *Cycle) Charter() Charter

func (*Cycle) Close

func (c *Cycle) Close(closedBy shared.ID) error

Close transitions from review to closed. Metrics should be computed externally and stored in ctem_cycle_metrics.

func (*Cycle) CreatedAt

func (c *Cycle) CreatedAt() time.Time

func (*Cycle) CreatedBy

func (c *Cycle) CreatedBy() shared.ID

func (*Cycle) EndDate

func (c *Cycle) EndDate() *time.Time

func (*Cycle) ID

func (c *Cycle) ID() shared.ID

Getters

func (*Cycle) IsActive

func (c *Cycle) IsActive() bool

IsActive returns true if the cycle is in active status.

func (*Cycle) Name

func (c *Cycle) Name() string

func (*Cycle) SetCharter

func (c *Cycle) SetCharter(charter Charter) error

SetCharter updates the cycle charter (only in planning status).

func (*Cycle) SetDates

func (c *Cycle) SetDates(start, end time.Time) error

SetDates sets the cycle start/end dates.

func (*Cycle) StartDate

func (c *Cycle) StartDate() *time.Time

func (*Cycle) StartReview

func (c *Cycle) StartReview() error

StartReview transitions from active to review.

func (*Cycle) Status

func (c *Cycle) Status() CycleStatus

func (*Cycle) TenantID

func (c *Cycle) TenantID() shared.ID

type CycleData

type CycleData struct {
	ID        shared.ID
	TenantID  shared.ID
	Name      string
	Status    CycleStatus
	StartDate *time.Time
	EndDate   *time.Time
	Charter   Charter
	ClosedBy  *shared.ID
	ClosedAt  *time.Time
	CreatedBy shared.ID
	CreatedAt time.Time
	UpdatedAt time.Time
}

CycleData is the persistence representation.

type CycleMetric

type CycleMetric struct {
	MetricType string
	Value      float64
	ComputedAt time.Time
}

CycleMetric holds a computed metric for a cycle.

type CycleStatus

type CycleStatus string

CycleStatus represents the lifecycle status of a CTEM cycle.

const (
	CycleStatusPlanning CycleStatus = "planning"
	CycleStatusActive   CycleStatus = "active"
	CycleStatusReview   CycleStatus = "review"
	CycleStatusClosed   CycleStatus = "closed"
)

type ReviewSnapshot

type ReviewSnapshot struct {
	CycleID              shared.ID
	TenantID             shared.ID
	Delta                ScopeDelta
	FindingsToRevalidate []shared.ID
	ComputedAt           time.Time
}

ReviewSnapshot bundles everything the handler computes on transition into review. Persisting this record gives the reviewer a deterministic view of the cycle outcome.

func NewReviewSnapshot

func NewReviewSnapshot(cycleID, tenantID shared.ID) ReviewSnapshot

NewReviewSnapshot builds an empty snapshot for a cycle at a given moment. Callers fill Delta and FindingsToRevalidate via the handler's SQL computations.

type ScopeChangeEvent

type ScopeChangeEvent struct {
	CycleID  shared.ID
	TenantID shared.ID
	AssetID  shared.ID
	Kind     ScopeChangeKind
	At       time.Time
	// Reason is a short string for audit / UI ("asset created",
	// "asset decommissioned", "business service membership
	// changed").
	Reason string
}

ScopeChangeEvent is the in-memory domain shape. Emitted by the assets service + consumed by the cycle handler.

func (ScopeChangeEvent) Validate

func (e ScopeChangeEvent) Validate() error

Validate ensures required fields are set.

type ScopeChangeKind

type ScopeChangeKind string

ScopeChangeKind enumerates what happened.

const (
	ScopeChangeAdded   ScopeChangeKind = "added"
	ScopeChangeRemoved ScopeChangeKind = "removed"
)

type ScopeDelta

type ScopeDelta struct {
	// AddedAssetIDs are assets that NOW match the cycle's scope
	// targets but were not in the frozen snapshot (created or
	// retagged during the active phase).
	AddedAssetIDs []shared.ID
	// RemovedAssetIDs are assets that were in the frozen snapshot
	// but no longer exist or no longer match the scope (deleted,
	// decommissioned, untagged).
	RemovedAssetIDs []shared.ID
	// UnchangedCount is the number of assets in both sets. Kept as
	// a count (not a list) because it is typically the vast majority
	// and we do not need the IDs.
	UnchangedCount int
	// ComputedAt is the wall-clock time the delta was produced.
	// Exposed to the UI so reviewers know the freshness.
	ComputedAt time.Time
}

ScopeDelta describes the difference between a cycle's frozen scope snapshot and the current tenant asset set.

func (ScopeDelta) IsEmpty

func (d ScopeDelta) IsEmpty() bool

IsEmpty returns true when the snapshot matches the current scope exactly — no assets added, none removed.

func (ScopeDelta) Size

func (d ScopeDelta) Size() int

Size returns the total magnitude of the delta (added + removed). Used by the UI to show a single "scope drift" badge without exposing the full lists.

type ScopeDeltaRollup

type ScopeDeltaRollup struct {
	CycleID         shared.ID
	AddedAssets     []shared.ID
	RemovedAssets   []shared.ID
	AddedByReason   map[string]int
	RemovedByReason map[string]int
	ComputedAt      time.Time
}

ScopeDeltaRollup aggregates a batch of ScopeChangeEvents for display. The cycle-review endpoint returns this so the UI shows "during this cycle so far: +12 assets, -3 assets".

func RollupChanges

func RollupChanges(cycleID shared.ID, events []ScopeChangeEvent) ScopeDeltaRollup

RollupChanges folds a sequence of ScopeChangeEvents into a ScopeDeltaRollup. Malformed events (validation fails) are skipped, not fatal — the rollup is best-effort aggregation for the UI.

func (ScopeDeltaRollup) IsEmpty

func (r ScopeDeltaRollup) IsEmpty() bool

IsEmpty returns true when no added/removed events contributed.

func (ScopeDeltaRollup) Size

func (r ScopeDeltaRollup) Size() int

Size returns the absolute drift magnitude.

Jump to

Keyboard shortcuts

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