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}