poam

package
v0.16.1 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: AGPL-3.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyFilters

func ApplyFilters(query *gorm.DB, filters ListFilters) *gorm.DB

ApplyFilters applies all non-nil filters to the given GORM query and returns it.

Types

type ControlRef

type ControlRef struct {
	CatalogID uuid.UUID `json:"catalogId"`
	ControlID string    `json:"controlId"`
}

ControlRef is a typed reference to a control within a catalog.

type CreateMilestoneParams

type CreateMilestoneParams struct {
	Title                 string
	Description           string
	Status                string
	PlannedCompletionDate *time.Time
	ResponsibleParty      *string
	Remarks               *string
	OrderIndex            *int
}

CreateMilestoneParams carries all data required to create a single milestone. OrderIndex is a pointer so that callers can distinguish "not provided" (nil, auto-assign) from "explicitly set to 0" (valid 0-based position).

type CreatePoamItemParams

type CreatePoamItemParams struct {
	SspID                 uuid.UUID
	Title                 string
	Description           string
	Status                string
	SourceType            string
	PrimaryOwnerUserID    *uuid.UUID
	PlannedCompletionDate *time.Time
	AcceptanceRationale   *string
	ResourceRequired      *string
	RiskIDs               []uuid.UUID
	EvidenceIDs           []uuid.UUID
	ControlRefs           []ControlRef
	FindingIDs            []uuid.UUID
	Milestones            []CreateMilestoneParams
}

CreatePoamItemParams carries all data required to create a POAM item and its initial milestones and link records in a single transaction.

type ListFilters

type ListFilters struct {
	Status         string
	SspID          *uuid.UUID
	RiskID         *uuid.UUID
	DeadlineBefore *time.Time
	OverdueOnly    bool
	OwnerRef       *uuid.UUID
}

ListFilters holds all supported filter parameters for listing POAM items.

type MilestoneStatus

type MilestoneStatus string

MilestoneStatus represents the lifecycle state of a POAM milestone.

const (
	MilestoneStatusOpen       MilestoneStatus = "open"
	MilestoneStatusInProgress MilestoneStatus = "in-progress"
	MilestoneStatusCompleted  MilestoneStatus = "completed"
	MilestoneStatusCancelled  MilestoneStatus = "cancelled"
)

func (MilestoneStatus) IsValid

func (s MilestoneStatus) IsValid() bool

IsValid reports whether the milestone status is one of the defined constants.

type PoamItem

type PoamItem struct {
	ID                    uuid.UUID  `gorm:"type:uuid;primaryKey"                      json:"id"`
	SspID                 uuid.UUID  `gorm:"type:uuid;not null;index"                  json:"sspId"`
	Title                 string     `gorm:"not null"                                  json:"title"`
	Description           string     `                                                 json:"description"`
	Status                string     `gorm:"type:text;not null"                        json:"status"`
	SourceType            string     `gorm:"type:text;not null"                        json:"sourceType"`
	PrimaryOwnerUserID    *uuid.UUID `gorm:"type:uuid"                                 json:"primaryOwnerUserId,omitempty"`
	PlannedCompletionDate *time.Time `                                                 json:"plannedCompletionDate,omitempty"`
	CompletedAt           *time.Time `                                                 json:"completedAt,omitempty"`
	AcceptanceRationale   *string    `                                                 json:"acceptanceRationale,omitempty"`
	// ResourceRequired is a free-text planning field describing effort or budget needed.
	// Point-of-contact identity is expressed via PrimaryOwnerUserID (a FK to the users table)
	// rather than free-text poc_name/poc_email fields.
	ResourceRequired   *string   `gorm:"type:text" json:"resourceRequired,omitempty"`
	LastStatusChangeAt time.Time `gorm:"not null"                                  json:"lastStatusChangeAt"`
	CreatedAt          time.Time `                                                 json:"createdAt"`
	UpdatedAt          time.Time `                                                 json:"updatedAt"`

	// Associations — loaded on demand via Preload.
	Milestones    []PoamItemMilestone    `gorm:"foreignKey:PoamItemID;constraint:OnDelete:CASCADE" json:"milestones,omitempty"`
	RiskLinks     []PoamItemRiskLink     `gorm:"foreignKey:PoamItemID;constraint:OnDelete:CASCADE" json:"riskLinks,omitempty"`
	EvidenceLinks []PoamItemEvidenceLink `gorm:"foreignKey:PoamItemID;constraint:OnDelete:CASCADE" json:"evidenceLinks,omitempty"`
	ControlLinks  []PoamItemControlLink  `gorm:"foreignKey:PoamItemID;constraint:OnDelete:CASCADE" json:"controlLinks,omitempty"`
	FindingLinks  []PoamItemFindingLink  `gorm:"foreignKey:PoamItemID;constraint:OnDelete:CASCADE" json:"findingLinks,omitempty"`
}

