From c69b988ba15e68865395eb09373e7b06e2f1204e Mon Sep 17 00:00:00 2001 From: gearnode Date: Wed, 5 Mar 2025 11:05:59 +0100 Subject: [PATCH] Add policy review date Signed-off-by: gearnode --- apps/console/src/pages/CreatePolicyPage.tsx | 27 +++++- apps/console/src/pages/PolicyOverviewPage.tsx | 7 +- apps/console/src/pages/UpdatePolicyPage.tsx | 36 ++++++-- .../CreatePolicyPageMutation.graphql.ts | 17 +++- .../PolicyOverviewPageQuery.graphql.ts | 16 +++- .../UpdatePolicyPageMutation.graphql.ts | 17 +++- .../UpdatePolicyPageQuery.graphql.ts | 16 +++- pkg/api/console/v1/schema.graphql | 3 + pkg/api/console/v1/schema/schema.go | 84 +++++++++++++++++-- pkg/api/console/v1/types/policy.go | 15 ++-- pkg/api/console/v1/types/types.go | 17 ++-- pkg/api/console/v1/v1_resolver.go | 2 + .../coredata/migrations/20250305T110005Z.sql | 1 + pkg/probo/coredata/policy.go | 12 +++ pkg/probo/policy_service.go | 4 + 15 files changed, 226 insertions(+), 48 deletions(-) create mode 100644 pkg/probo/coredata/migrations/20250305T110005Z.sql diff --git a/apps/console/src/pages/CreatePolicyPage.tsx b/apps/console/src/pages/CreatePolicyPage.tsx index 13d296161..ea9e16b17 100644 --- a/apps/console/src/pages/CreatePolicyPage.tsx +++ b/apps/console/src/pages/CreatePolicyPage.tsx @@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useToast } from "@/hooks/use-toast"; -import { FileText } from "lucide-react"; +import { FileText, Calendar } from "lucide-react"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import PolicyEditor from "@/components/PolicyEditor"; import type { CreatePolicyPageMutation } from "./__generated__/CreatePolicyPageMutation.graphql"; @@ -24,6 +24,7 @@ const CreatePolicyMutation = graphql` name content status + reviewDate } } } @@ -36,6 +37,7 @@ export default function CreatePolicyPage() { const [name, setName] = useState(""); const [content, setContent] = useState(""); const [status, setStatus] = useState<"DRAFT" | "ACTIVE">("DRAFT"); + const [reviewDate, setReviewDate] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const { toast } = useToast(); @@ -53,11 +55,18 @@ export default function CreatePolicyPage() { e.preventDefault(); setIsSubmitting(true); + // Convert reviewDate string to ISO format for the API + let reviewDateValue = null; + if (reviewDate) { + reviewDateValue = new Date(reviewDate).toISOString(); + } + const input = { organizationId: organizationId!, name, content, status, + reviewDate: reviewDateValue, }; commitMutation({ @@ -174,6 +183,22 @@ export default function CreatePolicyPage() { + +
+ + setReviewDate(e.target.value)} + /> +
diff --git a/apps/console/src/pages/PolicyOverviewPage.tsx b/apps/console/src/pages/PolicyOverviewPage.tsx index 2bd5903a0..d125df27f 100644 --- a/apps/console/src/pages/PolicyOverviewPage.tsx +++ b/apps/console/src/pages/PolicyOverviewPage.tsx @@ -24,6 +24,7 @@ const PolicyOverviewPageQuery = graphql` content createdAt updatedAt + reviewDate status } } @@ -210,7 +211,11 @@ function PolicyOverviewPageContent({ Review Due -

2025-02-15

+

+ {policy.reviewDate + ? formatDate(policy.reviewDate) + : "Not set"} +

diff --git a/apps/console/src/pages/UpdatePolicyPage.tsx b/apps/console/src/pages/UpdatePolicyPage.tsx index e1dfd6ece..9a442779e 100644 --- a/apps/console/src/pages/UpdatePolicyPage.tsx +++ b/apps/console/src/pages/UpdatePolicyPage.tsx @@ -13,7 +13,7 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { toast } from "@/hooks/use-toast"; -import { FileText } from "lucide-react"; +import { FileText, Calendar } from "lucide-react"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Suspense } from "react"; import PolicyEditor from "@/components/PolicyEditor"; @@ -29,6 +29,7 @@ const UpdatePolicyPageQuery = graphql` content status version + reviewDate } } } @@ -43,6 +44,7 @@ const UpdatePolicyMutation = graphql` content status version + reviewDate } } } @@ -65,6 +67,7 @@ function UpdatePolicyPageContent({ const [name, setName] = useState(data.node.name); const [content, setContent] = useState(data.node.content || ""); const [status, setStatus] = useState(data.node.status); + const [reviewDate, setReviewDate] = useState(data.node.reviewDate || ""); const [isSubmitting, setIsSubmitting] = useState(false); console.log( @@ -81,6 +84,12 @@ function UpdatePolicyPageContent({ e.preventDefault(); setIsSubmitting(true); + // Convert reviewDate string to ISO format for the API + let reviewDateValue = null; + if (reviewDate) { + reviewDateValue = new Date(reviewDate).toISOString(); + } + commitMutation({ variables: { input: { @@ -88,6 +97,7 @@ function UpdatePolicyPageContent({ name, content, status, + reviewDate: reviewDateValue, expectedVersion: data.node.version!, }, }, @@ -98,19 +108,16 @@ function UpdatePolicyPageContent({ toast({ title: "Error", description: "Failed to update policy. Please try again.", - variant: "destructive", }); return; } toast({ title: "Success", - description: "Policy updated successfully!", + description: "Policy updated successfully.", }); - navigate( - `/organizations/${organizationId}/policies/${response.updatePolicy.policy.id}` - ); + navigate(`/organizations/${organizationId}/policies/${policyId}`); }, onError: (error) => { setIsSubmitting(false); @@ -118,7 +125,6 @@ function UpdatePolicyPageContent({ toast({ title: "Error", description: "Failed to update policy. Please try again.", - variant: "destructive", }); }, }); @@ -193,6 +199,22 @@ function UpdatePolicyPageContent({
+ +
+ + setReviewDate(e.target.value)} + /> +
diff --git a/apps/console/src/pages/__generated__/CreatePolicyPageMutation.graphql.ts b/apps/console/src/pages/__generated__/CreatePolicyPageMutation.graphql.ts index ff9d670a4..eb8af679f 100644 --- a/apps/console/src/pages/__generated__/CreatePolicyPageMutation.graphql.ts +++ b/apps/console/src/pages/__generated__/CreatePolicyPageMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -14,6 +14,7 @@ export type CreatePolicyInput = { content: string; name: string; organizationId: string; + reviewDate?: string | null | undefined; status: PolicyStatus; }; export type CreatePolicyPageMutation$variables = { @@ -27,6 +28,7 @@ export type CreatePolicyPageMutation$data = { readonly content: string; readonly id: string; readonly name: string; + readonly reviewDate: string | null | undefined; readonly status: PolicyStatus; }; }; @@ -98,6 +100,13 @@ v3 = { "kind": "ScalarField", "name": "status", "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "reviewDate", + "storageKey": null } ], "storageKey": null @@ -171,16 +180,16 @@ return { ] }, "params": { - "cacheID": "f9d97eecb99b47365557e372c724af41", + "cacheID": "64796b84575bf926f45da4c98d31e645", "id": null, "metadata": {}, "name": "CreatePolicyPageMutation", "operationKind": "mutation", - "text": "mutation CreatePolicyPageMutation(\n $input: CreatePolicyInput!\n) {\n createPolicy(input: $input) {\n policyEdge {\n node {\n id\n name\n content\n status\n }\n }\n }\n}\n" + "text": "mutation CreatePolicyPageMutation(\n $input: CreatePolicyInput!\n) {\n createPolicy(input: $input) {\n policyEdge {\n node {\n id\n name\n content\n status\n reviewDate\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "dca08dd146693bcf614e7d02785e57b5"; +(node as any).hash = "b7ecb61ced1e31c0c0093946135eca3b"; export default node; diff --git a/apps/console/src/pages/__generated__/PolicyOverviewPageQuery.graphql.ts b/apps/console/src/pages/__generated__/PolicyOverviewPageQuery.graphql.ts index 71d9f7f19..2aa49c69c 100644 --- a/apps/console/src/pages/__generated__/PolicyOverviewPageQuery.graphql.ts +++ b/apps/console/src/pages/__generated__/PolicyOverviewPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<0eb945d3cbf8f223621fe7aa2b93eddc>> * @lightSyntaxTransform * @nogrep */ @@ -19,6 +19,7 @@ export type PolicyOverviewPageQuery$data = { readonly createdAt?: string; readonly id: string; readonly name?: string; + readonly reviewDate?: string | null | undefined; readonly status?: PolicyStatus; readonly updatedAt?: string; }; @@ -81,6 +82,13 @@ v3 = { "name": "updatedAt", "storageKey": null }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "reviewDate", + "storageKey": null + }, { "alias": null, "args": null, @@ -145,16 +153,16 @@ return { ] }, "params": { - "cacheID": "07fedea13b4dbbe58e15dfaa644b24fa", + "cacheID": "d3b31142132a379f9c3a8812ddcfb7da", "id": null, "metadata": {}, "name": "PolicyOverviewPageQuery", "operationKind": "query", - "text": "query PolicyOverviewPageQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n createdAt\n updatedAt\n status\n }\n }\n}\n" + "text": "query PolicyOverviewPageQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n createdAt\n updatedAt\n reviewDate\n status\n }\n }\n}\n" } }; })(); -(node as any).hash = "17389d925f3f3ffa3ed5eb8ed9051ae9"; +(node as any).hash = "1519b589fe7da5a258621ad445970ca7"; export default node; diff --git a/apps/console/src/pages/__generated__/UpdatePolicyPageMutation.graphql.ts b/apps/console/src/pages/__generated__/UpdatePolicyPageMutation.graphql.ts index 11e5f87b1..bd1ca3954 100644 --- a/apps/console/src/pages/__generated__/UpdatePolicyPageMutation.graphql.ts +++ b/apps/console/src/pages/__generated__/UpdatePolicyPageMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<9a54ece29b9ff9a2efa624f67f40f803>> * @lightSyntaxTransform * @nogrep */ @@ -15,6 +15,7 @@ export type UpdatePolicyInput = { expectedVersion: number; id: string; name?: string | null | undefined; + reviewDate?: string | null | undefined; status?: PolicyStatus | null | undefined; }; export type UpdatePolicyPageMutation$variables = { @@ -26,6 +27,7 @@ export type UpdatePolicyPageMutation$data = { readonly content: string; readonly id: string; readonly name: string; + readonly reviewDate: string | null | undefined; readonly status: PolicyStatus; readonly version: number; }; @@ -101,6 +103,13 @@ v1 = [ "kind": "ScalarField", "name": "version", "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "reviewDate", + "storageKey": null } ], "storageKey": null @@ -127,16 +136,16 @@ return { "selections": (v1/*: any*/) }, "params": { - "cacheID": "ca013100ee6a0bf7c4e572474f1ba088", + "cacheID": "ce2ccf9449b52e3df3b2b9bb82c55166", "id": null, "metadata": {}, "name": "UpdatePolicyPageMutation", "operationKind": "mutation", - "text": "mutation UpdatePolicyPageMutation(\n $input: UpdatePolicyInput!\n) {\n updatePolicy(input: $input) {\n policy {\n id\n name\n content\n status\n version\n }\n }\n}\n" + "text": "mutation UpdatePolicyPageMutation(\n $input: UpdatePolicyInput!\n) {\n updatePolicy(input: $input) {\n policy {\n id\n name\n content\n status\n version\n reviewDate\n }\n }\n}\n" } }; })(); -(node as any).hash = "c17a1ff9bf786b0e251374a14fff0086"; +(node as any).hash = "d5329966d0e13b8931d6f01d9afb74e2"; export default node; diff --git a/apps/console/src/pages/__generated__/UpdatePolicyPageQuery.graphql.ts b/apps/console/src/pages/__generated__/UpdatePolicyPageQuery.graphql.ts index 9b42e8289..3968184e2 100644 --- a/apps/console/src/pages/__generated__/UpdatePolicyPageQuery.graphql.ts +++ b/apps/console/src/pages/__generated__/UpdatePolicyPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<5ee387b238e8fdc7c41851c7e6740c95>> * @lightSyntaxTransform * @nogrep */ @@ -18,6 +18,7 @@ export type UpdatePolicyPageQuery$data = { readonly content?: string; readonly id: string; readonly name?: string; + readonly reviewDate?: string | null | undefined; readonly status?: PolicyStatus; readonly version?: number; }; @@ -79,6 +80,13 @@ v3 = { "kind": "ScalarField", "name": "version", "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "reviewDate", + "storageKey": null } ], "type": "Policy", @@ -137,16 +145,16 @@ return { ] }, "params": { - "cacheID": "ed70bb0199119ba5b9080ed86081ac79", + "cacheID": "fc062f2d2fcce04954feb69436433093", "id": null, "metadata": {}, "name": "UpdatePolicyPageQuery", "operationKind": "query", - "text": "query UpdatePolicyPageQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n status\n version\n }\n }\n}\n" + "text": "query UpdatePolicyPageQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n status\n version\n reviewDate\n }\n }\n}\n" } }; })(); -(node as any).hash = "303abaec54b66ef4f5c886d1cd606f12"; +(node as any).hash = "4ae49cad4f03a09d87475483c271bd94"; export default node; diff --git a/pkg/api/console/v1/schema.graphql b/pkg/api/console/v1/schema.graphql index c08422d62..83d8868f0 100644 --- a/pkg/api/console/v1/schema.graphql +++ b/pkg/api/console/v1/schema.graphql @@ -649,6 +649,7 @@ input CreatePolicyInput { name: String! content: String! status: PolicyStatus! + reviewDate: Datetime } input UpdatePolicyInput { @@ -657,6 +658,7 @@ input UpdatePolicyInput { name: String content: String status: PolicyStatus + reviewDate: Datetime } input DeletePolicyInput { @@ -681,6 +683,7 @@ type Policy implements Node { name: String! status: PolicyStatus! content: String! + reviewDate: Datetime createdAt: Datetime! updatedAt: Datetime! } diff --git a/pkg/api/console/v1/schema/schema.go b/pkg/api/console/v1/schema/schema.go index 6cd10bbc7..6655b5a99 100644 --- a/pkg/api/console/v1/schema/schema.go +++ b/pkg/api/console/v1/schema/schema.go @@ -285,13 +285,14 @@ type ComplexityRoot struct { } Policy struct { - Content func(childComplexity int) int - CreatedAt func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Status func(childComplexity int) int - UpdatedAt func(childComplexity int) int - Version func(childComplexity int) int + Content func(childComplexity int) int + CreatedAt func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + ReviewDate func(childComplexity int) int + Status func(childComplexity int) int + UpdatedAt func(childComplexity int) int + Version func(childComplexity int) int } PolicyConnection struct { @@ -1497,6 +1498,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Policy.Name(childComplexity), true + case "Policy.reviewDate": + if e.complexity.Policy.ReviewDate == nil { + break + } + + return e.complexity.Policy.ReviewDate(childComplexity), true + case "Policy.status": if e.complexity.Policy.Status == nil { break @@ -2734,6 +2742,7 @@ input CreatePolicyInput { name: String! content: String! status: PolicyStatus! + reviewDate: Datetime } input UpdatePolicyInput { @@ -2742,6 +2751,7 @@ input UpdatePolicyInput { name: String content: String status: PolicyStatus + reviewDate: Datetime } input DeletePolicyInput { @@ -2766,6 +2776,7 @@ type Policy implements Node { name: String! status: PolicyStatus! content: String! + reviewDate: Datetime createdAt: Datetime! updatedAt: Datetime! } @@ -9472,6 +9483,41 @@ func (ec *executionContext) fieldContext_Policy_content(_ context.Context, field return fc, nil } +func (ec *executionContext) _Policy_reviewDate(ctx context.Context, field graphql.CollectedField, obj *types.Policy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Policy_reviewDate(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ReviewDate, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*time.Time) + fc.Result = res + return ec.marshalODatetime2ᚖtimeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Policy_reviewDate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Policy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Policy_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Policy) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Policy_createdAt(ctx, field) if err != nil { @@ -9721,6 +9767,8 @@ func (ec *executionContext) fieldContext_PolicyEdge_node(_ context.Context, fiel return ec.fieldContext_Policy_status(ctx, field) case "content": return ec.fieldContext_Policy_content(ctx, field) + case "reviewDate": + return ec.fieldContext_Policy_reviewDate(ctx, field) case "createdAt": return ec.fieldContext_Policy_createdAt(ctx, field) case "updatedAt": @@ -11143,6 +11191,8 @@ func (ec *executionContext) fieldContext_UpdatePolicyPayload_policy(_ context.Co return ec.fieldContext_Policy_status(ctx, field) case "content": return ec.fieldContext_Policy_content(ctx, field) + case "reviewDate": + return ec.fieldContext_Policy_reviewDate(ctx, field) case "createdAt": return ec.fieldContext_Policy_createdAt(ctx, field) case "updatedAt": @@ -13966,7 +14016,7 @@ func (ec *executionContext) unmarshalInputCreatePolicyInput(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"organizationId", "name", "content", "status"} + fieldsInOrder := [...]string{"organizationId", "name", "content", "status", "reviewDate"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -14001,6 +14051,13 @@ func (ec *executionContext) unmarshalInputCreatePolicyInput(ctx context.Context, return it, err } it.Status = data + case "reviewDate": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reviewDate")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ReviewDate = data } } @@ -14479,7 +14536,7 @@ func (ec *executionContext) unmarshalInputUpdatePolicyInput(ctx context.Context, asMap[k] = v } - fieldsInOrder := [...]string{"id", "expectedVersion", "name", "content", "status"} + fieldsInOrder := [...]string{"id", "expectedVersion", "name", "content", "status", "reviewDate"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -14521,6 +14578,13 @@ func (ec *executionContext) unmarshalInputUpdatePolicyInput(ctx context.Context, return it, err } it.Status = data + case "reviewDate": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reviewDate")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ReviewDate = data } } @@ -16903,6 +16967,8 @@ func (ec *executionContext) _Policy(ctx context.Context, sel ast.SelectionSet, o if out.Values[i] == graphql.Null { out.Invalids++ } + case "reviewDate": + out.Values[i] = ec._Policy_reviewDate(ctx, field, obj) case "createdAt": out.Values[i] = ec._Policy_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/pkg/api/console/v1/types/policy.go b/pkg/api/console/v1/types/policy.go index cedc74841..a8006d245 100644 --- a/pkg/api/console/v1/types/policy.go +++ b/pkg/api/console/v1/types/policy.go @@ -21,13 +21,14 @@ import ( func NewPolicy(policy *coredata.Policy) *Policy { return &Policy{ - ID: policy.ID, - Version: policy.Version, - Name: policy.Name, - Content: policy.Content, - CreatedAt: policy.CreatedAt, - UpdatedAt: policy.UpdatedAt, - Status: policy.Status, + ID: policy.ID, + Version: policy.Version, + Name: policy.Name, + Content: policy.Content, + CreatedAt: policy.CreatedAt, + UpdatedAt: policy.UpdatedAt, + Status: policy.Status, + ReviewDate: policy.ReviewDate, } } diff --git a/pkg/api/console/v1/types/types.go b/pkg/api/console/v1/types/types.go index 75f53c898..93ed1a723 100644 --- a/pkg/api/console/v1/types/types.go +++ b/pkg/api/console/v1/types/types.go @@ -107,6 +107,7 @@ type CreatePolicyInput struct { Name string `json:"name"` Content string `json:"content"` Status coredata.PolicyStatus `json:"status"` + ReviewDate *time.Time `json:"reviewDate,omitempty"` } type CreatePolicyPayload struct { @@ -315,13 +316,14 @@ type PeopleEdge struct { } type Policy struct { - ID gid.GID `json:"id"` - Version int `json:"version"` - Name string `json:"name"` - Status coredata.PolicyStatus `json:"status"` - Content string `json:"content"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID gid.GID `json:"id"` + Version int `json:"version"` + Name string `json:"name"` + Status coredata.PolicyStatus `json:"status"` + Content string `json:"content"` + ReviewDate *time.Time `json:"reviewDate,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } func (Policy) IsNode() {} @@ -431,6 +433,7 @@ type UpdatePolicyInput struct { Name *string `json:"name,omitempty"` Content *string `json:"content,omitempty"` Status *coredata.PolicyStatus `json:"status,omitempty"` + ReviewDate *time.Time `json:"reviewDate,omitempty"` } type UpdatePolicyPayload struct { diff --git a/pkg/api/console/v1/v1_resolver.go b/pkg/api/console/v1/v1_resolver.go index 2c15467f6..a5bcb5fa4 100644 --- a/pkg/api/console/v1/v1_resolver.go +++ b/pkg/api/console/v1/v1_resolver.go @@ -382,6 +382,7 @@ func (r *mutationResolver) CreatePolicy(ctx context.Context, input types.CreateP Name: input.Name, Content: input.Content, Status: input.Status, + ReviewDate: input.ReviewDate, }) if err != nil { return nil, fmt.Errorf("cannot create policy: %w", err) @@ -400,6 +401,7 @@ func (r *mutationResolver) UpdatePolicy(ctx context.Context, input types.UpdateP Name: input.Name, Content: input.Content, Status: input.Status, + ReviewDate: input.ReviewDate, }) if err != nil { return nil, fmt.Errorf("cannot update policy: %w", err) diff --git a/pkg/probo/coredata/migrations/20250305T110005Z.sql b/pkg/probo/coredata/migrations/20250305T110005Z.sql new file mode 100644 index 000000000..223a8efc4 --- /dev/null +++ b/pkg/probo/coredata/migrations/20250305T110005Z.sql @@ -0,0 +1 @@ +ALTER TABLE policies ADD COLUMN review_date TIMESTAMP WITH TIME ZONE; \ No newline at end of file diff --git a/pkg/probo/coredata/policy.go b/pkg/probo/coredata/policy.go index 2a893dd4a..4cc142290 100644 --- a/pkg/probo/coredata/policy.go +++ b/pkg/probo/coredata/policy.go @@ -19,6 +19,7 @@ type ( Status PolicyStatus `db:"status"` Name string `db:"name"` Content string `db:"content"` + ReviewDate *time.Time `db:"review_date"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` Version int `db:"version"` @@ -31,6 +32,7 @@ type ( Name *string Content *string Status *PolicyStatus + ReviewDate **time.Time } ) @@ -51,6 +53,7 @@ SELECT name, status, content, + review_date, created_at, updated_at, version @@ -96,6 +99,7 @@ SELECT name, status, content, + review_date, created_at, updated_at, version @@ -140,6 +144,7 @@ INSERT INTO name, status, content, + review_date, created_at, updated_at, version @@ -150,6 +155,7 @@ VALUES ( @name, @status, @content, + @review_date, @created_at, @updated_at, @version @@ -162,6 +168,7 @@ VALUES ( "name": p.Name, "status": p.Status, "content": p.Content, + "review_date": p.ReviewDate, "created_at": p.CreatedAt, "updated_at": p.UpdatedAt, "version": p.Version, @@ -199,6 +206,7 @@ UPDATE policies SET name = COALESCE(@name, name), status = COALESCE(@status, status), content = COALESCE(@content, content), + review_date = COALESCE(@review_date, review_date), updated_at = @updated_at, version = version + 1 WHERE %s @@ -209,6 +217,7 @@ RETURNING organization_id, name, content, + review_date, created_at, updated_at, status, @@ -231,6 +240,9 @@ RETURNING if params.Status != nil { args["status"] = *params.Status } + if params.ReviewDate != nil { + args["review_date"] = *params.ReviewDate + } maps.Copy(args, scope.SQLArguments()) diff --git a/pkg/probo/policy_service.go b/pkg/probo/policy_service.go index abc77d5b7..33f4a5e7b 100644 --- a/pkg/probo/policy_service.go +++ b/pkg/probo/policy_service.go @@ -21,6 +21,7 @@ type ( Name string Status coredata.PolicyStatus Content string + ReviewDate *time.Time } UpdatePolicyRequest struct { @@ -29,6 +30,7 @@ type ( Name *string Content *string Status *coredata.PolicyStatus + ReviewDate *time.Time } ) @@ -69,6 +71,7 @@ func (s *PolicyService) Create( Name: req.Name, Content: req.Content, Status: req.Status, + ReviewDate: req.ReviewDate, CreatedAt: now, UpdatedAt: now, } @@ -104,6 +107,7 @@ func (s *PolicyService) Update( Name: req.Name, Content: req.Content, Status: req.Status, + ReviewDate: &req.ReviewDate, } policy := &coredata.Policy{ID: req.ID}