Add implemented state and justification to controls
Introduce `implemented` enum (IMPLEMENTED/NOT_IMPLEMENTED) and `not_implemented_justification` (nullable text) fields on the Control entity across all API surfaces (GraphQL, MCP, CLI), database, frontend, and SOA export. The database stores implementation state as a PostgreSQL enum `control_implementation_state`. Controls default to IMPLEMENTED during migration. The SOA list and PDF export show implementation status alongside applicability, with "-" for non-applicable controls. Justification columns are renamed for clarity: "Justification for non-applicability" and "Justification for non-implementation". Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -68,10 +68,12 @@ type (
|
||||
Dark string `json:"dark"`
|
||||
} `json:"logo,omitempty"`
|
||||
Controls []struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
BestPractice *bool `json:"best_practice,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
BestPractice *bool `json:"best_practice,omitempty"`
|
||||
Implemented string `json:"implemented,omitempty"`
|
||||
NotImplementedJustification *string `json:"not_implemented_justification,omitempty"`
|
||||
} `json:"controls"`
|
||||
}
|
||||
}
|
||||
@@ -573,16 +575,26 @@ func (s FrameworkService) Import(
|
||||
if control.BestPractice != nil {
|
||||
bestPractice = *control.BestPractice
|
||||
}
|
||||
implemented := coredata.ControlImplementationState(control.Implemented)
|
||||
if !implemented.IsValid() {
|
||||
implemented = coredata.ControlImplementationStateImplemented
|
||||
}
|
||||
var notImplementedJustification *string
|
||||
if implemented == coredata.ControlImplementationStateNotImplemented {
|
||||
notImplementedJustification = control.NotImplementedJustification
|
||||
}
|
||||
control := &coredata.Control{
|
||||
ID: controlID,
|
||||
FrameworkID: frameworkID,
|
||||
OrganizationID: organization.ID,
|
||||
SectionTitle: control.ID,
|
||||
Name: control.Name,
|
||||
Description: &description,
|
||||
BestPractice: bestPractice,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
ID: controlID,
|
||||
FrameworkID: frameworkID,
|
||||
OrganizationID: organization.ID,
|
||||
SectionTitle: control.ID,
|
||||
Name: control.Name,
|
||||
Description: &description,
|
||||
BestPractice: bestPractice,
|
||||
Implemented: implemented,
|
||||
NotImplementedJustification: notImplementedJustification,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := control.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user