PoamItem is the primary GORM model for a POAM item. Field names follow the Confluence design doc (v15).

func (*PoamItem) BeforeCreate

func (p *PoamItem) BeforeCreate(_ *gorm.DB) error

BeforeCreate auto-assigns a UUID and validates enum fields.

func (PoamItem) TableName

func (PoamItem) TableName() string

TableName returns the physical table name.

type PoamItemControlLink struct {
	PoamItemID uuid.UUID `gorm:"type:uuid;primaryKey"             json:"poamItemId"`
	CatalogID  uuid.UUID `gorm:"type:uuid;primaryKey;index"       json:"catalogId"`
	ControlID  string    `gorm:"type:text;not null;primaryKey"    json:"controlId"`
	CreatedAt  time.Time `                                        json:"createdAt"`
	PoamItem   *PoamItem `json:"-" gorm:"foreignKey:PoamItemID;references:ID;constraint:OnDelete:CASCADE"`
}

PoamItemControlLink is the join table linking PoamItems to Controls. CatalogID/ControlID have no DB-level FK (same cross-context reasoning as PoamItemRiskLink).

func (PoamItemControlLink) TableName

func (PoamItemControlLink) TableName() string

TableName returns the physical table name.

type PoamItemEvidenceLink struct {
	PoamItemID uuid.UUID `gorm:"type:uuid;primaryKey"       json:"poamItemId"`
	EvidenceID uuid.UUID `gorm:"type:uuid;primaryKey;index" json:"evidenceId"`
	CreatedAt  time.Time `                                  json:"createdAt"`
	PoamItem   *PoamItem `json:"-" gorm:"foreignKey:PoamItemID;references:ID;constraint:OnDelete:CASCADE"`
}

PoamItemEvidenceLink is the join table linking PoamItems to Evidence records. EvidenceID has no DB-level FK (same cross-context reasoning as PoamItemRiskLink).

func (PoamItemEvidenceLink) TableName

func (PoamItemEvidenceLink) TableName() string

TableName returns the physical table name.

type PoamItemFindingLink struct {
	PoamItemID uuid.UUID `gorm:"type:uuid;primaryKey"       json:"poamItemId"`
	FindingID  uuid.UUID `gorm:"type:uuid;primaryKey;index" json:"findingId"`
	CreatedAt  time.Time `                                  json:"createdAt"`
	PoamItem   *PoamItem `json:"-" gorm:"foreignKey:PoamItemID;references:ID;constraint:OnDelete:CASCADE"`
}

PoamItemFindingLink is the join table linking PoamItems to Findings. FindingID has no DB-level FK (same cross-context reasoning as PoamItemRiskLink).

func (PoamItemFindingLink) TableName

func (PoamItemFindingLink) TableName() string

TableName returns the physical table name.

type PoamItemMilestone

type PoamItemMilestone struct {
	ID                    uuid.UUID  `gorm:"type:uuid;primaryKey"     json:"id"`
	PoamItemID            uuid.UUID  `gorm:"type:uuid;index;not null" json:"poamItemId"`
	Title                 string     `gorm:"not null"                 json:"title"`
	Description           string     `                                json:"description"`
	Status                string     `gorm:"type:text;not null"       json:"status"`
	PlannedCompletionDate *time.Time `                                json:"plannedCompletionDate,omitempty"`
	CompletionDate        *time.Time `                                json:"completionDate,omitempty"`
	ResponsibleParty      *string    `                                json:"responsibleParty,omitempty"`
	Remarks               *string    `                                json:"remarks,omitempty"`
	OrderIndex            int        `gorm:"not null;default:0"       json:"orderIndex"`
	CreatedAt             time.Time  `                                json:"createdAt"`
	UpdatedAt             time.Time  `                                json:"updatedAt"`
}

PoamItemMilestone is a strong-typed milestone entry for a PoamItem. Field names follow the Confluence design doc (v15).

func (*PoamItemMilestone) BeforeCreate

func (m *PoamItemMilestone) BeforeCreate(_ *gorm.DB) error

BeforeCreate auto-assigns a UUID and validates enum fields.

func (PoamItemMilestone) TableName

func (PoamItemMilestone) TableName() string

TableName returns the physical table name.

type PoamItemRiskLink struct {
	PoamItemID uuid.UUID `gorm:"type:uuid;primaryKey"       json:"poamItemId"`
	RiskID     uuid.UUID `gorm:"type:uuid;primaryKey;index" json:"riskId"`
	CreatedAt  time.Time `                                  json:"createdAt"`
	PoamItem   *PoamItem `json:"-" gorm:"foreignKey:PoamItemID;references:ID;constraint:OnDelete:CASCADE"`
}

