Rename NONCONFORMITY to MINOR_NONCONFORMITY and add MAJOR_NONCONFORMITY
Support distinguishing between minor and major non-conformities in findings. Rename the existing NONCONFORMITY enum value to MINOR_NONCONFORMITY and add a new MAJOR_NONCONFORMITY value across all API layers (GraphQL, MCP, CLI) and the database. Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -131,8 +131,10 @@ type Props = {
|
|||||||
|
|
||||||
function getKindLabel(kind: string, __: (s: string) => string): string {
|
function getKindLabel(kind: string, __: (s: string) => string): string {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case "NONCONFORMITY":
|
case "MINOR_NONCONFORMITY":
|
||||||
return __("Nonconformity");
|
return __("Minor nonconformity");
|
||||||
|
case "MAJOR_NONCONFORMITY":
|
||||||
|
return __("Major nonconformity");
|
||||||
case "OBSERVATION":
|
case "OBSERVATION":
|
||||||
return __("Observation");
|
return __("Observation");
|
||||||
case "EXCEPTION":
|
case "EXCEPTION":
|
||||||
|
|||||||
@@ -271,7 +271,8 @@ export default function FindingsPage({ queryRef }: FindingsPageProps) {
|
|||||||
onValueChange={handleKindFilterChange}
|
onValueChange={handleKindFilterChange}
|
||||||
>
|
>
|
||||||
<Option value="ALL">{__("All kinds")}</Option>
|
<Option value="ALL">{__("All kinds")}</Option>
|
||||||
<Option value="NONCONFORMITY">{__("Nonconformity")}</Option>
|
<Option value="MINOR_NONCONFORMITY">{__("Minor nonconformity")}</Option>
|
||||||
|
<Option value="MAJOR_NONCONFORMITY">{__("Major nonconformity")}</Option>
|
||||||
<Option value="OBSERVATION">{__("Observation")}</Option>
|
<Option value="OBSERVATION">{__("Observation")}</Option>
|
||||||
<Option value="EXCEPTION">{__("Exception")}</Option>
|
<Option value="EXCEPTION">{__("Exception")}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -366,8 +367,10 @@ export default function FindingsPage({ queryRef }: FindingsPageProps) {
|
|||||||
|
|
||||||
function getKindLabel(kind: string, __: (s: string) => string): string {
|
function getKindLabel(kind: string, __: (s: string) => string): string {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case "NONCONFORMITY":
|
case "MINOR_NONCONFORMITY":
|
||||||
return __("Nonconformity");
|
return __("Minor nonconformity");
|
||||||
|
case "MAJOR_NONCONFORMITY":
|
||||||
|
return __("Major nonconformity");
|
||||||
case "OBSERVATION":
|
case "OBSERVATION":
|
||||||
return __("Observation");
|
return __("Observation");
|
||||||
case "EXCEPTION":
|
case "EXCEPTION":
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const createFindingMutation = graphql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
kind: z.enum(["NONCONFORMITY", "OBSERVATION", "EXCEPTION"]),
|
kind: z.enum(["MINOR_NONCONFORMITY", "MAJOR_NONCONFORMITY", "OBSERVATION", "EXCEPTION"]),
|
||||||
description: z.string().optional(),
|
description: z.string().optional(),
|
||||||
source: z.string().optional(),
|
source: z.string().optional(),
|
||||||
identifiedOn: z.string().optional(),
|
identifiedOn: z.string().optional(),
|
||||||
@@ -98,7 +98,8 @@ export function CreateFindingDialog({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const kindOptions = [
|
const kindOptions = [
|
||||||
{ value: "NONCONFORMITY", label: __("Nonconformity") },
|
{ value: "MINOR_NONCONFORMITY", label: __("Minor nonconformity") },
|
||||||
|
{ value: "MAJOR_NONCONFORMITY", label: __("Major nonconformity") },
|
||||||
{ value: "OBSERVATION", label: __("Observation") },
|
{ value: "OBSERVATION", label: __("Observation") },
|
||||||
{ value: "EXCEPTION", label: __("Exception") },
|
{ value: "EXCEPTION", label: __("Exception") },
|
||||||
];
|
];
|
||||||
@@ -111,7 +112,7 @@ export function CreateFindingDialog({
|
|||||||
|
|
||||||
const { register, handleSubmit, formState, reset, control } = useFormWithSchema(schema, {
|
const { register, handleSubmit, formState, reset, control } = useFormWithSchema(schema, {
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
kind: "NONCONFORMITY" as const,
|
kind: "MINOR_NONCONFORMITY" as const,
|
||||||
description: "",
|
description: "",
|
||||||
source: "",
|
source: "",
|
||||||
identifiedOn: "",
|
identifiedOn: "",
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func TestFinding_CreateNonconformity(t *testing.T) {
|
|||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"organizationId": owner.GetOrganizationID().String(),
|
"organizationId": owner.GetOrganizationID().String(),
|
||||||
"kind": "NONCONFORMITY",
|
"kind": "MINOR_NONCONFORMITY",
|
||||||
"description": "Unauthorized access detected",
|
"description": "Unauthorized access detected",
|
||||||
"rootCause": "Insufficient access controls",
|
"rootCause": "Insufficient access controls",
|
||||||
"correctiveAction": "Implement MFA",
|
"correctiveAction": "Implement MFA",
|
||||||
@@ -81,7 +81,7 @@ func TestFinding_CreateNonconformity(t *testing.T) {
|
|||||||
|
|
||||||
node := result.CreateFinding.FindingEdge.Node
|
node := result.CreateFinding.FindingEdge.Node
|
||||||
assert.NotEmpty(t, node.ID)
|
assert.NotEmpty(t, node.ID)
|
||||||
assert.Equal(t, "NONCONFORMITY", node.Kind)
|
assert.Equal(t, "MINOR_NONCONFORMITY", node.Kind)
|
||||||
assert.Equal(t, "Unauthorized access detected", node.Description)
|
assert.Equal(t, "Unauthorized access detected", node.Description)
|
||||||
assert.Equal(t, "Insufficient access controls", node.RootCause)
|
assert.Equal(t, "Insufficient access controls", node.RootCause)
|
||||||
assert.Equal(t, "Implement MFA", node.CorrectiveAction)
|
assert.Equal(t, "Implement MFA", node.CorrectiveAction)
|
||||||
@@ -178,7 +178,7 @@ func TestFinding_Update(t *testing.T) {
|
|||||||
err := owner.Execute(createQuery, map[string]any{
|
err := owner.Execute(createQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"organizationId": owner.GetOrganizationID().String(),
|
"organizationId": owner.GetOrganizationID().String(),
|
||||||
"kind": "NONCONFORMITY",
|
"kind": "MINOR_NONCONFORMITY",
|
||||||
"description": "Original description",
|
"description": "Original description",
|
||||||
"ownerId": profileID,
|
"ownerId": profileID,
|
||||||
"status": "OPEN",
|
"status": "OPEN",
|
||||||
@@ -330,7 +330,7 @@ func TestFinding_List(t *testing.T) {
|
|||||||
err := owner.Execute(createQuery, map[string]any{
|
err := owner.Execute(createQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"organizationId": owner.GetOrganizationID().String(),
|
"organizationId": owner.GetOrganizationID().String(),
|
||||||
"kind": "NONCONFORMITY",
|
"kind": "MINOR_NONCONFORMITY",
|
||||||
"description": fmt.Sprintf("Finding %d", i),
|
"description": fmt.Sprintf("Finding %d", i),
|
||||||
"ownerId": profileID,
|
"ownerId": profileID,
|
||||||
"status": "OPEN",
|
"status": "OPEN",
|
||||||
@@ -402,7 +402,7 @@ func TestFinding_ListWithKindFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
kinds := []string{"NONCONFORMITY", "OBSERVATION", "EXCEPTION"}
|
kinds := []string{"MINOR_NONCONFORMITY", "MAJOR_NONCONFORMITY", "OBSERVATION", "EXCEPTION"}
|
||||||
for _, kind := range kinds {
|
for _, kind := range kinds {
|
||||||
var createResult struct {
|
var createResult struct {
|
||||||
CreateFinding struct {
|
CreateFinding struct {
|
||||||
@@ -503,7 +503,7 @@ func TestFinding_CreateAuditMapping(t *testing.T) {
|
|||||||
err := owner.Execute(createQuery, map[string]any{
|
err := owner.Execute(createQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"organizationId": owner.GetOrganizationID().String(),
|
"organizationId": owner.GetOrganizationID().String(),
|
||||||
"kind": "NONCONFORMITY",
|
"kind": "MINOR_NONCONFORMITY",
|
||||||
"ownerId": profileID,
|
"ownerId": profileID,
|
||||||
"status": "OPEN",
|
"status": "OPEN",
|
||||||
"priority": "HIGH",
|
"priority": "HIGH",
|
||||||
@@ -774,7 +774,7 @@ func TestFinding_StatusAndPriorityValues(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": owner.GetOrganizationID().String(),
|
"organizationId": owner.GetOrganizationID().String(),
|
||||||
"kind": "NONCONFORMITY",
|
"kind": "MINOR_NONCONFORMITY",
|
||||||
"ownerId": profileID,
|
"ownerId": profileID,
|
||||||
"status": status,
|
"status": status,
|
||||||
"priority": "LOW",
|
"priority": "LOW",
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a new finding",
|
Short: "Create a new finding",
|
||||||
Example: ` # Create a finding
|
Example: ` # Create a finding
|
||||||
prb finding create --organization ORG_ID --kind NONCONFORMITY --owner-id OWNER_ID --status OPEN --priority HIGH`,
|
prb finding create --organization ORG_ID --kind MINOR_NONCONFORMITY --owner-id OWNER_ID --status OPEN --priority HIGH`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := cmdutil.ValidateEnum("kind", flagKind, []string{"NONCONFORMITY", "OBSERVATION", "EXCEPTION"}); err != nil {
|
if err := cmdutil.ValidateEnum("kind", flagKind, []string{"MINOR_NONCONFORMITY", "MAJOR_NONCONFORMITY", "OBSERVATION", "EXCEPTION"}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := cmdutil.ValidateEnum("status", flagStatus, []string{"OPEN", "IN_PROGRESS", "CLOSED", "RISK_ACCEPTED", "MITIGATED", "FALSE_POSITIVE"}); err != nil {
|
if err := cmdutil.ValidateEnum("status", flagStatus, []string{"OPEN", "IN_PROGRESS", "CLOSED", "RISK_ACCEPTED", "MITIGATED", "FALSE_POSITIVE"}); err != nil {
|
||||||
@@ -165,7 +165,7 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrganization, "organization", "", "Organization ID (required)")
|
cmd.Flags().StringVar(&flagOrganization, "organization", "", "Organization ID (required)")
|
||||||
cmd.Flags().StringVar(&flagKind, "kind", "", "Finding kind: NONCONFORMITY, OBSERVATION, EXCEPTION (required)")
|
cmd.Flags().StringVar(&flagKind, "kind", "", "Finding kind: MINOR_NONCONFORMITY, MAJOR_NONCONFORMITY, OBSERVATION, EXCEPTION (required)")
|
||||||
cmd.Flags().StringVar(&flagDescription, "description", "", "Finding description")
|
cmd.Flags().StringVar(&flagDescription, "description", "", "Finding description")
|
||||||
cmd.Flags().StringVar(&flagSource, "source", "", "Finding source")
|
cmd.Flags().StringVar(&flagSource, "source", "", "Finding source")
|
||||||
cmd.Flags().StringVar(&flagIdentifiedOn, "identified-on", "", "Date identified (RFC3339)")
|
cmd.Flags().StringVar(&flagIdentifiedOn, "identified-on", "", "Date identified (RFC3339)")
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
prb finding list --organization <organization-id>
|
prb finding list --organization <organization-id>
|
||||||
|
|
||||||
# Filter by kind and output as JSON
|
# Filter by kind and output as JSON
|
||||||
prb finding ls --organization <organization-id> --kind NONCONFORMITY --json`,
|
prb finding ls --organization <organization-id> --kind MINOR_NONCONFORMITY --json`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := cmdutil.ValidateOutputFlag(flagOutput); err != nil {
|
if err := cmdutil.ValidateOutputFlag(flagOutput); err != nil {
|
||||||
@@ -117,7 +117,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
filter := map[string]any{}
|
filter := map[string]any{}
|
||||||
if flagKind != "" {
|
if flagKind != "" {
|
||||||
if err := cmdutil.ValidateEnum("kind", flagKind, []string{"NONCONFORMITY", "OBSERVATION", "EXCEPTION"}); err != nil {
|
if err := cmdutil.ValidateEnum("kind", flagKind, []string{"MINOR_NONCONFORMITY", "MAJOR_NONCONFORMITY", "OBSERVATION", "EXCEPTION"}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filter["kind"] = flagKind
|
filter["kind"] = flagKind
|
||||||
@@ -200,7 +200,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
cmd.Flags().IntVarP(&flagLimit, "limit", "L", 30, "Maximum number of findings to list")
|
cmd.Flags().IntVarP(&flagLimit, "limit", "L", 30, "Maximum number of findings to list")
|
||||||
cmd.Flags().StringVar(&flagOrderBy, "order-by", "", "Order by field (CREATED_AT, REFERENCE_ID, IDENTIFIED_ON, DUE_DATE, STATUS, PRIORITY, KIND)")
|
cmd.Flags().StringVar(&flagOrderBy, "order-by", "", "Order by field (CREATED_AT, REFERENCE_ID, IDENTIFIED_ON, DUE_DATE, STATUS, PRIORITY, KIND)")
|
||||||
cmd.Flags().StringVar(&flagOrderDir, "order-direction", "DESC", "Sort direction (ASC, DESC)")
|
cmd.Flags().StringVar(&flagOrderDir, "order-direction", "DESC", "Sort direction (ASC, DESC)")
|
||||||
cmd.Flags().StringVar(&flagKind, "kind", "", "Filter by kind (NONCONFORMITY, OBSERVATION, EXCEPTION)")
|
cmd.Flags().StringVar(&flagKind, "kind", "", "Filter by kind (MINOR_NONCONFORMITY, MAJOR_NONCONFORMITY, OBSERVATION, EXCEPTION)")
|
||||||
flagOutput = cmdutil.AddOutputFlag(cmd)
|
flagOutput = cmdutil.AddOutputFlag(cmd)
|
||||||
|
|
||||||
_ = cmd.MarkFlagRequired("organization")
|
_ = cmd.MarkFlagRequired("organization")
|
||||||
|
|||||||
@@ -22,14 +22,16 @@ import (
|
|||||||
type FindingKind string
|
type FindingKind string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FindingKindNonconformity FindingKind = "NONCONFORMITY"
|
FindingKindMinorNonconformity FindingKind = "MINOR_NONCONFORMITY"
|
||||||
|
FindingKindMajorNonconformity FindingKind = "MAJOR_NONCONFORMITY"
|
||||||
FindingKindObservation FindingKind = "OBSERVATION"
|
FindingKindObservation FindingKind = "OBSERVATION"
|
||||||
FindingKindException FindingKind = "EXCEPTION"
|
FindingKindException FindingKind = "EXCEPTION"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FindingKinds() []FindingKind {
|
func FindingKinds() []FindingKind {
|
||||||
return []FindingKind{
|
return []FindingKind{
|
||||||
FindingKindNonconformity,
|
FindingKindMinorNonconformity,
|
||||||
|
FindingKindMajorNonconformity,
|
||||||
FindingKindObservation,
|
FindingKindObservation,
|
||||||
FindingKindException,
|
FindingKindException,
|
||||||
}
|
}
|
||||||
@@ -51,8 +53,10 @@ func (fk *FindingKind) Scan(value any) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case "NONCONFORMITY":
|
case "MINOR_NONCONFORMITY":
|
||||||
*fk = FindingKindNonconformity
|
*fk = FindingKindMinorNonconformity
|
||||||
|
case "MAJOR_NONCONFORMITY":
|
||||||
|
*fk = FindingKindMajorNonconformity
|
||||||
case "OBSERVATION":
|
case "OBSERVATION":
|
||||||
*fk = FindingKindObservation
|
*fk = FindingKindObservation
|
||||||
case "EXCEPTION":
|
case "EXCEPTION":
|
||||||
|
|||||||
3
pkg/coredata/migrations/20260319T120000Z.sql
Normal file
3
pkg/coredata/migrations/20260319T120000Z.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-- Rename NONCONFORMITY to MINOR_NONCONFORMITY and add MAJOR_NONCONFORMITY
|
||||||
|
ALTER TYPE findings_kind RENAME VALUE 'NONCONFORMITY' TO 'MINOR_NONCONFORMITY';
|
||||||
|
ALTER TYPE findings_kind ADD VALUE 'MAJOR_NONCONFORMITY';
|
||||||
@@ -165,9 +165,13 @@ enum TrustCenterDocumentAccessStatus
|
|||||||
|
|
||||||
enum FindingKind
|
enum FindingKind
|
||||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.FindingKind") {
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.FindingKind") {
|
||||||
NONCONFORMITY
|
MINOR_NONCONFORMITY
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.FindingKindNonconformity"
|
value: "go.probo.inc/probo/pkg/coredata.FindingKindMinorNonconformity"
|
||||||
|
)
|
||||||
|
MAJOR_NONCONFORMITY
|
||||||
|
@goEnum(
|
||||||
|
value: "go.probo.inc/probo/pkg/coredata.FindingKindMajorNonconformity"
|
||||||
)
|
)
|
||||||
OBSERVATION
|
OBSERVATION
|
||||||
@goEnum(
|
@goEnum(
|
||||||
|
|||||||
@@ -2312,7 +2312,8 @@ components:
|
|||||||
FindingKind:
|
FindingKind:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- NONCONFORMITY
|
- MINOR_NONCONFORMITY
|
||||||
|
- MAJOR_NONCONFORMITY
|
||||||
- OBSERVATION
|
- OBSERVATION
|
||||||
- EXCEPTION
|
- EXCEPTION
|
||||||
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.FindingKind
|
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.FindingKind
|
||||||
@@ -2491,7 +2492,7 @@ components:
|
|||||||
anyOf:
|
anyOf:
|
||||||
- $ref: "#/components/schemas/FindingKind"
|
- $ref: "#/components/schemas/FindingKind"
|
||||||
- type: "null"
|
- type: "null"
|
||||||
description: Filter by finding kind (NONCONFORMITY, OBSERVATION, EXCEPTION). Defaults to null which returns all kinds.
|
description: Filter by finding kind (MINOR_NONCONFORMITY, MAJOR_NONCONFORMITY, OBSERVATION, EXCEPTION). Defaults to null which returns all kinds.
|
||||||
status:
|
status:
|
||||||
anyOf:
|
anyOf:
|
||||||
- $ref: "#/components/schemas/FindingStatus"
|
- $ref: "#/components/schemas/FindingStatus"
|
||||||
|
|||||||
Reference in New Issue
Block a user