PoamItemRiskLink is the join table linking PoamItems to Risks. Uses a composite primary key and OnDelete:CASCADE to match the Risk service link table pattern (e.g., risk_evidence_links).

Note: only the PoamItem side carries a DB-level FK constraint. The RiskID column intentionally has no FK back to the risks table because Risks live in a separate bounded context. Referential integrity on the Risk side is enforced at the application layer (EnsureExists checks before link creation).

func (PoamItemRiskLink) TableName

func (PoamItemRiskLink) TableName() string

TableName returns the physical table name.

type PoamItemSourceType

type PoamItemSourceType string

PoamItemSourceType describes how a POAM item was created.

const (
	PoamItemSourceTypeManual        PoamItemSourceType = "manual"
	PoamItemSourceTypeRiskPromotion PoamItemSourceType = "risk-promotion"
	PoamItemSourceTypeImport        PoamItemSourceType = "import"
)

func (PoamItemSourceType) IsValid

func (s PoamItemSourceType) IsValid() bool

IsValid reports whether the source type value is one of the defined constants.

type PoamItemStatus

type PoamItemStatus string

PoamItemStatus represents the lifecycle state of a POAM item.

const (
	PoamItemStatusOpen       PoamItemStatus = "open"
	PoamItemStatusInProgress PoamItemStatus = "in-progress"
	PoamItemStatusCompleted  PoamItemStatus = "completed"
	PoamItemStatusOverdue    PoamItemStatus = "overdue"
)

func (PoamItemStatus) IsValid

func (s PoamItemStatus) IsValid() bool

IsValid reports whether the status value is one of the defined constants.

type PoamService

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

PoamService encapsulates all database operations for POAM items and their sub-resources. Handlers must not import gorm directly; all persistence is delegated here.

func NewPoamService

func NewPoamService(db *gorm.DB) *PoamService

NewPoamService constructs a PoamService backed by the given *gorm.DB.

func (s *PoamService) AddControlLink(poamItemID uuid.UUID, ref ControlRef) (*PoamItemControlLink, error)

AddControlLink creates a control link for the given POAM item. Duplicate links are silently ignored.

func (s *PoamService) AddEvidenceLink(poamItemID, evidenceID uuid.UUID) (*PoamItemEvidenceLink, error)

AddEvidenceLink creates an evidence link for the given POAM item. Duplicate links are silently ignored.

func (s *PoamService) AddFindingLink(poamItemID, findingID uuid.UUID) (*PoamItemFindingLink, error)

AddFindingLink creates a finding link for the given POAM item. Duplicate links are silently ignored.

func (*PoamService) AddMilestone

func (s *PoamService) AddMilestone(poamItemID uuid.UUID, params CreateMilestoneParams) (*PoamItemMilestone, error)

AddMilestone inserts a new milestone for the given POAM item.

func (s *PoamService) AddRiskLink(poamItemID, riskID uuid.UUID) (*PoamItemRiskLink, error)

AddRiskLink creates a risk link for the given POAM item. Duplicate links are silently ignored (ON CONFLICT DO NOTHING), matching the Risk service pattern.

func (*PoamService) Create

func (s *PoamService) Create(params CreatePoamItemParams) (*PoamItem, error)

Create inserts a new POAM item together with its initial milestones and all link records inside a single database transaction.

func (*PoamService) CreateWithTx added in v0.15.0

func (s *PoamService) CreateWithTx(tx *gorm.DB, params CreatePoamItemParams) (*PoamItem, error)

CreateWithTx inserts a new POAM item and its milestones/links within an externally-managed *gorm.DB transaction. The caller is responsible for committing or rolling back the transaction. This is used by cross-context operations such as RiskService.PromoteToPoam that need atomicity across multiple bounded contexts.

NOTE: This method only processes Milestones and RiskIDs from CreatePoamItemParams. EvidenceIDs, ControlRefs, and FindingIDs present in the params struct are intentionally ignored — this method is scoped to the risk-promotion use case. Use the full Create method for general POAM item creation with all link types.

func (*PoamService) Delete

func (s *PoamService) Delete(id uuid.UUID) error

Delete removes a POAM item and all its dependent records (milestones, all four link tables) inside a single transaction.

func (s *PoamService) DeleteControlLink(poamItemID, catalogID uuid.UUID, controlID string) error

DeleteControlLink removes the control link identified by (poamItemID, catalogID, controlID).

func (s *PoamService) DeleteEvidenceLink(poamItemID, evidenceID uuid.UUID) error

DeleteEvidenceLink removes the evidence link identified by (poamItemID, evidenceID).

func (s *PoamService) DeleteFindingLink(poamItemID, findingID uuid.UUID) error

DeleteFindingLink removes the finding link identified by (poamItemID, findingID).

func (*PoamService) DeleteMilestone

func (s *PoamService) DeleteMilestone(poamItemID, milestoneID uuid.UUID) error

DeleteMilestone removes the milestone identified by (poamItemID, milestoneID). Returns gorm.ErrRecordNotFound when the milestone does not exist or does not belong to the given POAM item.

func (s *PoamService) DeleteRiskLink(poamItemID, riskID uuid.UUID) error

DeleteRiskLink removes the risk link identified by (poamItemID, riskID). Returns gorm.ErrRecordNotFound when the link does not exist.

func (*PoamService) EnsureExists

func (s *PoamService) EnsureExists(id uuid.UUID) error

EnsureExists returns nil if a POAM item with the given id exists, or gorm.ErrRecordNotFound if it does not.

func (*PoamService) EnsureSSPExists

func (s *PoamService) EnsureSSPExists(id uuid.UUID) error

EnsureSSPExists returns nil if an SSP with the given id exists, or gorm.ErrRecordNotFound if it does not.

func (*PoamService) GetByID

func (s *PoamService) GetByID(id uuid.UUID) (*PoamItem, error)

GetByID fetches a single POAM item by its UUID, preloading milestones ordered by order_index ascending.

func (*PoamService) List

func (s *PoamService) List(filters ListFilters) ([]PoamItem, error)

List returns all POAM items matching the given filters.

func (s *PoamService) ListControlLinks(poamItemID uuid.UUID) ([]PoamItemControlLink, error)

ListControlLinks returns all control link records for the given POAM item.

func (s *PoamService) ListEvidenceLinks(poamItemID uuid.UUID) ([]PoamItemEvidenceLink, error)

ListEvidenceLinks returns all evidence link records for the given POAM item.

func (s *PoamService) ListFindingLinks(poamItemID uuid.UUID) ([]PoamItemFindingLink, error)

ListFindingLinks returns all finding link records for the given POAM item.

func (*PoamService) ListMilestones

func (s *PoamService) ListMilestones(poamItemID uuid.UUID) ([]PoamItemMilestone, error)

ListMilestones returns all milestones for the given POAM item, ordered by order_index ascending.

func (s *PoamService) ListRiskLinks(poamItemID uuid.UUID) ([]PoamItemRiskLink, error)

ListRiskLinks returns all risk link records for the given POAM item.

func (*PoamService) Update

func (s *PoamService) Update(id uuid.UUID, params UpdatePoamItemParams) (*PoamItem, error)

Update applies non-nil scalar fields from params to the POAM item identified by id, and processes any link add/remove operations — all inside a single transaction. This follows the Risk service pattern: fetch the current record, mutate the struct, then call tx.Save() rather than using a raw map.

last_status_change_at is stamped only when the status actually changes. completed_at is set automatically when status transitions to "completed" and cleared if status moves away from "completed". It is not settable via params.

func (*PoamService) UpdateMilestone

func (s *PoamService) UpdateMilestone(poamItemID, milestoneID uuid.UUID, params UpdateMilestoneParams) (*PoamItemMilestone, error)

UpdateMilestone applies non-nil fields from params to the milestone identified by (poamItemID, milestoneID). When status transitions to "completed", completion_date is set automatically. Returns gorm.ErrRecordNotFound when the milestone does not belong to the given POAM item.

type UpdateMilestoneParams

type UpdateMilestoneParams struct {
	Title                 *string
	Description           *string
	Status                *string
	PlannedCompletionDate *time.Time
	ResponsibleParty      *string
	Remarks               *string
	OrderIndex            *int
}

UpdateMilestoneParams carries the fields that may be patched on an existing milestone. Only non-nil pointer fields are applied.

type UpdatePoamItemParams

type UpdatePoamItemParams struct {
	Title                 *string
	Description           *string
	Status                *string
	PrimaryOwnerUserID    *uuid.UUID
	PlannedCompletionDate *time.Time
	AcceptanceRationale   *string
	// Link management — applied inside the same transaction as the scalar update.
	AddRiskIDs        []uuid.UUID
	RemoveRiskIDs     []uuid.UUID
	AddEvidenceIDs    []uuid.UUID
	RemoveEvidenceIDs []uuid.UUID
	AddControlRefs    []ControlRef
	RemoveControlRefs []ControlRef
	AddFindingIDs     []uuid.UUID
	RemoveFindingIDs  []uuid.UUID
}

UpdatePoamItemParams carries the fields that may be patched on an existing POAM item. Only non-nil pointer fields are applied. Link slices use explicit add/remove semantics so callers can manage associations in one call.

Jump to

Keyboard shortcuts

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