From d30daf830563b21f82036fc3bb02033a88c6c0aa Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Fri, 8 Aug 2025 18:54:29 +0200 Subject: [PATCH 1/2] chore: add updated-at timestamps Signed-off-by: Miguel Martinez --- .../controlplane/v1/response_messages.pb.go | 606 ++++++++++-------- .../controlplane/v1/response_messages.proto | 3 + .../api/controlplane/v1/user.pb.go | 2 +- .../api/controlplane/v1/user.proto | 2 +- .../api/controlplane/v1/user_grpc.pb.go | 2 +- .../controlplane/v1/response_messages.ts | 54 +- .../frontend/google/protobuf/descriptor.ts | 16 +- .../controlplane.v1.OrgItem.jsonschema.json | 6 + .../controlplane.v1.OrgItem.schema.json | 6 + .../controlplane.v1.User.jsonschema.json | 6 + .../controlplane.v1.User.schema.json | 6 + ...ne.v1.WorkflowContractItem.jsonschema.json | 6 + ...lplane.v1.WorkflowContractItem.schema.json | 6 + app/controlplane/internal/service/context.go | 6 +- app/controlplane/internal/service/user.go | 1 + .../internal/service/workflowcontract.go | 1 + app/controlplane/pkg/biz/organization.go | 1 + app/controlplane/pkg/biz/user.go | 1 + app/controlplane/pkg/biz/workflowcontract.go | 1 + .../ent/migrate/migrations/20250808164000.sql | 3 + .../ent/migrate/migrations/20250808164400.sql | 5 + .../ent/migrate/migrations/20250808165202.sql | 4 + .../pkg/data/ent/migrate/migrations/atlas.sum | 5 +- .../pkg/data/ent/migrate/schema.go | 9 +- app/controlplane/pkg/data/ent/mutation.go | 168 ++++- app/controlplane/pkg/data/ent/organization.go | 13 +- .../pkg/data/ent/organization/organization.go | 10 + .../pkg/data/ent/organization/where.go | 45 ++ .../pkg/data/ent/organization_create.go | 65 ++ .../pkg/data/ent/organization_update.go | 35 + app/controlplane/pkg/data/ent/runtime.go | 14 +- app/controlplane/pkg/data/ent/schema-viz.html | 2 +- .../pkg/data/ent/schema/organization.go | 5 + app/controlplane/pkg/data/ent/schema/user.go | 7 +- .../pkg/data/ent/schema/workflowcontract.go | 7 +- app/controlplane/pkg/data/ent/user.go | 13 +- app/controlplane/pkg/data/ent/user/user.go | 10 + app/controlplane/pkg/data/ent/user/where.go | 45 ++ app/controlplane/pkg/data/ent/user_create.go | 65 ++ app/controlplane/pkg/data/ent/user_update.go | 35 + .../pkg/data/ent/workflowcontract.go | 13 +- .../pkg/data/ent/workflowcontract/where.go | 45 ++ .../ent/workflowcontract/workflowcontract.go | 10 + .../pkg/data/ent/workflowcontract_create.go | 65 ++ .../pkg/data/ent/workflowcontract_update.go | 34 + app/controlplane/pkg/data/membership.go | 4 +- app/controlplane/pkg/data/organization.go | 5 +- app/controlplane/pkg/data/project.go | 2 +- app/controlplane/pkg/data/projectversion.go | 2 +- app/controlplane/pkg/data/user.go | 8 +- app/controlplane/pkg/data/workflow.go | 3 +- app/controlplane/pkg/data/workflowcontract.go | 5 +- 52 files changed, 1172 insertions(+), 321 deletions(-) create mode 100644 app/controlplane/pkg/data/ent/migrate/migrations/20250808164000.sql create mode 100644 app/controlplane/pkg/data/ent/migrate/migrations/20250808164400.sql create mode 100644 app/controlplane/pkg/data/ent/migrate/migrations/20250808165202.sql diff --git a/app/controlplane/api/controlplane/v1/response_messages.pb.go b/app/controlplane/api/controlplane/v1/response_messages.pb.go index 6a09896e2..56731993b 100644 --- a/app/controlplane/api/controlplane/v1/response_messages.pb.go +++ b/app/controlplane/api/controlplane/v1/response_messages.pb.go @@ -1306,6 +1306,7 @@ type WorkflowContractItem struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` LatestRevision int32 `protobuf:"varint,4,opt,name=latest_revision,json=latestRevision,proto3" json:"latest_revision,omitempty"` LatestRevisionCreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=latest_revision_created_at,json=latestRevisionCreatedAt,proto3" json:"latest_revision_created_at,omitempty"` // Workflows associated with this contract @@ -1377,6 +1378,13 @@ func (x *WorkflowContractItem) GetCreatedAt() *timestamppb.Timestamp { return nil } +func (x *WorkflowContractItem) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + func (x *WorkflowContractItem) GetLatestRevision() int32 { if x != nil { return x.LatestRevision @@ -1662,6 +1670,7 @@ type User struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` FirstName string `protobuf:"bytes,4,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"` LastName string `protobuf:"bytes,5,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"` } @@ -1719,6 +1728,13 @@ func (x *User) GetCreatedAt() *timestamppb.Timestamp { return nil } +func (x *User) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + func (x *User) GetFirstName() string { if x != nil { return x.FirstName @@ -1836,6 +1852,7 @@ type OrgItem struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` DefaultPolicyViolationStrategy OrgItem_PolicyViolationBlockingStrategy `protobuf:"varint,4,opt,name=default_policy_violation_strategy,json=defaultPolicyViolationStrategy,proto3,enum=controlplane.v1.OrgItem_PolicyViolationBlockingStrategy" json:"default_policy_violation_strategy,omitempty"` PolicyAllowedHostnames []string `protobuf:"bytes,5,rep,name=policy_allowed_hostnames,json=policyAllowedHostnames,proto3" json:"policy_allowed_hostnames,omitempty"` } @@ -1893,6 +1910,13 @@ func (x *OrgItem) GetCreatedAt() *timestamppb.Timestamp { return nil } +func (x *OrgItem) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + func (x *OrgItem) GetDefaultPolicyViolationStrategy() OrgItem_PolicyViolationBlockingStrategy { if x != nil { return x.DefaultPolicyViolationStrategy @@ -2760,7 +2784,7 @@ var file_controlplane_v1_response_messages_proto_rawDesc = []byte{ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0xcb, 0x03, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, + 0x22, 0x86, 0x04, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, @@ -2769,269 +2793,280 @@ var file_controlplane_v1_response_messages_proto_rawDesc = []byte{ 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x6c, 0x61, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x1a, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x17, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x29, 0x0a, 0x0e, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x66, 0x52, 0x0c, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x66, 0x73, 0x12, 0x42, 0x0a, 0x0d, 0x73, 0x63, - 0x6f, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x52, 0x0c, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x46, - 0x0a, 0x0c, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xed, 0x01, 0x0a, 0x0b, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x66, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2d, 0x64, - 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, - 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, - 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, 0x61, - 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, - 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x9d, 0x04, 0x0a, 0x1b, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, - 0x02, 0x76, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x02, - 0x18, 0x01, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x12, 0x57, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x61, 0x77, - 0x42, 0x6f, 0x64, 0x79, 0x52, 0x0b, 0x72, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0xd1, 0x01, 0x0a, 0x07, 0x52, 0x61, 0x77, 0x42, 0x6f, - 0x64, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x5e, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x61, 0x77, 0x42, 0x6f, 0x64, 0x79, 0x2e, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x42, 0x09, 0xba, 0x48, 0x06, 0x82, 0x01, 0x03, 0x22, 0x01, 0x00, 0x52, 0x06, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x52, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x12, 0x16, 0x0a, 0x12, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x4f, 0x52, 0x4d, - 0x41, 0x54, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x4f, 0x52, - 0x4d, 0x41, 0x54, 0x5f, 0x59, 0x41, 0x4d, 0x4c, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x4f, - 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x43, 0x55, 0x45, 0x10, 0x03, 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x22, 0xa3, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xbf, 0x02, 0x0a, - 0x11, 0x4f, 0x72, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x49, 0x74, - 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x29, - 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, - 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x57, + 0x0a, 0x1a, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x68, 0x69, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0xdf, - 0x03, 0x0a, 0x07, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x83, 0x01, 0x0a, 0x21, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x69, 0x6f, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x2e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, - 0x1e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x69, - 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, - 0x38, 0x0a, 0x18, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, - 0x64, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x16, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, - 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb4, 0x01, 0x0a, 0x1f, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x32, 0x0a, - 0x2e, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x54, - 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x2c, 0x0a, 0x28, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, 0x4c, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, - 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x01, 0x12, - 0x2f, 0x0a, 0x2b, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x52, - 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x49, 0x53, 0x4f, 0x52, 0x59, 0x10, 0x02, - 0x22, 0xf5, 0x04, 0x0a, 0x0e, 0x43, 0x41, 0x53, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, - 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x3d, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x5d, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x41, 0x53, - 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x41, 0x53, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x06, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x49, 0x6e, 0x6c, 0x69, 0x6e, - 0x65, 0x1a, 0x25, 0x0a, 0x06, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, - 0x61, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, - 0x6d, 0x61, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x18, 0x0a, 0x14, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x22, 0xdd, 0x03, 0x0a, 0x0c, 0x41, 0x50, 0x49, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x72, 0x67, 0x61, - 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x5f, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x17, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, + 0x65, 0x66, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x66, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x52, 0x65, 0x66, 0x73, 0x12, 0x42, 0x0a, 0x0d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x5f, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x46, 0x0a, 0x0c, 0x53, 0x63, 0x6f, + 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0xed, 0x01, 0x0a, 0x0b, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, + 0x66, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x97, 0x01, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, + 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2d, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, + 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, + 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, + 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, + 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x9d, 0x04, 0x0a, 0x1b, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, + 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, + 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, + 0x02, 0x76, 0x31, 0x12, 0x57, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x52, 0x61, 0x77, 0x42, 0x6f, 0x64, 0x79, 0x52, + 0x0b, 0x72, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x23, 0x0a, 0x0d, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x1a, 0xd1, 0x01, 0x0a, 0x07, 0x52, 0x61, 0x77, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x12, 0x5e, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x2e, + 0x52, 0x61, 0x77, 0x42, 0x6f, 0x64, 0x79, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x09, + 0xba, 0x48, 0x06, 0x82, 0x01, 0x03, 0x22, 0x01, 0x00, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x22, 0x52, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x16, 0x0a, 0x12, 0x46, + 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x4a, 0x53, + 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x59, + 0x41, 0x4d, 0x4c, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, + 0x43, 0x55, 0x45, 0x10, 0x03, 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x22, 0xde, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0xbf, 0x02, 0x0a, 0x11, 0x4f, 0x72, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x52, + 0x03, 0x6f, 0x72, 0x67, 0x12, 0x29, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x33, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, + 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x9a, 0x04, 0x0a, 0x07, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, - 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x2a, 0xa6, 0x01, 0x0a, 0x09, 0x52, 0x75, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x12, 0x18, - 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, - 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x55, 0x4e, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, - 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, - 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, - 0x05, 0x2a, 0xd4, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, - 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, - 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, - 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x56, 0x49, 0x45, - 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, - 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x41, 0x44, 0x4d, - 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, - 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x4f, 0x57, 0x4e, 0x45, - 0x52, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, - 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, - 0x52, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, - 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, - 0x49, 0x42, 0x55, 0x54, 0x4f, 0x52, 0x10, 0x05, 0x2a, 0x60, 0x0a, 0x0e, 0x41, 0x6c, 0x6c, 0x6f, - 0x77, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x4c, - 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x1c, - 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x1a, 0x04, - 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x46, 0x65, - 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x41, 0x75, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x12, 0x24, 0x0a, 0x20, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x55, - 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x21, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, - 0x54, 0x45, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, - 0x4e, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x04, 0xa8, - 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x84, 0x01, 0x0a, 0x19, 0x55, 0x73, - 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x6f, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, - 0x69, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x29, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x83, 0x01, 0x0a, 0x21, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x69, + 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x49, 0x74, 0x65, 0x6d, + 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x52, 0x1e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, + 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x12, 0x38, 0x0a, 0x18, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x64, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x16, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb4, 0x01, 0x0a, 0x1f, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x32, + 0x0a, 0x2e, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x52, 0x41, + 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x2c, 0x0a, 0x28, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, + 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, + 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x01, + 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, + 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x49, 0x53, 0x4f, 0x52, 0x59, 0x10, + 0x02, 0x22, 0xf5, 0x04, 0x0a, 0x0e, 0x43, 0x41, 0x53, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x5d, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x41, + 0x53, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x41, 0x53, 0x42, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x06, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x49, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x1a, 0x25, 0x0a, 0x06, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, + 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x08, 0x6d, 0x61, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, + 0x1d, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x18, 0x0a, 0x14, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x22, 0xdd, 0x03, 0x0a, 0x0c, 0x41, 0x50, + 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, + 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, + 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x2a, 0xa6, 0x01, 0x0a, 0x09, 0x52, 0x75, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, + 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x55, 0x4e, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, + 0x12, 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, + 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, + 0x10, 0x05, 0x2a, 0xd4, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, + 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, + 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x56, 0x49, + 0x45, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, + 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x41, 0x44, + 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, + 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x4f, 0x57, 0x4e, + 0x45, 0x52, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, + 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x4d, 0x45, 0x4d, 0x42, + 0x45, 0x52, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, + 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x52, 0x49, 0x42, 0x55, 0x54, 0x4f, 0x52, 0x10, 0x05, 0x2a, 0x60, 0x0a, 0x0e, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x1c, 0x41, + 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, + 0x1c, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x1a, + 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x41, 0x75, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x24, 0x0a, 0x20, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, + 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x21, 0x46, 0x45, 0x44, 0x45, 0x52, + 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x04, + 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x84, 0x01, 0x0a, 0x19, 0x55, + 0x73, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x6f, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x68, 0x69, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x29, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, + 0x48, 0x49, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x32, 0x0a, 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, - 0x49, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x32, 0x0a, 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x57, - 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, - 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4f, - 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, - 0x2a, 0x80, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x4f, 0x66, 0x4f, 0x72, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x28, - 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, - 0x4f, 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x31, 0x0a, 0x27, 0x55, 0x53, - 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x4f, 0x46, - 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, - 0x4e, 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, - 0x45, 0xf4, 0x03, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x49, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, + 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, + 0x03, 0x2a, 0x80, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4f, 0x72, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2c, 0x0a, + 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, + 0x5f, 0x4f, 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x31, 0x0a, 0x27, 0x55, + 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x4f, + 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x49, 0x4e, 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, + 0xa0, 0x45, 0xf4, 0x03, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, + 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3115,37 +3150,40 @@ var file_controlplane_v1_response_messages_proto_depIdxs = []int32{ 16, // 21: controlplane.v1.PolicyEvaluation.group_reference:type_name -> controlplane.v1.PolicyReference 34, // 22: controlplane.v1.PolicyReference.digest:type_name -> controlplane.v1.PolicyReference.DigestEntry 37, // 23: controlplane.v1.WorkflowContractItem.created_at:type_name -> google.protobuf.Timestamp - 37, // 24: controlplane.v1.WorkflowContractItem.latest_revision_created_at:type_name -> google.protobuf.Timestamp - 19, // 25: controlplane.v1.WorkflowContractItem.workflow_refs:type_name -> controlplane.v1.WorkflowRef - 18, // 26: controlplane.v1.WorkflowContractItem.scoped_entity:type_name -> controlplane.v1.ScopedEntity - 37, // 27: controlplane.v1.WorkflowContractVersionItem.created_at:type_name -> google.protobuf.Timestamp - 39, // 28: controlplane.v1.WorkflowContractVersionItem.v1:type_name -> workflowcontract.v1.CraftingSchema - 35, // 29: controlplane.v1.WorkflowContractVersionItem.raw_contract:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody - 37, // 30: controlplane.v1.User.created_at:type_name -> google.protobuf.Timestamp - 23, // 31: controlplane.v1.OrgMembershipItem.org:type_name -> controlplane.v1.OrgItem - 21, // 32: controlplane.v1.OrgMembershipItem.user:type_name -> controlplane.v1.User - 37, // 33: controlplane.v1.OrgMembershipItem.created_at:type_name -> google.protobuf.Timestamp - 37, // 34: controlplane.v1.OrgMembershipItem.updated_at:type_name -> google.protobuf.Timestamp - 1, // 35: controlplane.v1.OrgMembershipItem.role:type_name -> controlplane.v1.MembershipRole - 37, // 36: controlplane.v1.OrgItem.created_at:type_name -> google.protobuf.Timestamp - 7, // 37: controlplane.v1.OrgItem.default_policy_violation_strategy:type_name -> controlplane.v1.OrgItem.PolicyViolationBlockingStrategy - 37, // 38: controlplane.v1.CASBackendItem.created_at:type_name -> google.protobuf.Timestamp - 37, // 39: controlplane.v1.CASBackendItem.validated_at:type_name -> google.protobuf.Timestamp - 8, // 40: controlplane.v1.CASBackendItem.validation_status:type_name -> controlplane.v1.CASBackendItem.ValidationStatus - 36, // 41: controlplane.v1.CASBackendItem.limits:type_name -> controlplane.v1.CASBackendItem.Limits - 18, // 42: controlplane.v1.APITokenItem.scoped_entity:type_name -> controlplane.v1.ScopedEntity - 37, // 43: controlplane.v1.APITokenItem.created_at:type_name -> google.protobuf.Timestamp - 37, // 44: controlplane.v1.APITokenItem.revoked_at:type_name -> google.protobuf.Timestamp - 37, // 45: controlplane.v1.APITokenItem.expires_at:type_name -> google.protobuf.Timestamp - 37, // 46: controlplane.v1.APITokenItem.last_used_at:type_name -> google.protobuf.Timestamp - 13, // 47: controlplane.v1.AttestationItem.PolicyEvaluationsEntry.value:type_name -> controlplane.v1.PolicyEvaluations - 31, // 48: controlplane.v1.AttestationItem.Material.annotations:type_name -> controlplane.v1.AttestationItem.Material.AnnotationsEntry - 6, // 49: controlplane.v1.WorkflowContractVersionItem.RawBody.format:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody.Format - 50, // [50:50] is the sub-list for method output_type - 50, // [50:50] is the sub-list for method input_type - 50, // [50:50] is the sub-list for extension type_name - 50, // [50:50] is the sub-list for extension extendee - 0, // [0:50] is the sub-list for field type_name + 37, // 24: controlplane.v1.WorkflowContractItem.updated_at:type_name -> google.protobuf.Timestamp + 37, // 25: controlplane.v1.WorkflowContractItem.latest_revision_created_at:type_name -> google.protobuf.Timestamp + 19, // 26: controlplane.v1.WorkflowContractItem.workflow_refs:type_name -> controlplane.v1.WorkflowRef + 18, // 27: controlplane.v1.WorkflowContractItem.scoped_entity:type_name -> controlplane.v1.ScopedEntity + 37, // 28: controlplane.v1.WorkflowContractVersionItem.created_at:type_name -> google.protobuf.Timestamp + 39, // 29: controlplane.v1.WorkflowContractVersionItem.v1:type_name -> workflowcontract.v1.CraftingSchema + 35, // 30: controlplane.v1.WorkflowContractVersionItem.raw_contract:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody + 37, // 31: controlplane.v1.User.created_at:type_name -> google.protobuf.Timestamp + 37, // 32: controlplane.v1.User.updated_at:type_name -> google.protobuf.Timestamp + 23, // 33: controlplane.v1.OrgMembershipItem.org:type_name -> controlplane.v1.OrgItem + 21, // 34: controlplane.v1.OrgMembershipItem.user:type_name -> controlplane.v1.User + 37, // 35: controlplane.v1.OrgMembershipItem.created_at:type_name -> google.protobuf.Timestamp + 37, // 36: controlplane.v1.OrgMembershipItem.updated_at:type_name -> google.protobuf.Timestamp + 1, // 37: controlplane.v1.OrgMembershipItem.role:type_name -> controlplane.v1.MembershipRole + 37, // 38: controlplane.v1.OrgItem.created_at:type_name -> google.protobuf.Timestamp + 37, // 39: controlplane.v1.OrgItem.updated_at:type_name -> google.protobuf.Timestamp + 7, // 40: controlplane.v1.OrgItem.default_policy_violation_strategy:type_name -> controlplane.v1.OrgItem.PolicyViolationBlockingStrategy + 37, // 41: controlplane.v1.CASBackendItem.created_at:type_name -> google.protobuf.Timestamp + 37, // 42: controlplane.v1.CASBackendItem.validated_at:type_name -> google.protobuf.Timestamp + 8, // 43: controlplane.v1.CASBackendItem.validation_status:type_name -> controlplane.v1.CASBackendItem.ValidationStatus + 36, // 44: controlplane.v1.CASBackendItem.limits:type_name -> controlplane.v1.CASBackendItem.Limits + 18, // 45: controlplane.v1.APITokenItem.scoped_entity:type_name -> controlplane.v1.ScopedEntity + 37, // 46: controlplane.v1.APITokenItem.created_at:type_name -> google.protobuf.Timestamp + 37, // 47: controlplane.v1.APITokenItem.revoked_at:type_name -> google.protobuf.Timestamp + 37, // 48: controlplane.v1.APITokenItem.expires_at:type_name -> google.protobuf.Timestamp + 37, // 49: controlplane.v1.APITokenItem.last_used_at:type_name -> google.protobuf.Timestamp + 13, // 50: controlplane.v1.AttestationItem.PolicyEvaluationsEntry.value:type_name -> controlplane.v1.PolicyEvaluations + 31, // 51: controlplane.v1.AttestationItem.Material.annotations:type_name -> controlplane.v1.AttestationItem.Material.AnnotationsEntry + 6, // 52: controlplane.v1.WorkflowContractVersionItem.RawBody.format:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody.Format + 53, // [53:53] is the sub-list for method output_type + 53, // [53:53] is the sub-list for method input_type + 53, // [53:53] is the sub-list for extension type_name + 53, // [53:53] is the sub-list for extension extendee + 0, // [0:53] is the sub-list for field type_name } func init() { file_controlplane_v1_response_messages_proto_init() } diff --git a/app/controlplane/api/controlplane/v1/response_messages.proto b/app/controlplane/api/controlplane/v1/response_messages.proto index 43810ca74..6f48fa33f 100644 --- a/app/controlplane/api/controlplane/v1/response_messages.proto +++ b/app/controlplane/api/controlplane/v1/response_messages.proto @@ -171,6 +171,7 @@ message WorkflowContractItem { string name = 2; string description = 6; google.protobuf.Timestamp created_at = 3; + google.protobuf.Timestamp updated_at = 10; int32 latest_revision = 4; google.protobuf.Timestamp latest_revision_created_at = 8; // Workflows associated with this contract @@ -234,6 +235,7 @@ message User { string id = 1; string email = 2; google.protobuf.Timestamp created_at = 3; + google.protobuf.Timestamp updated_at = 6; string first_name = 4; string last_name = 5; } @@ -261,6 +263,7 @@ message OrgItem { string id = 1; string name = 2; google.protobuf.Timestamp created_at = 3; + google.protobuf.Timestamp updated_at = 6; PolicyViolationBlockingStrategy default_policy_violation_strategy = 4; repeated string policy_allowed_hostnames = 5; diff --git a/app/controlplane/api/controlplane/v1/user.pb.go b/app/controlplane/api/controlplane/v1/user.pb.go index 28b4a42ed..e51fcd594 100644 --- a/app/controlplane/api/controlplane/v1/user.pb.go +++ b/app/controlplane/api/controlplane/v1/user.pb.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/app/controlplane/api/controlplane/v1/user.proto b/app/controlplane/api/controlplane/v1/user.proto index 881bda578..056f041b7 100644 --- a/app/controlplane/api/controlplane/v1/user.proto +++ b/app/controlplane/api/controlplane/v1/user.proto @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/app/controlplane/api/controlplane/v1/user_grpc.pb.go b/app/controlplane/api/controlplane/v1/user_grpc.pb.go index 69fae47a6..4563863c1 100644 --- a/app/controlplane/api/controlplane/v1/user_grpc.pb.go +++ b/app/controlplane/api/controlplane/v1/user_grpc.pb.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts b/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts index 38e0e2b50..7c15bda07 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts @@ -434,6 +434,7 @@ export interface WorkflowContractItem { name: string; description: string; createdAt?: Date; + updatedAt?: Date; latestRevision: number; latestRevisionCreatedAt?: Date; /** @@ -535,6 +536,7 @@ export interface User { id: string; email: string; createdAt?: Date; + updatedAt?: Date; firstName: string; lastName: string; } @@ -553,6 +555,7 @@ export interface OrgItem { id: string; name: string; createdAt?: Date; + updatedAt?: Date; defaultPolicyViolationStrategy: OrgItem_PolicyViolationBlockingStrategy; policyAllowedHostnames: string[]; } @@ -2820,6 +2823,7 @@ function createBaseWorkflowContractItem(): WorkflowContractItem { name: "", description: "", createdAt: undefined, + updatedAt: undefined, latestRevision: 0, latestRevisionCreatedAt: undefined, workflowNames: [], @@ -2842,6 +2846,9 @@ export const WorkflowContractItem = { if (message.createdAt !== undefined) { Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(26).fork()).ldelim(); } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(82).fork()).ldelim(); + } if (message.latestRevision !== 0) { writer.uint32(32).int32(message.latestRevision); } @@ -2895,6 +2902,13 @@ export const WorkflowContractItem = { message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); continue; + case 10: + if (tag !== 82) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; case 4: if (tag !== 32) { break; @@ -2945,6 +2959,7 @@ export const WorkflowContractItem = { name: isSet(object.name) ? String(object.name) : "", description: isSet(object.description) ? String(object.description) : "", createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, latestRevision: isSet(object.latestRevision) ? Number(object.latestRevision) : 0, latestRevisionCreatedAt: isSet(object.latestRevisionCreatedAt) ? fromJsonTimestamp(object.latestRevisionCreatedAt) @@ -2963,6 +2978,7 @@ export const WorkflowContractItem = { message.name !== undefined && (obj.name = message.name); message.description !== undefined && (obj.description = message.description); message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); message.latestRevision !== undefined && (obj.latestRevision = Math.round(message.latestRevision)); message.latestRevisionCreatedAt !== undefined && (obj.latestRevisionCreatedAt = message.latestRevisionCreatedAt.toISOString()); @@ -2991,6 +3007,7 @@ export const WorkflowContractItem = { message.name = object.name ?? ""; message.description = object.description ?? ""; message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; message.latestRevision = object.latestRevision ?? 0; message.latestRevisionCreatedAt = object.latestRevisionCreatedAt ?? undefined; message.workflowNames = object.workflowNames?.map((e) => e) || []; @@ -3376,7 +3393,7 @@ export const WorkflowContractVersionItem_RawBody = { }; function createBaseUser(): User { - return { id: "", email: "", createdAt: undefined, firstName: "", lastName: "" }; + return { id: "", email: "", createdAt: undefined, updatedAt: undefined, firstName: "", lastName: "" }; } export const User = { @@ -3390,6 +3407,9 @@ export const User = { if (message.createdAt !== undefined) { Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(26).fork()).ldelim(); } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(50).fork()).ldelim(); + } if (message.firstName !== "") { writer.uint32(34).string(message.firstName); } @@ -3427,6 +3447,13 @@ export const User = { message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); continue; + case 6: + if (tag !== 50) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; case 4: if (tag !== 34) { break; @@ -3455,6 +3482,7 @@ export const User = { id: isSet(object.id) ? String(object.id) : "", email: isSet(object.email) ? String(object.email) : "", createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, firstName: isSet(object.firstName) ? String(object.firstName) : "", lastName: isSet(object.lastName) ? String(object.lastName) : "", }; @@ -3465,6 +3493,7 @@ export const User = { message.id !== undefined && (obj.id = message.id); message.email !== undefined && (obj.email = message.email); message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); message.firstName !== undefined && (obj.firstName = message.firstName); message.lastName !== undefined && (obj.lastName = message.lastName); return obj; @@ -3479,6 +3508,7 @@ export const User = { message.id = object.id ?? ""; message.email = object.email ?? ""; message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; message.firstName = object.firstName ?? ""; message.lastName = object.lastName ?? ""; return message; @@ -3630,7 +3660,14 @@ export const OrgMembershipItem = { }; function createBaseOrgItem(): OrgItem { - return { id: "", name: "", createdAt: undefined, defaultPolicyViolationStrategy: 0, policyAllowedHostnames: [] }; + return { + id: "", + name: "", + createdAt: undefined, + updatedAt: undefined, + defaultPolicyViolationStrategy: 0, + policyAllowedHostnames: [], + }; } export const OrgItem = { @@ -3644,6 +3681,9 @@ export const OrgItem = { if (message.createdAt !== undefined) { Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(26).fork()).ldelim(); } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(50).fork()).ldelim(); + } if (message.defaultPolicyViolationStrategy !== 0) { writer.uint32(32).int32(message.defaultPolicyViolationStrategy); } @@ -3681,6 +3721,13 @@ export const OrgItem = { message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); continue; + case 6: + if (tag !== 50) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; case 4: if (tag !== 32) { break; @@ -3709,6 +3756,7 @@ export const OrgItem = { id: isSet(object.id) ? String(object.id) : "", name: isSet(object.name) ? String(object.name) : "", createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, defaultPolicyViolationStrategy: isSet(object.defaultPolicyViolationStrategy) ? orgItem_PolicyViolationBlockingStrategyFromJSON(object.defaultPolicyViolationStrategy) : 0, @@ -3723,6 +3771,7 @@ export const OrgItem = { message.id !== undefined && (obj.id = message.id); message.name !== undefined && (obj.name = message.name); message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); message.defaultPolicyViolationStrategy !== undefined && (obj.defaultPolicyViolationStrategy = orgItem_PolicyViolationBlockingStrategyToJSON( message.defaultPolicyViolationStrategy, @@ -3744,6 +3793,7 @@ export const OrgItem = { message.id = object.id ?? ""; message.name = object.name ?? ""; message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; message.defaultPolicyViolationStrategy = object.defaultPolicyViolationStrategy ?? 0; message.policyAllowedHostnames = object.policyAllowedHostnames?.map((e) => e) || []; return message; diff --git a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts index d59b21da4..0d2d2fb32 100644 --- a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts +++ b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts @@ -30,7 +30,7 @@ export enum Edition { EDITION_2024 = 1001, /** * EDITION_1_TEST_ONLY - Placeholder editions for testing feature resolution. These should not be - * used or relied on outside of tests. + * used or relyed on outside of tests. */ EDITION_1_TEST_ONLY = 1, EDITION_2_TEST_ONLY = 2, @@ -875,13 +875,12 @@ export interface MessageOptions { export interface FieldOptions { /** - * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of - * type "bytes" in the open source release. - * TODO: make ctype actually deprecated. + * type "bytes" in the open source release -- sorry, we'll try to include + * other types in a future version! */ ctype: FieldOptions_CType; /** @@ -1053,7 +1052,11 @@ export function fieldOptions_JSTypeToJSON(object: FieldOptions_JSType): string { } } -/** If set to RETENTION_SOURCE, the option will be omitted from the binary. */ +/** + * If set to RETENTION_SOURCE, the option will be omitted from the binary. + * Note: as of January 2023, support for this is in progress and does not yet + * have an effect (b/264593489). + */ export enum FieldOptions_OptionRetention { RETENTION_UNKNOWN = 0, RETENTION_RUNTIME = 1, @@ -1096,7 +1099,8 @@ export function fieldOptions_OptionRetentionToJSON(object: FieldOptions_OptionRe /** * This indicates the types of entities that the field may apply to when used * as an option. If it is unset, then the field may be freely used as an - * option on any kind of entity. + * option on any kind of entity. Note: as of January 2023, support for this is + * in progress and does not yet have an effect (b/264593489). */ export enum FieldOptions_OptionTargetType { TARGET_TYPE_UNKNOWN = 0, diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.jsonschema.json index 5efc6e0b1..b3142d742 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.jsonschema.json @@ -29,6 +29,9 @@ "type": "string" }, "type": "array" + }, + "^(updated_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" } }, "properties": { @@ -64,6 +67,9 @@ "type": "string" }, "type": "array" + }, + "updatedAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" } }, "title": "Org Item", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.schema.json index 587b5c52b..1dcd00f8d 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.OrgItem.schema.json @@ -29,6 +29,9 @@ "type": "string" }, "type": "array" + }, + "^(updatedAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json" } }, "properties": { @@ -64,6 +67,9 @@ "type": "string" }, "type": "array" + }, + "updated_at": { + "$ref": "google.protobuf.Timestamp.schema.json" } }, "title": "Org Item", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.User.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.User.jsonschema.json index 79732db9d..c441c984f 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.User.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.User.jsonschema.json @@ -11,6 +11,9 @@ }, "^(last_name)$": { "type": "string" + }, + "^(updated_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" } }, "properties": { @@ -28,6 +31,9 @@ }, "lastName": { "type": "string" + }, + "updatedAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" } }, "title": "User", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.User.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.User.schema.json index 0b37fb48b..4943ad921 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.User.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.User.schema.json @@ -11,6 +11,9 @@ }, "^(lastName)$": { "type": "string" + }, + "^(updatedAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json" } }, "properties": { @@ -28,6 +31,9 @@ }, "last_name": { "type": "string" + }, + "updated_at": { + "$ref": "google.protobuf.Timestamp.schema.json" } }, "title": "User", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.jsonschema.json index 4b840f5ab..4ad956f73 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.jsonschema.json @@ -18,6 +18,9 @@ "$ref": "controlplane.v1.ScopedEntity.jsonschema.json", "description": "wether the contract is scoped to an entity in the organization" }, + "^(updated_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" + }, "^(workflow_names)$": { "description": "Workflows associated with this contract", "items": { @@ -57,6 +60,9 @@ "$ref": "controlplane.v1.ScopedEntity.jsonschema.json", "description": "wether the contract is scoped to an entity in the organization" }, + "updatedAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json" + }, "workflowNames": { "description": "Workflows associated with this contract", "items": { diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.schema.json index 675fad47e..e35955a94 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.WorkflowContractItem.schema.json @@ -18,6 +18,9 @@ "$ref": "controlplane.v1.ScopedEntity.schema.json", "description": "wether the contract is scoped to an entity in the organization" }, + "^(updatedAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json" + }, "^(workflowNames)$": { "description": "Workflows associated with this contract", "items": { @@ -57,6 +60,9 @@ "$ref": "controlplane.v1.ScopedEntity.schema.json", "description": "wether the contract is scoped to an entity in the organization" }, + "updated_at": { + "$ref": "google.protobuf.Timestamp.schema.json" + }, "workflow_names": { "description": "Workflows associated with this contract", "items": { diff --git a/app/controlplane/internal/service/context.go b/app/controlplane/internal/service/context.go index 5929b8d41..021e768ca 100644 --- a/app/controlplane/internal/service/context.go +++ b/app/controlplane/internal/service/context.go @@ -118,13 +118,17 @@ func (s *ContextService) Current(ctx context.Context, _ *pb.ContextServiceCurren func bizOrgToPb(m *biz.Organization) *pb.OrgItem { return &pb.OrgItem{Id: m.ID, Name: m.Name, CreatedAt: timestamppb.New(*m.CreatedAt), + UpdatedAt: timestamppb.New(*m.UpdatedAt), DefaultPolicyViolationStrategy: bizPolicyViolationBlockingStrategyToPb(m.BlockOnPolicyViolation), PolicyAllowedHostnames: m.PoliciesAllowedHostnames, } } func bizUserToPb(u *biz.User) *pb.User { - return &pb.User{Id: u.ID, Email: u.Email, CreatedAt: timestamppb.New(*u.CreatedAt), FirstName: u.FirstName, LastName: u.LastName} + return &pb.User{Id: u.ID, Email: u.Email, + CreatedAt: timestamppb.New(*u.CreatedAt), FirstName: u.FirstName, LastName: u.LastName, + UpdatedAt: timestamppb.New(*u.UpdatedAt), + } } func bizPolicyViolationBlockingStrategyToPb(blockOnPolicyViolation bool) pb.OrgItem_PolicyViolationBlockingStrategy { diff --git a/app/controlplane/internal/service/user.go b/app/controlplane/internal/service/user.go index 60bfc00c8..bba3e1d2b 100644 --- a/app/controlplane/internal/service/user.go +++ b/app/controlplane/internal/service/user.go @@ -99,6 +99,7 @@ func bizMembershipToPb(m *biz.Membership) *pb.OrgMembershipItem { item := &pb.OrgMembershipItem{ Id: m.ID.String(), Current: m.Current, CreatedAt: timestamppb.New(*m.CreatedAt), + UpdatedAt: timestamppb.New(*m.UpdatedAt), Org: bizOrgToPb(m.Org), Role: bizRoleToPb(m.Role), } diff --git a/app/controlplane/internal/service/workflowcontract.go b/app/controlplane/internal/service/workflowcontract.go index 9438c2caa..96de16897 100644 --- a/app/controlplane/internal/service/workflowcontract.go +++ b/app/controlplane/internal/service/workflowcontract.go @@ -229,6 +229,7 @@ func bizWorkFlowContractToPb(schema *biz.WorkflowContract) *pb.WorkflowContractI result := &pb.WorkflowContractItem{ Id: schema.ID.String(), CreatedAt: timestamppb.New(*schema.CreatedAt), + UpdatedAt: timestamppb.New(*schema.UpdatedAt), Name: schema.Name, LatestRevision: int32(schema.LatestRevision), LatestRevisionCreatedAt: timestamppb.New(*schema.LatestRevisionCreatedAt), diff --git a/app/controlplane/pkg/biz/organization.go b/app/controlplane/pkg/biz/organization.go index f231e081f..9890cfefd 100644 --- a/app/controlplane/pkg/biz/organization.go +++ b/app/controlplane/pkg/biz/organization.go @@ -34,6 +34,7 @@ import ( type Organization struct { ID, Name string CreatedAt *time.Time + UpdatedAt *time.Time // BlockOnPolicyViolation blocks the workflow run if policy evaluation fails BlockOnPolicyViolation bool // PoliciesAllowedHostnames is an array of hostnames that are allowed to be used in the policies diff --git a/app/controlplane/pkg/biz/user.go b/app/controlplane/pkg/biz/user.go index 883122506..37af519e6 100644 --- a/app/controlplane/pkg/biz/user.go +++ b/app/controlplane/pkg/biz/user.go @@ -38,6 +38,7 @@ type User struct { LastName string Email string CreatedAt *time.Time + UpdatedAt *time.Time HasRestrictedAccess *bool } diff --git a/app/controlplane/pkg/biz/workflowcontract.go b/app/controlplane/pkg/biz/workflowcontract.go index ecb2c56d4..801e8c341 100644 --- a/app/controlplane/pkg/biz/workflowcontract.go +++ b/app/controlplane/pkg/biz/workflowcontract.go @@ -39,6 +39,7 @@ type WorkflowContract struct { LatestRevision int LatestRevisionCreatedAt *time.Time CreatedAt *time.Time + UpdatedAt *time.Time // WorkflowRefs is the list of workflows associated with this contract WorkflowRefs []*WorkflowRef // entity the contract is scoped to, if not set it's scoped to the organization diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/20250808164000.sql b/app/controlplane/pkg/data/ent/migrate/migrations/20250808164000.sql new file mode 100644 index 000000000..65fc971b5 --- /dev/null +++ b/app/controlplane/pkg/data/ent/migrate/migrations/20250808164000.sql @@ -0,0 +1,3 @@ +-- Modify "users" table +ALTER TABLE "users" ADD COLUMN "updated_at" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP; +UPDATE "users" SET "updated_at" = "created_at"; diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/20250808164400.sql b/app/controlplane/pkg/data/ent/migrate/migrations/20250808164400.sql new file mode 100644 index 000000000..e3e32781e --- /dev/null +++ b/app/controlplane/pkg/data/ent/migrate/migrations/20250808164400.sql @@ -0,0 +1,5 @@ +-- Modify "workflow_contracts" table +ALTER TABLE "workflow_contracts" ADD COLUMN "updated_at" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP; + +UPDATE "workflow_contracts" SET "updated_at" = "created_at"; + diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/20250808165202.sql b/app/controlplane/pkg/data/ent/migrate/migrations/20250808165202.sql new file mode 100644 index 000000000..ad4b71e53 --- /dev/null +++ b/app/controlplane/pkg/data/ent/migrate/migrations/20250808165202.sql @@ -0,0 +1,4 @@ +-- Modify "organizations" table +ALTER TABLE "organizations" ADD COLUMN "updated_at" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP; + +UPDATE "organizations" SET "updated_at" = "created_at"; \ No newline at end of file diff --git a/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum b/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum index 76f7342cf..5cebbfdf9 100644 --- a/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum +++ b/app/controlplane/pkg/data/ent/migrate/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:MV6bti+wV7UeXF/Nybo/cGCkofX4a6Eq3JsxtdaQwD4= +h1:CR4ZZX0wKUI9H+dldKzHZ2IkDpnRSTyssXoCkVJk31g= 20230706165452_init-schema.sql h1:VvqbNFEQnCvUVyj2iDYVQQxDM0+sSXqocpt/5H64k8M= 20230710111950-cas-backend.sql h1:A8iBuSzZIEbdsv9ipBtscZQuaBp3V5/VMw7eZH6GX+g= 20230712094107-cas-backends-workflow-runs.sql h1:a5rzxpVGyd56nLRSsKrmCFc9sebg65RWzLghKHh5xvI= @@ -104,3 +104,6 @@ h1:MV6bti+wV7UeXF/Nybo/cGCkofX4a6Eq3JsxtdaQwD4= 20250805225449.sql h1:L1M7mR2PuAVoT7bDo9rAoy+eUN7C25sm5Yj1o+zlvhk= 20250806210344.sql h1:1TYAuhyqB0kdaBbYT3DZ7cUKKXWqRZ5axAeiZ2lupJA= 20250807205444.sql h1:Dny88Wcw08mFl8XBsu8BKiVTkhc/vRGob3NvhO62uno= +20250808164000.sql h1:T6Yt5JhbfB+7iY4WPpeCEsT3G5wplxTBB64De3ZXNus= +20250808164400.sql h1:r7S2LM8d3kbKQ7WNuggjvmNw3kcccx0rYzzklw8Q2I8= +20250808165202.sql h1:Oreh9FpYwo/cdcs3Oza/+ACzScXeTRBGIEvua8RqoLo= diff --git a/app/controlplane/pkg/data/ent/migrate/schema.go b/app/controlplane/pkg/data/ent/migrate/schema.go index c8e9d8f58..360ab5dbf 100644 --- a/app/controlplane/pkg/data/ent/migrate/schema.go +++ b/app/controlplane/pkg/data/ent/migrate/schema.go @@ -415,6 +415,7 @@ var ( {Name: "id", Type: field.TypeUUID, Unique: true}, {Name: "name", Type: field.TypeString, Unique: true}, {Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, + {Name: "updated_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, {Name: "block_on_policy_violation", Type: field.TypeBool, Default: false}, {Name: "policies_allowed_hostnames", Type: field.TypeJSON, Nullable: true}, } @@ -553,6 +554,7 @@ var ( {Name: "id", Type: field.TypeUUID, Unique: true}, {Name: "email", Type: field.TypeString, Unique: true}, {Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, + {Name: "updated_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, {Name: "has_restricted_access", Type: field.TypeBool, Nullable: true}, {Name: "first_name", Type: field.TypeString, Nullable: true}, {Name: "last_name", Type: field.TypeString, Nullable: true}, @@ -566,7 +568,7 @@ var ( { Name: "user_has_restricted_access", Unique: false, - Columns: []*schema.Column{UsersColumns[3]}, + Columns: []*schema.Column{UsersColumns[4]}, }, }, } @@ -659,6 +661,7 @@ var ( {Name: "id", Type: field.TypeUUID, Unique: true}, {Name: "name", Type: field.TypeString}, {Name: "created_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, + {Name: "updated_at", Type: field.TypeTime, Default: "CURRENT_TIMESTAMP"}, {Name: "deleted_at", Type: field.TypeTime, Nullable: true}, {Name: "description", Type: field.TypeString, Nullable: true}, {Name: "scoped_resource_type", Type: field.TypeEnum, Nullable: true, Enums: []string{"project", "org"}}, @@ -673,7 +676,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "workflow_contracts_organizations_workflow_contracts", - Columns: []*schema.Column{WorkflowContractsColumns[7]}, + Columns: []*schema.Column{WorkflowContractsColumns[8]}, RefColumns: []*schema.Column{OrganizationsColumns[0]}, OnDelete: schema.Cascade, }, @@ -682,7 +685,7 @@ var ( { Name: "workflowcontract_name_organization_workflow_contracts", Unique: true, - Columns: []*schema.Column{WorkflowContractsColumns[1], WorkflowContractsColumns[7]}, + Columns: []*schema.Column{WorkflowContractsColumns[1], WorkflowContractsColumns[8]}, Annotation: &entsql.IndexAnnotation{ Where: "deleted_at IS NULL", }, diff --git a/app/controlplane/pkg/data/ent/mutation.go b/app/controlplane/pkg/data/ent/mutation.go index 358ffa851..023822fd9 100644 --- a/app/controlplane/pkg/data/ent/mutation.go +++ b/app/controlplane/pkg/data/ent/mutation.go @@ -8484,6 +8484,7 @@ type OrganizationMutation struct { id *uuid.UUID name *string created_at *time.Time + updated_at *time.Time block_on_policy_violation *bool policies_allowed_hostnames *[]string appendpolicies_allowed_hostnames []string @@ -8693,6 +8694,42 @@ func (m *OrganizationMutation) ResetCreatedAt() { m.created_at = nil } +// SetUpdatedAt sets the "updated_at" field. +func (m *OrganizationMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *OrganizationMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the Organization entity. +// If the Organization object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *OrganizationMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *OrganizationMutation) ResetUpdatedAt() { + m.updated_at = nil +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (m *OrganizationMutation) SetBlockOnPolicyViolation(b bool) { m.block_on_policy_violation = &b @@ -9260,13 +9297,16 @@ func (m *OrganizationMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *OrganizationMutation) Fields() []string { - fields := make([]string, 0, 4) + fields := make([]string, 0, 5) if m.name != nil { fields = append(fields, organization.FieldName) } if m.created_at != nil { fields = append(fields, organization.FieldCreatedAt) } + if m.updated_at != nil { + fields = append(fields, organization.FieldUpdatedAt) + } if m.block_on_policy_violation != nil { fields = append(fields, organization.FieldBlockOnPolicyViolation) } @@ -9285,6 +9325,8 @@ func (m *OrganizationMutation) Field(name string) (ent.Value, bool) { return m.Name() case organization.FieldCreatedAt: return m.CreatedAt() + case organization.FieldUpdatedAt: + return m.UpdatedAt() case organization.FieldBlockOnPolicyViolation: return m.BlockOnPolicyViolation() case organization.FieldPoliciesAllowedHostnames: @@ -9302,6 +9344,8 @@ func (m *OrganizationMutation) OldField(ctx context.Context, name string) (ent.V return m.OldName(ctx) case organization.FieldCreatedAt: return m.OldCreatedAt(ctx) + case organization.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) case organization.FieldBlockOnPolicyViolation: return m.OldBlockOnPolicyViolation(ctx) case organization.FieldPoliciesAllowedHostnames: @@ -9329,6 +9373,13 @@ func (m *OrganizationMutation) SetField(name string, value ent.Value) error { } m.SetCreatedAt(v) return nil + case organization.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil case organization.FieldBlockOnPolicyViolation: v, ok := value.(bool) if !ok { @@ -9407,6 +9458,9 @@ func (m *OrganizationMutation) ResetField(name string) error { case organization.FieldCreatedAt: m.ResetCreatedAt() return nil + case organization.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil case organization.FieldBlockOnPolicyViolation: m.ResetBlockOnPolicyViolation() return nil @@ -12967,6 +13021,7 @@ type UserMutation struct { id *uuid.UUID email *string created_at *time.Time + updated_at *time.Time has_restricted_access *bool first_name *string last_name *string @@ -13158,6 +13213,42 @@ func (m *UserMutation) ResetCreatedAt() { m.created_at = nil } +// SetUpdatedAt sets the "updated_at" field. +func (m *UserMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *UserMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the User entity. +// If the User object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *UserMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *UserMutation) ResetUpdatedAt() { + m.updated_at = nil +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (m *UserMutation) SetHasRestrictedAccess(b bool) { m.has_restricted_access = &b @@ -13447,13 +13538,16 @@ func (m *UserMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *UserMutation) Fields() []string { - fields := make([]string, 0, 5) + fields := make([]string, 0, 6) if m.email != nil { fields = append(fields, user.FieldEmail) } if m.created_at != nil { fields = append(fields, user.FieldCreatedAt) } + if m.updated_at != nil { + fields = append(fields, user.FieldUpdatedAt) + } if m.has_restricted_access != nil { fields = append(fields, user.FieldHasRestrictedAccess) } @@ -13475,6 +13569,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) { return m.Email() case user.FieldCreatedAt: return m.CreatedAt() + case user.FieldUpdatedAt: + return m.UpdatedAt() case user.FieldHasRestrictedAccess: return m.HasRestrictedAccess() case user.FieldFirstName: @@ -13494,6 +13590,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er return m.OldEmail(ctx) case user.FieldCreatedAt: return m.OldCreatedAt(ctx) + case user.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) case user.FieldHasRestrictedAccess: return m.OldHasRestrictedAccess(ctx) case user.FieldFirstName: @@ -13523,6 +13621,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error { } m.SetCreatedAt(v) return nil + case user.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil case user.FieldHasRestrictedAccess: v, ok := value.(bool) if !ok { @@ -13620,6 +13725,9 @@ func (m *UserMutation) ResetField(name string) error { case user.FieldCreatedAt: m.ResetCreatedAt() return nil + case user.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil case user.FieldHasRestrictedAccess: m.ResetHasRestrictedAccess() return nil @@ -15436,6 +15544,7 @@ type WorkflowContractMutation struct { id *uuid.UUID name *string created_at *time.Time + updated_at *time.Time deleted_at *time.Time description *string scoped_resource_type *biz.ContractScope @@ -15630,6 +15739,42 @@ func (m *WorkflowContractMutation) ResetCreatedAt() { m.created_at = nil } +// SetUpdatedAt sets the "updated_at" field. +func (m *WorkflowContractMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t +} + +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *WorkflowContractMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at + if v == nil { + return + } + return *v, true +} + +// OldUpdatedAt returns the old "updated_at" field's value of the WorkflowContract entity. +// If the WorkflowContract object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *WorkflowContractMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldUpdatedAt requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) + } + return oldValue.UpdatedAt, nil +} + +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *WorkflowContractMutation) ResetUpdatedAt() { + m.updated_at = nil +} + // SetDeletedAt sets the "deleted_at" field. func (m *WorkflowContractMutation) SetDeletedAt(t time.Time) { m.deleted_at = &t @@ -16007,13 +16152,16 @@ func (m *WorkflowContractMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *WorkflowContractMutation) Fields() []string { - fields := make([]string, 0, 6) + fields := make([]string, 0, 7) if m.name != nil { fields = append(fields, workflowcontract.FieldName) } if m.created_at != nil { fields = append(fields, workflowcontract.FieldCreatedAt) } + if m.updated_at != nil { + fields = append(fields, workflowcontract.FieldUpdatedAt) + } if m.deleted_at != nil { fields = append(fields, workflowcontract.FieldDeletedAt) } @@ -16038,6 +16186,8 @@ func (m *WorkflowContractMutation) Field(name string) (ent.Value, bool) { return m.Name() case workflowcontract.FieldCreatedAt: return m.CreatedAt() + case workflowcontract.FieldUpdatedAt: + return m.UpdatedAt() case workflowcontract.FieldDeletedAt: return m.DeletedAt() case workflowcontract.FieldDescription: @@ -16059,6 +16209,8 @@ func (m *WorkflowContractMutation) OldField(ctx context.Context, name string) (e return m.OldName(ctx) case workflowcontract.FieldCreatedAt: return m.OldCreatedAt(ctx) + case workflowcontract.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) case workflowcontract.FieldDeletedAt: return m.OldDeletedAt(ctx) case workflowcontract.FieldDescription: @@ -16090,6 +16242,13 @@ func (m *WorkflowContractMutation) SetField(name string, value ent.Value) error } m.SetCreatedAt(v) return nil + case workflowcontract.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil case workflowcontract.FieldDeletedAt: v, ok := value.(time.Time) if !ok { @@ -16200,6 +16359,9 @@ func (m *WorkflowContractMutation) ResetField(name string) error { case workflowcontract.FieldCreatedAt: m.ResetCreatedAt() return nil + case workflowcontract.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil case workflowcontract.FieldDeletedAt: m.ResetDeletedAt() return nil diff --git a/app/controlplane/pkg/data/ent/organization.go b/app/controlplane/pkg/data/ent/organization.go index 3f4517511..7425e4372 100644 --- a/app/controlplane/pkg/data/ent/organization.go +++ b/app/controlplane/pkg/data/ent/organization.go @@ -23,6 +23,8 @@ type Organization struct { Name string `json:"name,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` // BlockOnPolicyViolation holds the value of the "block_on_policy_violation" field. BlockOnPolicyViolation bool `json:"block_on_policy_violation,omitempty"` // PoliciesAllowedHostnames holds the value of the "policies_allowed_hostnames" field. @@ -139,7 +141,7 @@ func (*Organization) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullBool) case organization.FieldName: values[i] = new(sql.NullString) - case organization.FieldCreatedAt: + case organization.FieldCreatedAt, organization.FieldUpdatedAt: values[i] = new(sql.NullTime) case organization.FieldID: values[i] = new(uuid.UUID) @@ -176,6 +178,12 @@ func (o *Organization) assignValues(columns []string, values []any) error { } else if value.Valid { o.CreatedAt = value.Time } + case organization.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + o.UpdatedAt = value.Time + } case organization.FieldBlockOnPolicyViolation: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field block_on_policy_violation", values[i]) @@ -272,6 +280,9 @@ func (o *Organization) String() string { builder.WriteString("created_at=") builder.WriteString(o.CreatedAt.Format(time.ANSIC)) builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(o.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") builder.WriteString("block_on_policy_violation=") builder.WriteString(fmt.Sprintf("%v", o.BlockOnPolicyViolation)) builder.WriteString(", ") diff --git a/app/controlplane/pkg/data/ent/organization/organization.go b/app/controlplane/pkg/data/ent/organization/organization.go index 7c49e7437..621b61ccd 100644 --- a/app/controlplane/pkg/data/ent/organization/organization.go +++ b/app/controlplane/pkg/data/ent/organization/organization.go @@ -19,6 +19,8 @@ const ( FieldName = "name" // FieldCreatedAt holds the string denoting the created_at field in the database. FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" // FieldBlockOnPolicyViolation holds the string denoting the block_on_policy_violation field in the database. FieldBlockOnPolicyViolation = "block_on_policy_violation" // FieldPoliciesAllowedHostnames holds the string denoting the policies_allowed_hostnames field in the database. @@ -104,6 +106,7 @@ var Columns = []string{ FieldID, FieldName, FieldCreatedAt, + FieldUpdatedAt, FieldBlockOnPolicyViolation, FieldPoliciesAllowedHostnames, } @@ -121,6 +124,8 @@ func ValidColumn(column string) bool { var ( // DefaultCreatedAt holds the default value on creation for the "created_at" field. DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time // DefaultBlockOnPolicyViolation holds the default value on creation for the "block_on_policy_violation" field. DefaultBlockOnPolicyViolation bool // DefaultID holds the default value on creation for the "id" field. @@ -145,6 +150,11 @@ func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() } +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + // ByBlockOnPolicyViolation orders the results by the block_on_policy_violation field. func ByBlockOnPolicyViolation(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldBlockOnPolicyViolation, opts...).ToFunc() diff --git a/app/controlplane/pkg/data/ent/organization/where.go b/app/controlplane/pkg/data/ent/organization/where.go index 794ef64b7..61d77a4d7 100644 --- a/app/controlplane/pkg/data/ent/organization/where.go +++ b/app/controlplane/pkg/data/ent/organization/where.go @@ -66,6 +66,11 @@ func CreatedAt(v time.Time) predicate.Organization { return predicate.Organization(sql.FieldEQ(FieldCreatedAt, v)) } +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldEQ(FieldUpdatedAt, v)) +} + // BlockOnPolicyViolation applies equality check predicate on the "block_on_policy_violation" field. It's identical to BlockOnPolicyViolationEQ. func BlockOnPolicyViolation(v bool) predicate.Organization { return predicate.Organization(sql.FieldEQ(FieldBlockOnPolicyViolation, v)) @@ -176,6 +181,46 @@ func CreatedAtLTE(v time.Time) predicate.Organization { return predicate.Organization(sql.FieldLTE(FieldCreatedAt, v)) } +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.Organization { + return predicate.Organization(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.Organization { + return predicate.Organization(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.Organization { + return predicate.Organization(sql.FieldLTE(FieldUpdatedAt, v)) +} + // BlockOnPolicyViolationEQ applies the EQ predicate on the "block_on_policy_violation" field. func BlockOnPolicyViolationEQ(v bool) predicate.Organization { return predicate.Organization(sql.FieldEQ(FieldBlockOnPolicyViolation, v)) diff --git a/app/controlplane/pkg/data/ent/organization_create.go b/app/controlplane/pkg/data/ent/organization_create.go index 93b7c5d5a..0a680daab 100644 --- a/app/controlplane/pkg/data/ent/organization_create.go +++ b/app/controlplane/pkg/data/ent/organization_create.go @@ -52,6 +52,20 @@ func (oc *OrganizationCreate) SetNillableCreatedAt(t *time.Time) *OrganizationCr return oc } +// SetUpdatedAt sets the "updated_at" field. +func (oc *OrganizationCreate) SetUpdatedAt(t time.Time) *OrganizationCreate { + oc.mutation.SetUpdatedAt(t) + return oc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (oc *OrganizationCreate) SetNillableUpdatedAt(t *time.Time) *OrganizationCreate { + if t != nil { + oc.SetUpdatedAt(*t) + } + return oc +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (oc *OrganizationCreate) SetBlockOnPolicyViolation(b bool) *OrganizationCreate { oc.mutation.SetBlockOnPolicyViolation(b) @@ -245,6 +259,10 @@ func (oc *OrganizationCreate) defaults() { v := organization.DefaultCreatedAt() oc.mutation.SetCreatedAt(v) } + if _, ok := oc.mutation.UpdatedAt(); !ok { + v := organization.DefaultUpdatedAt() + oc.mutation.SetUpdatedAt(v) + } if _, ok := oc.mutation.BlockOnPolicyViolation(); !ok { v := organization.DefaultBlockOnPolicyViolation oc.mutation.SetBlockOnPolicyViolation(v) @@ -263,6 +281,9 @@ func (oc *OrganizationCreate) check() error { if _, ok := oc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Organization.created_at"`)} } + if _, ok := oc.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Organization.updated_at"`)} + } if _, ok := oc.mutation.BlockOnPolicyViolation(); !ok { return &ValidationError{Name: "block_on_policy_violation", err: errors.New(`ent: missing required field "Organization.block_on_policy_violation"`)} } @@ -310,6 +331,10 @@ func (oc *OrganizationCreate) createSpec() (*Organization, *sqlgraph.CreateSpec) _spec.SetField(organization.FieldCreatedAt, field.TypeTime, value) _node.CreatedAt = value } + if value, ok := oc.mutation.UpdatedAt(); ok { + _spec.SetField(organization.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } if value, ok := oc.mutation.BlockOnPolicyViolation(); ok { _spec.SetField(organization.FieldBlockOnPolicyViolation, field.TypeBool, value) _node.BlockOnPolicyViolation = value @@ -510,6 +535,18 @@ func (u *OrganizationUpsert) UpdateName() *OrganizationUpsert { return u } +// SetUpdatedAt sets the "updated_at" field. +func (u *OrganizationUpsert) SetUpdatedAt(v time.Time) *OrganizationUpsert { + u.Set(organization.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *OrganizationUpsert) UpdateUpdatedAt() *OrganizationUpsert { + u.SetExcluded(organization.FieldUpdatedAt) + return u +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (u *OrganizationUpsert) SetBlockOnPolicyViolation(v bool) *OrganizationUpsert { u.Set(organization.FieldBlockOnPolicyViolation, v) @@ -605,6 +642,20 @@ func (u *OrganizationUpsertOne) UpdateName() *OrganizationUpsertOne { }) } +// SetUpdatedAt sets the "updated_at" field. +func (u *OrganizationUpsertOne) SetUpdatedAt(v time.Time) *OrganizationUpsertOne { + return u.Update(func(s *OrganizationUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *OrganizationUpsertOne) UpdateUpdatedAt() *OrganizationUpsertOne { + return u.Update(func(s *OrganizationUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (u *OrganizationUpsertOne) SetBlockOnPolicyViolation(v bool) *OrganizationUpsertOne { return u.Update(func(s *OrganizationUpsert) { @@ -872,6 +923,20 @@ func (u *OrganizationUpsertBulk) UpdateName() *OrganizationUpsertBulk { }) } +// SetUpdatedAt sets the "updated_at" field. +func (u *OrganizationUpsertBulk) SetUpdatedAt(v time.Time) *OrganizationUpsertBulk { + return u.Update(func(s *OrganizationUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *OrganizationUpsertBulk) UpdateUpdatedAt() *OrganizationUpsertBulk { + return u.Update(func(s *OrganizationUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (u *OrganizationUpsertBulk) SetBlockOnPolicyViolation(v bool) *OrganizationUpsertBulk { return u.Update(func(s *OrganizationUpsert) { diff --git a/app/controlplane/pkg/data/ent/organization_update.go b/app/controlplane/pkg/data/ent/organization_update.go index 60ce17c09..6e2e5f2d7 100644 --- a/app/controlplane/pkg/data/ent/organization_update.go +++ b/app/controlplane/pkg/data/ent/organization_update.go @@ -6,6 +6,7 @@ import ( "context" "errors" "fmt" + "time" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -52,6 +53,20 @@ func (ou *OrganizationUpdate) SetNillableName(s *string) *OrganizationUpdate { return ou } +// SetUpdatedAt sets the "updated_at" field. +func (ou *OrganizationUpdate) SetUpdatedAt(t time.Time) *OrganizationUpdate { + ou.mutation.SetUpdatedAt(t) + return ou +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (ou *OrganizationUpdate) SetNillableUpdatedAt(t *time.Time) *OrganizationUpdate { + if t != nil { + ou.SetUpdatedAt(*t) + } + return ou +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (ou *OrganizationUpdate) SetBlockOnPolicyViolation(b bool) *OrganizationUpdate { ou.mutation.SetBlockOnPolicyViolation(b) @@ -422,6 +437,9 @@ func (ou *OrganizationUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := ou.mutation.Name(); ok { _spec.SetField(organization.FieldName, field.TypeString, value) } + if value, ok := ou.mutation.UpdatedAt(); ok { + _spec.SetField(organization.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := ou.mutation.BlockOnPolicyViolation(); ok { _spec.SetField(organization.FieldBlockOnPolicyViolation, field.TypeBool, value) } @@ -832,6 +850,20 @@ func (ouo *OrganizationUpdateOne) SetNillableName(s *string) *OrganizationUpdate return ouo } +// SetUpdatedAt sets the "updated_at" field. +func (ouo *OrganizationUpdateOne) SetUpdatedAt(t time.Time) *OrganizationUpdateOne { + ouo.mutation.SetUpdatedAt(t) + return ouo +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (ouo *OrganizationUpdateOne) SetNillableUpdatedAt(t *time.Time) *OrganizationUpdateOne { + if t != nil { + ouo.SetUpdatedAt(*t) + } + return ouo +} + // SetBlockOnPolicyViolation sets the "block_on_policy_violation" field. func (ouo *OrganizationUpdateOne) SetBlockOnPolicyViolation(b bool) *OrganizationUpdateOne { ouo.mutation.SetBlockOnPolicyViolation(b) @@ -1232,6 +1264,9 @@ func (ouo *OrganizationUpdateOne) sqlSave(ctx context.Context) (_node *Organizat if value, ok := ouo.mutation.Name(); ok { _spec.SetField(organization.FieldName, field.TypeString, value) } + if value, ok := ouo.mutation.UpdatedAt(); ok { + _spec.SetField(organization.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := ouo.mutation.BlockOnPolicyViolation(); ok { _spec.SetField(organization.FieldBlockOnPolicyViolation, field.TypeBool, value) } diff --git a/app/controlplane/pkg/data/ent/runtime.go b/app/controlplane/pkg/data/ent/runtime.go index a30d2da45..207ebd38a 100644 --- a/app/controlplane/pkg/data/ent/runtime.go +++ b/app/controlplane/pkg/data/ent/runtime.go @@ -191,8 +191,12 @@ func init() { organizationDescCreatedAt := organizationFields[2].Descriptor() // organization.DefaultCreatedAt holds the default value on creation for the created_at field. organization.DefaultCreatedAt = organizationDescCreatedAt.Default.(func() time.Time) + // organizationDescUpdatedAt is the schema descriptor for updated_at field. + organizationDescUpdatedAt := organizationFields[3].Descriptor() + // organization.DefaultUpdatedAt holds the default value on creation for the updated_at field. + organization.DefaultUpdatedAt = organizationDescUpdatedAt.Default.(func() time.Time) // organizationDescBlockOnPolicyViolation is the schema descriptor for block_on_policy_violation field. - organizationDescBlockOnPolicyViolation := organizationFields[3].Descriptor() + organizationDescBlockOnPolicyViolation := organizationFields[4].Descriptor() // organization.DefaultBlockOnPolicyViolation holds the default value on creation for the block_on_policy_violation field. organization.DefaultBlockOnPolicyViolation = organizationDescBlockOnPolicyViolation.Default.(bool) // organizationDescID is the schema descriptor for id field. @@ -279,6 +283,10 @@ func init() { userDescCreatedAt := userFields[2].Descriptor() // user.DefaultCreatedAt holds the default value on creation for the created_at field. user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time) + // userDescUpdatedAt is the schema descriptor for updated_at field. + userDescUpdatedAt := userFields[3].Descriptor() + // user.DefaultUpdatedAt holds the default value on creation for the updated_at field. + user.DefaultUpdatedAt = userDescUpdatedAt.Default.(func() time.Time) // userDescID is the schema descriptor for id field. userDescID := userFields[1].Descriptor() // user.DefaultID holds the default value on creation for the id field. @@ -311,6 +319,10 @@ func init() { workflowcontractDescCreatedAt := workflowcontractFields[2].Descriptor() // workflowcontract.DefaultCreatedAt holds the default value on creation for the created_at field. workflowcontract.DefaultCreatedAt = workflowcontractDescCreatedAt.Default.(func() time.Time) + // workflowcontractDescUpdatedAt is the schema descriptor for updated_at field. + workflowcontractDescUpdatedAt := workflowcontractFields[3].Descriptor() + // workflowcontract.DefaultUpdatedAt holds the default value on creation for the updated_at field. + workflowcontract.DefaultUpdatedAt = workflowcontractDescUpdatedAt.Default.(func() time.Time) // workflowcontractDescID is the schema descriptor for id field. workflowcontractDescID := workflowcontractFields[0].Descriptor() // workflowcontract.DefaultID holds the default value on creation for the id field. diff --git a/app/controlplane/pkg/data/ent/schema-viz.html b/app/controlplane/pkg/data/ent/schema-viz.html index b0d4a220a..486cb3cc5 100644 --- a/app/controlplane/pkg/data/ent/schema-viz.html +++ b/app/controlplane/pkg/data/ent/schema-viz.html @@ -70,7 +70,7 @@ } - const entGraph = JSON.parse("{\"nodes\":[{\"id\":\"APIToken\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"expires_at\",\"type\":\"time.Time\"},{\"name\":\"revoked_at\",\"type\":\"time.Time\"},{\"name\":\"last_used_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Attestation\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"bundle\",\"type\":\"[]byte\"},{\"name\":\"workflowrun_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"CASBackend\",\"fields\":[{\"name\":\"location\",\"type\":\"string\"},{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"provider\",\"type\":\"biz.CASBackendProvider\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"secret_name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"validation_status\",\"type\":\"biz.CASBackendValidationStatus\"},{\"name\":\"validated_at\",\"type\":\"time.Time\"},{\"name\":\"default\",\"type\":\"bool\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"fallback\",\"type\":\"bool\"},{\"name\":\"max_blob_size_bytes\",\"type\":\"int64\"}]},{\"id\":\"CASMapping\",\"fields\":[{\"name\":\"digest\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"workflow_run_id\",\"type\":\"uuid.UUID\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Group\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"member_count\",\"type\":\"int\"}]},{\"id\":\"GroupMembership\",\"fields\":[{\"name\":\"group_id\",\"type\":\"uuid.UUID\"},{\"name\":\"user_id\",\"type\":\"uuid.UUID\"},{\"name\":\"maintainer\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"}]},{\"id\":\"Integration\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"kind\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"secret_name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"configuration\",\"type\":\"[]byte\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"}]},{\"id\":\"IntegrationAttachment\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"configuration\",\"type\":\"[]byte\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"workflow_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Membership\",\"fields\":[{\"name\":\"current\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"role\",\"type\":\"authz.Role\"},{\"name\":\"membership_type\",\"type\":\"authz.MembershipType\"},{\"name\":\"member_id\",\"type\":\"uuid.UUID\"},{\"name\":\"resource_type\",\"type\":\"authz.ResourceType\"},{\"name\":\"resource_id\",\"type\":\"uuid.UUID\"},{\"name\":\"parent_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"OrgInvitation\",\"fields\":[{\"name\":\"receiver_email\",\"type\":\"string\"},{\"name\":\"status\",\"type\":\"biz.OrgInvitationStatus\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"sender_id\",\"type\":\"uuid.UUID\"},{\"name\":\"role\",\"type\":\"authz.Role\"},{\"name\":\"context\",\"type\":\"biz.OrgInvitationContext\"}]},{\"id\":\"Organization\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"block_on_policy_violation\",\"type\":\"bool\"},{\"name\":\"policies_allowed_hostnames\",\"type\":\"[]string\"}]},{\"id\":\"Project\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"ProjectVersion\",\"fields\":[{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"},{\"name\":\"prerelease\",\"type\":\"bool\"},{\"name\":\"workflow_run_count\",\"type\":\"int\"},{\"name\":\"released_at\",\"type\":\"time.Time\"},{\"name\":\"latest\",\"type\":\"bool\"}]},{\"id\":\"Referrer\",\"fields\":[{\"name\":\"digest\",\"type\":\"string\"},{\"name\":\"kind\",\"type\":\"string\"},{\"name\":\"downloadable\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"metadata\",\"type\":\"map[string]string\"},{\"name\":\"annotations\",\"type\":\"map[string]string\"}]},{\"id\":\"RobotAccount\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"revoked_at\",\"type\":\"time.Time\"}]},{\"id\":\"User\",\"fields\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"has_restricted_access\",\"type\":\"bool\"},{\"name\":\"first_name\",\"type\":\"string\"},{\"name\":\"last_name\",\"type\":\"string\"}]},{\"id\":\"Workflow\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"project_old\",\"type\":\"string\"},{\"name\":\"team\",\"type\":\"string\"},{\"name\":\"runs_count\",\"type\":\"int\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"public\",\"type\":\"bool\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"},{\"name\":\"latest_run\",\"type\":\"uuid.UUID\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"metadata\",\"type\":\"map[string]interface {}\"}]},{\"id\":\"WorkflowContract\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"scoped_resource_type\",\"type\":\"biz.ContractScope\"},{\"name\":\"scoped_resource_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"WorkflowContractVersion\",\"fields\":[{\"name\":\"body\",\"type\":\"[]byte\"},{\"name\":\"raw_body\",\"type\":\"[]byte\"},{\"name\":\"raw_body_format\",\"type\":\"unmarshal.RawFormat\"},{\"name\":\"revision\",\"type\":\"int\"},{\"name\":\"created_at\",\"type\":\"time.Time\"}]},{\"id\":\"WorkflowRun\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"finished_at\",\"type\":\"time.Time\"},{\"name\":\"state\",\"type\":\"biz.WorkflowRunStatus\"},{\"name\":\"reason\",\"type\":\"string\"},{\"name\":\"run_url\",\"type\":\"string\"},{\"name\":\"runner_type\",\"type\":\"string\"},{\"name\":\"attestation\",\"type\":\"*dsse.Envelope\"},{\"name\":\"attestation_digest\",\"type\":\"string\"},{\"name\":\"attestation_state\",\"type\":\"[]byte\"},{\"name\":\"contract_revision_used\",\"type\":\"int\"},{\"name\":\"contract_revision_latest\",\"type\":\"int\"},{\"name\":\"version_id\",\"type\":\"uuid.UUID\"},{\"name\":\"workflow_id\",\"type\":\"uuid.UUID\"}]}],\"edges\":[{\"from\":\"APIToken\",\"to\":\"Project\",\"label\":\"project\"},{\"from\":\"CASMapping\",\"to\":\"CASBackend\",\"label\":\"cas_backend\"},{\"from\":\"CASMapping\",\"to\":\"Organization\",\"label\":\"organization\"},{\"from\":\"CASMapping\",\"to\":\"Project\",\"label\":\"project\"},{\"from\":\"GroupMembership\",\"to\":\"Group\",\"label\":\"group\"},{\"from\":\"GroupMembership\",\"to\":\"User\",\"label\":\"user\"},{\"from\":\"IntegrationAttachment\",\"to\":\"Integration\",\"label\":\"integration\"},{\"from\":\"IntegrationAttachment\",\"to\":\"Workflow\",\"label\":\"workflow\"},{\"from\":\"Membership\",\"to\":\"Membership\",\"label\":\"children\"},{\"from\":\"OrgInvitation\",\"to\":\"Organization\",\"label\":\"organization\"},{\"from\":\"OrgInvitation\",\"to\":\"User\",\"label\":\"sender\"},{\"from\":\"Organization\",\"to\":\"Membership\",\"label\":\"memberships\"},{\"from\":\"Organization\",\"to\":\"WorkflowContract\",\"label\":\"workflow_contracts\"},{\"from\":\"Organization\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"Organization\",\"to\":\"CASBackend\",\"label\":\"cas_backends\"},{\"from\":\"Organization\",\"to\":\"Integration\",\"label\":\"integrations\"},{\"from\":\"Organization\",\"to\":\"APIToken\",\"label\":\"api_tokens\"},{\"from\":\"Organization\",\"to\":\"Project\",\"label\":\"projects\"},{\"from\":\"Organization\",\"to\":\"Group\",\"label\":\"groups\"},{\"from\":\"Project\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"Project\",\"to\":\"ProjectVersion\",\"label\":\"versions\"},{\"from\":\"ProjectVersion\",\"to\":\"WorkflowRun\",\"label\":\"runs\"},{\"from\":\"Referrer\",\"to\":\"Referrer\",\"label\":\"references\"},{\"from\":\"Referrer\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"User\",\"to\":\"Membership\",\"label\":\"memberships\"},{\"from\":\"Workflow\",\"to\":\"RobotAccount\",\"label\":\"robotaccounts\"},{\"from\":\"Workflow\",\"to\":\"WorkflowRun\",\"label\":\"workflowruns\"},{\"from\":\"Workflow\",\"to\":\"WorkflowContract\",\"label\":\"contract\"},{\"from\":\"Workflow\",\"to\":\"WorkflowRun\",\"label\":\"latest_workflow_run\"},{\"from\":\"WorkflowContract\",\"to\":\"WorkflowContractVersion\",\"label\":\"versions\"},{\"from\":\"WorkflowRun\",\"to\":\"WorkflowContractVersion\",\"label\":\"contract_version\"},{\"from\":\"WorkflowRun\",\"to\":\"CASBackend\",\"label\":\"cas_backends\"},{\"from\":\"WorkflowRun\",\"to\":\"Attestation\",\"label\":\"attestation_bundle\"}]}"); + const entGraph = JSON.parse("{\"nodes\":[{\"id\":\"APIToken\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"expires_at\",\"type\":\"time.Time\"},{\"name\":\"revoked_at\",\"type\":\"time.Time\"},{\"name\":\"last_used_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Attestation\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"bundle\",\"type\":\"[]byte\"},{\"name\":\"workflowrun_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"CASBackend\",\"fields\":[{\"name\":\"location\",\"type\":\"string\"},{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"provider\",\"type\":\"biz.CASBackendProvider\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"secret_name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"validation_status\",\"type\":\"biz.CASBackendValidationStatus\"},{\"name\":\"validated_at\",\"type\":\"time.Time\"},{\"name\":\"default\",\"type\":\"bool\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"fallback\",\"type\":\"bool\"},{\"name\":\"max_blob_size_bytes\",\"type\":\"int64\"}]},{\"id\":\"CASMapping\",\"fields\":[{\"name\":\"digest\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"workflow_run_id\",\"type\":\"uuid.UUID\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Group\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"member_count\",\"type\":\"int\"}]},{\"id\":\"GroupMembership\",\"fields\":[{\"name\":\"group_id\",\"type\":\"uuid.UUID\"},{\"name\":\"user_id\",\"type\":\"uuid.UUID\"},{\"name\":\"maintainer\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"}]},{\"id\":\"Integration\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"kind\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"secret_name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"configuration\",\"type\":\"[]byte\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"}]},{\"id\":\"IntegrationAttachment\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"configuration\",\"type\":\"[]byte\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"workflow_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"Membership\",\"fields\":[{\"name\":\"current\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"role\",\"type\":\"authz.Role\"},{\"name\":\"membership_type\",\"type\":\"authz.MembershipType\"},{\"name\":\"member_id\",\"type\":\"uuid.UUID\"},{\"name\":\"resource_type\",\"type\":\"authz.ResourceType\"},{\"name\":\"resource_id\",\"type\":\"uuid.UUID\"},{\"name\":\"parent_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"OrgInvitation\",\"fields\":[{\"name\":\"receiver_email\",\"type\":\"string\"},{\"name\":\"status\",\"type\":\"biz.OrgInvitationStatus\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"sender_id\",\"type\":\"uuid.UUID\"},{\"name\":\"role\",\"type\":\"authz.Role\"},{\"name\":\"context\",\"type\":\"biz.OrgInvitationContext\"}]},{\"id\":\"Organization\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"block_on_policy_violation\",\"type\":\"bool\"},{\"name\":\"policies_allowed_hostnames\",\"type\":\"[]string\"}]},{\"id\":\"Project\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"ProjectVersion\",\"fields\":[{\"name\":\"version\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"},{\"name\":\"prerelease\",\"type\":\"bool\"},{\"name\":\"workflow_run_count\",\"type\":\"int\"},{\"name\":\"released_at\",\"type\":\"time.Time\"},{\"name\":\"latest\",\"type\":\"bool\"}]},{\"id\":\"Referrer\",\"fields\":[{\"name\":\"digest\",\"type\":\"string\"},{\"name\":\"kind\",\"type\":\"string\"},{\"name\":\"downloadable\",\"type\":\"bool\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"metadata\",\"type\":\"map[string]string\"},{\"name\":\"annotations\",\"type\":\"map[string]string\"}]},{\"id\":\"RobotAccount\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"revoked_at\",\"type\":\"time.Time\"}]},{\"id\":\"User\",\"fields\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"has_restricted_access\",\"type\":\"bool\"},{\"name\":\"first_name\",\"type\":\"string\"},{\"name\":\"last_name\",\"type\":\"string\"}]},{\"id\":\"Workflow\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"project_old\",\"type\":\"string\"},{\"name\":\"team\",\"type\":\"string\"},{\"name\":\"runs_count\",\"type\":\"int\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"public\",\"type\":\"bool\"},{\"name\":\"organization_id\",\"type\":\"uuid.UUID\"},{\"name\":\"project_id\",\"type\":\"uuid.UUID\"},{\"name\":\"latest_run\",\"type\":\"uuid.UUID\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"metadata\",\"type\":\"map[string]interface {}\"}]},{\"id\":\"WorkflowContract\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"updated_at\",\"type\":\"time.Time\"},{\"name\":\"deleted_at\",\"type\":\"time.Time\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"scoped_resource_type\",\"type\":\"biz.ContractScope\"},{\"name\":\"scoped_resource_id\",\"type\":\"uuid.UUID\"}]},{\"id\":\"WorkflowContractVersion\",\"fields\":[{\"name\":\"body\",\"type\":\"[]byte\"},{\"name\":\"raw_body\",\"type\":\"[]byte\"},{\"name\":\"raw_body_format\",\"type\":\"unmarshal.RawFormat\"},{\"name\":\"revision\",\"type\":\"int\"},{\"name\":\"created_at\",\"type\":\"time.Time\"}]},{\"id\":\"WorkflowRun\",\"fields\":[{\"name\":\"created_at\",\"type\":\"time.Time\"},{\"name\":\"finished_at\",\"type\":\"time.Time\"},{\"name\":\"state\",\"type\":\"biz.WorkflowRunStatus\"},{\"name\":\"reason\",\"type\":\"string\"},{\"name\":\"run_url\",\"type\":\"string\"},{\"name\":\"runner_type\",\"type\":\"string\"},{\"name\":\"attestation\",\"type\":\"*dsse.Envelope\"},{\"name\":\"attestation_digest\",\"type\":\"string\"},{\"name\":\"attestation_state\",\"type\":\"[]byte\"},{\"name\":\"contract_revision_used\",\"type\":\"int\"},{\"name\":\"contract_revision_latest\",\"type\":\"int\"},{\"name\":\"version_id\",\"type\":\"uuid.UUID\"},{\"name\":\"workflow_id\",\"type\":\"uuid.UUID\"}]}],\"edges\":[{\"from\":\"APIToken\",\"to\":\"Project\",\"label\":\"project\"},{\"from\":\"CASMapping\",\"to\":\"CASBackend\",\"label\":\"cas_backend\"},{\"from\":\"CASMapping\",\"to\":\"Organization\",\"label\":\"organization\"},{\"from\":\"CASMapping\",\"to\":\"Project\",\"label\":\"project\"},{\"from\":\"GroupMembership\",\"to\":\"Group\",\"label\":\"group\"},{\"from\":\"GroupMembership\",\"to\":\"User\",\"label\":\"user\"},{\"from\":\"IntegrationAttachment\",\"to\":\"Integration\",\"label\":\"integration\"},{\"from\":\"IntegrationAttachment\",\"to\":\"Workflow\",\"label\":\"workflow\"},{\"from\":\"Membership\",\"to\":\"Membership\",\"label\":\"children\"},{\"from\":\"OrgInvitation\",\"to\":\"Organization\",\"label\":\"organization\"},{\"from\":\"OrgInvitation\",\"to\":\"User\",\"label\":\"sender\"},{\"from\":\"Organization\",\"to\":\"Membership\",\"label\":\"memberships\"},{\"from\":\"Organization\",\"to\":\"WorkflowContract\",\"label\":\"workflow_contracts\"},{\"from\":\"Organization\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"Organization\",\"to\":\"CASBackend\",\"label\":\"cas_backends\"},{\"from\":\"Organization\",\"to\":\"Integration\",\"label\":\"integrations\"},{\"from\":\"Organization\",\"to\":\"APIToken\",\"label\":\"api_tokens\"},{\"from\":\"Organization\",\"to\":\"Project\",\"label\":\"projects\"},{\"from\":\"Organization\",\"to\":\"Group\",\"label\":\"groups\"},{\"from\":\"Project\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"Project\",\"to\":\"ProjectVersion\",\"label\":\"versions\"},{\"from\":\"ProjectVersion\",\"to\":\"WorkflowRun\",\"label\":\"runs\"},{\"from\":\"Referrer\",\"to\":\"Referrer\",\"label\":\"references\"},{\"from\":\"Referrer\",\"to\":\"Workflow\",\"label\":\"workflows\"},{\"from\":\"User\",\"to\":\"Membership\",\"label\":\"memberships\"},{\"from\":\"Workflow\",\"to\":\"RobotAccount\",\"label\":\"robotaccounts\"},{\"from\":\"Workflow\",\"to\":\"WorkflowRun\",\"label\":\"workflowruns\"},{\"from\":\"Workflow\",\"to\":\"WorkflowContract\",\"label\":\"contract\"},{\"from\":\"Workflow\",\"to\":\"WorkflowRun\",\"label\":\"latest_workflow_run\"},{\"from\":\"WorkflowContract\",\"to\":\"WorkflowContractVersion\",\"label\":\"versions\"},{\"from\":\"WorkflowRun\",\"to\":\"WorkflowContractVersion\",\"label\":\"contract_version\"},{\"from\":\"WorkflowRun\",\"to\":\"CASBackend\",\"label\":\"cas_backends\"},{\"from\":\"WorkflowRun\",\"to\":\"Attestation\",\"label\":\"attestation_bundle\"}]}"); const nodes = new vis.DataSet((entGraph.nodes || []).map(n => ({ id: n.id, diff --git a/app/controlplane/pkg/data/ent/schema/organization.go b/app/controlplane/pkg/data/ent/schema/organization.go index 40eb7c77a..d3c82d103 100644 --- a/app/controlplane/pkg/data/ent/schema/organization.go +++ b/app/controlplane/pkg/data/ent/schema/organization.go @@ -41,6 +41,11 @@ func (Organization) Fields() []ent.Field { Annotations(&entsql.Annotation{ Default: "CURRENT_TIMESTAMP", }), + field.Time("updated_at"). + Default(time.Now). + Annotations(&entsql.Annotation{ + Default: "CURRENT_TIMESTAMP", + }), field.Bool("block_on_policy_violation").Default(false), // array of hostnames that are allowed to be used in the policies field.Strings("policies_allowed_hostnames").Optional(), diff --git a/app/controlplane/pkg/data/ent/schema/user.go b/app/controlplane/pkg/data/ent/schema/user.go index d4241e98c..e381b44ad 100644 --- a/app/controlplane/pkg/data/ent/schema/user.go +++ b/app/controlplane/pkg/data/ent/schema/user.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -49,6 +49,11 @@ func (User) Fields() []ent.Field { Annotations(&entsql.Annotation{ Default: "CURRENT_TIMESTAMP", }), + field.Time("updated_at"). + Default(time.Now). + Annotations(&entsql.Annotation{ + Default: "CURRENT_TIMESTAMP", + }), field.Bool("has_restricted_access").Optional().Nillable(), field.String("first_name").Optional(), field.String("last_name").Optional(), diff --git a/app/controlplane/pkg/data/ent/schema/workflowcontract.go b/app/controlplane/pkg/data/ent/schema/workflowcontract.go index 59ea1b40a..ea3c2d77d 100644 --- a/app/controlplane/pkg/data/ent/schema/workflowcontract.go +++ b/app/controlplane/pkg/data/ent/schema/workflowcontract.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,6 +43,11 @@ func (WorkflowContract) Fields() []ent.Field { Annotations(&entsql.Annotation{ Default: "CURRENT_TIMESTAMP", }), + field.Time("updated_at"). + Default(time.Now). + Annotations(&entsql.Annotation{ + Default: "CURRENT_TIMESTAMP", + }), field.Time("deleted_at").Optional(), field.String("description").Optional(), // If this value is set, the contract is scoped to a resource diff --git a/app/controlplane/pkg/data/ent/user.go b/app/controlplane/pkg/data/ent/user.go index 5e0812f20..43f1d5332 100644 --- a/app/controlplane/pkg/data/ent/user.go +++ b/app/controlplane/pkg/data/ent/user.go @@ -22,6 +22,8 @@ type User struct { Email string `json:"email,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` // HasRestrictedAccess holds the value of the "has_restricted_access" field. HasRestrictedAccess *bool `json:"has_restricted_access,omitempty"` // FirstName holds the value of the "first_name" field. @@ -72,7 +74,7 @@ func (*User) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullBool) case user.FieldEmail, user.FieldFirstName, user.FieldLastName: values[i] = new(sql.NullString) - case user.FieldCreatedAt: + case user.FieldCreatedAt, user.FieldUpdatedAt: values[i] = new(sql.NullTime) case user.FieldID: values[i] = new(uuid.UUID) @@ -109,6 +111,12 @@ func (u *User) assignValues(columns []string, values []any) error { } else if value.Valid { u.CreatedAt = value.Time } + case user.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + u.UpdatedAt = value.Time + } case user.FieldHasRestrictedAccess: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field has_restricted_access", values[i]) @@ -180,6 +188,9 @@ func (u *User) String() string { builder.WriteString("created_at=") builder.WriteString(u.CreatedAt.Format(time.ANSIC)) builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(u.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") if v := u.HasRestrictedAccess; v != nil { builder.WriteString("has_restricted_access=") builder.WriteString(fmt.Sprintf("%v", *v)) diff --git a/app/controlplane/pkg/data/ent/user/user.go b/app/controlplane/pkg/data/ent/user/user.go index b1ef93cb3..0e9a36837 100644 --- a/app/controlplane/pkg/data/ent/user/user.go +++ b/app/controlplane/pkg/data/ent/user/user.go @@ -19,6 +19,8 @@ const ( FieldEmail = "email" // FieldCreatedAt holds the string denoting the created_at field in the database. FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" // FieldHasRestrictedAccess holds the string denoting the has_restricted_access field in the database. FieldHasRestrictedAccess = "has_restricted_access" // FieldFirstName holds the string denoting the first_name field in the database. @@ -52,6 +54,7 @@ var Columns = []string{ FieldID, FieldEmail, FieldCreatedAt, + FieldUpdatedAt, FieldHasRestrictedAccess, FieldFirstName, FieldLastName, @@ -72,6 +75,8 @@ var ( EmailValidator func(string) error // DefaultCreatedAt holds the default value on creation for the "created_at" field. DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time // DefaultID holds the default value on creation for the "id" field. DefaultID func() uuid.UUID ) @@ -94,6 +99,11 @@ func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() } +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + // ByHasRestrictedAccess orders the results by the has_restricted_access field. func ByHasRestrictedAccess(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldHasRestrictedAccess, opts...).ToFunc() diff --git a/app/controlplane/pkg/data/ent/user/where.go b/app/controlplane/pkg/data/ent/user/where.go index 904fdad71..d73e98a52 100644 --- a/app/controlplane/pkg/data/ent/user/where.go +++ b/app/controlplane/pkg/data/ent/user/where.go @@ -66,6 +66,11 @@ func CreatedAt(v time.Time) predicate.User { return predicate.User(sql.FieldEQ(FieldCreatedAt, v)) } +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.User { + return predicate.User(sql.FieldEQ(FieldUpdatedAt, v)) +} + // HasRestrictedAccess applies equality check predicate on the "has_restricted_access" field. It's identical to HasRestrictedAccessEQ. func HasRestrictedAccess(v bool) predicate.User { return predicate.User(sql.FieldEQ(FieldHasRestrictedAccess, v)) @@ -186,6 +191,46 @@ func CreatedAtLTE(v time.Time) predicate.User { return predicate.User(sql.FieldLTE(FieldCreatedAt, v)) } +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.User { + return predicate.User(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.User { + return predicate.User(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.User { + return predicate.User(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.User { + return predicate.User(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.User { + return predicate.User(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.User { + return predicate.User(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.User { + return predicate.User(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.User { + return predicate.User(sql.FieldLTE(FieldUpdatedAt, v)) +} + // HasRestrictedAccessEQ applies the EQ predicate on the "has_restricted_access" field. func HasRestrictedAccessEQ(v bool) predicate.User { return predicate.User(sql.FieldEQ(FieldHasRestrictedAccess, v)) diff --git a/app/controlplane/pkg/data/ent/user_create.go b/app/controlplane/pkg/data/ent/user_create.go index af7741543..256cab6b2 100644 --- a/app/controlplane/pkg/data/ent/user_create.go +++ b/app/controlplane/pkg/data/ent/user_create.go @@ -46,6 +46,20 @@ func (uc *UserCreate) SetNillableCreatedAt(t *time.Time) *UserCreate { return uc } +// SetUpdatedAt sets the "updated_at" field. +func (uc *UserCreate) SetUpdatedAt(t time.Time) *UserCreate { + uc.mutation.SetUpdatedAt(t) + return uc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (uc *UserCreate) SetNillableUpdatedAt(t *time.Time) *UserCreate { + if t != nil { + uc.SetUpdatedAt(*t) + } + return uc +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (uc *UserCreate) SetHasRestrictedAccess(b bool) *UserCreate { uc.mutation.SetHasRestrictedAccess(b) @@ -171,6 +185,10 @@ func (uc *UserCreate) defaults() { v := user.DefaultCreatedAt() uc.mutation.SetCreatedAt(v) } + if _, ok := uc.mutation.UpdatedAt(); !ok { + v := user.DefaultUpdatedAt() + uc.mutation.SetUpdatedAt(v) + } if _, ok := uc.mutation.ID(); !ok { v := user.DefaultID() uc.mutation.SetID(v) @@ -190,6 +208,9 @@ func (uc *UserCreate) check() error { if _, ok := uc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "User.created_at"`)} } + if _, ok := uc.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "User.updated_at"`)} + } return nil } @@ -234,6 +255,10 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { _spec.SetField(user.FieldCreatedAt, field.TypeTime, value) _node.CreatedAt = value } + if value, ok := uc.mutation.UpdatedAt(); ok { + _spec.SetField(user.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } if value, ok := uc.mutation.HasRestrictedAccess(); ok { _spec.SetField(user.FieldHasRestrictedAccess, field.TypeBool, value) _node.HasRestrictedAccess = &value @@ -342,6 +367,18 @@ func (u *UserUpsert) UpdateEmail() *UserUpsert { return u } +// SetUpdatedAt sets the "updated_at" field. +func (u *UserUpsert) SetUpdatedAt(v time.Time) *UserUpsert { + u.Set(user.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserUpsert) UpdateUpdatedAt() *UserUpsert { + u.SetExcluded(user.FieldUpdatedAt) + return u +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (u *UserUpsert) SetHasRestrictedAccess(v bool) *UserUpsert { u.Set(user.FieldHasRestrictedAccess, v) @@ -461,6 +498,20 @@ func (u *UserUpsertOne) UpdateEmail() *UserUpsertOne { }) } +// SetUpdatedAt sets the "updated_at" field. +func (u *UserUpsertOne) SetUpdatedAt(v time.Time) *UserUpsertOne { + return u.Update(func(s *UserUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserUpsertOne) UpdateUpdatedAt() *UserUpsertOne { + return u.Update(func(s *UserUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (u *UserUpsertOne) SetHasRestrictedAccess(v bool) *UserUpsertOne { return u.Update(func(s *UserUpsert) { @@ -756,6 +807,20 @@ func (u *UserUpsertBulk) UpdateEmail() *UserUpsertBulk { }) } +// SetUpdatedAt sets the "updated_at" field. +func (u *UserUpsertBulk) SetUpdatedAt(v time.Time) *UserUpsertBulk { + return u.Update(func(s *UserUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *UserUpsertBulk) UpdateUpdatedAt() *UserUpsertBulk { + return u.Update(func(s *UserUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (u *UserUpsertBulk) SetHasRestrictedAccess(v bool) *UserUpsertBulk { return u.Update(func(s *UserUpsert) { diff --git a/app/controlplane/pkg/data/ent/user_update.go b/app/controlplane/pkg/data/ent/user_update.go index 9a3b798a1..fab1f5537 100644 --- a/app/controlplane/pkg/data/ent/user_update.go +++ b/app/controlplane/pkg/data/ent/user_update.go @@ -6,6 +6,7 @@ import ( "context" "errors" "fmt" + "time" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -45,6 +46,20 @@ func (uu *UserUpdate) SetNillableEmail(s *string) *UserUpdate { return uu } +// SetUpdatedAt sets the "updated_at" field. +func (uu *UserUpdate) SetUpdatedAt(t time.Time) *UserUpdate { + uu.mutation.SetUpdatedAt(t) + return uu +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (uu *UserUpdate) SetNillableUpdatedAt(t *time.Time) *UserUpdate { + if t != nil { + uu.SetUpdatedAt(*t) + } + return uu +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (uu *UserUpdate) SetHasRestrictedAccess(b bool) *UserUpdate { uu.mutation.SetHasRestrictedAccess(b) @@ -240,6 +255,9 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := uu.mutation.Email(); ok { _spec.SetField(user.FieldEmail, field.TypeString, value) } + if value, ok := uu.mutation.UpdatedAt(); ok { + _spec.SetField(user.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := uu.mutation.HasRestrictedAccess(); ok { _spec.SetField(user.FieldHasRestrictedAccess, field.TypeBool, value) } @@ -384,6 +402,20 @@ func (uuo *UserUpdateOne) SetNillableEmail(s *string) *UserUpdateOne { return uuo } +// SetUpdatedAt sets the "updated_at" field. +func (uuo *UserUpdateOne) SetUpdatedAt(t time.Time) *UserUpdateOne { + uuo.mutation.SetUpdatedAt(t) + return uuo +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableUpdatedAt(t *time.Time) *UserUpdateOne { + if t != nil { + uuo.SetUpdatedAt(*t) + } + return uuo +} + // SetHasRestrictedAccess sets the "has_restricted_access" field. func (uuo *UserUpdateOne) SetHasRestrictedAccess(b bool) *UserUpdateOne { uuo.mutation.SetHasRestrictedAccess(b) @@ -609,6 +641,9 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) if value, ok := uuo.mutation.Email(); ok { _spec.SetField(user.FieldEmail, field.TypeString, value) } + if value, ok := uuo.mutation.UpdatedAt(); ok { + _spec.SetField(user.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := uuo.mutation.HasRestrictedAccess(); ok { _spec.SetField(user.FieldHasRestrictedAccess, field.TypeBool, value) } diff --git a/app/controlplane/pkg/data/ent/workflowcontract.go b/app/controlplane/pkg/data/ent/workflowcontract.go index b4ba03c94..ded8d5814 100644 --- a/app/controlplane/pkg/data/ent/workflowcontract.go +++ b/app/controlplane/pkg/data/ent/workflowcontract.go @@ -24,6 +24,8 @@ type WorkflowContract struct { Name string `json:"name,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at,omitempty"` // DeletedAt holds the value of the "deleted_at" field. DeletedAt time.Time `json:"deleted_at,omitempty"` // Description holds the value of the "description" field. @@ -88,7 +90,7 @@ func (*WorkflowContract) scanValues(columns []string) ([]any, error) { switch columns[i] { case workflowcontract.FieldName, workflowcontract.FieldDescription, workflowcontract.FieldScopedResourceType: values[i] = new(sql.NullString) - case workflowcontract.FieldCreatedAt, workflowcontract.FieldDeletedAt: + case workflowcontract.FieldCreatedAt, workflowcontract.FieldUpdatedAt, workflowcontract.FieldDeletedAt: values[i] = new(sql.NullTime) case workflowcontract.FieldID, workflowcontract.FieldScopedResourceID: values[i] = new(uuid.UUID) @@ -127,6 +129,12 @@ func (wc *WorkflowContract) assignValues(columns []string, values []any) error { } else if value.Valid { wc.CreatedAt = value.Time } + case workflowcontract.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + wc.UpdatedAt = value.Time + } case workflowcontract.FieldDeletedAt: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field deleted_at", values[i]) @@ -215,6 +223,9 @@ func (wc *WorkflowContract) String() string { builder.WriteString("created_at=") builder.WriteString(wc.CreatedAt.Format(time.ANSIC)) builder.WriteString(", ") + builder.WriteString("updated_at=") + builder.WriteString(wc.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", ") builder.WriteString("deleted_at=") builder.WriteString(wc.DeletedAt.Format(time.ANSIC)) builder.WriteString(", ") diff --git a/app/controlplane/pkg/data/ent/workflowcontract/where.go b/app/controlplane/pkg/data/ent/workflowcontract/where.go index ade940dec..3349309a0 100644 --- a/app/controlplane/pkg/data/ent/workflowcontract/where.go +++ b/app/controlplane/pkg/data/ent/workflowcontract/where.go @@ -67,6 +67,11 @@ func CreatedAt(v time.Time) predicate.WorkflowContract { return predicate.WorkflowContract(sql.FieldEQ(FieldCreatedAt, v)) } +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldEQ(FieldUpdatedAt, v)) +} + // DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ. func DeletedAt(v time.Time) predicate.WorkflowContract { return predicate.WorkflowContract(sql.FieldEQ(FieldDeletedAt, v)) @@ -187,6 +192,46 @@ func CreatedAtLTE(v time.Time) predicate.WorkflowContract { return predicate.WorkflowContract(sql.FieldLTE(FieldCreatedAt, v)) } +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldNEQ(FieldUpdatedAt, v)) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldNotIn(FieldUpdatedAt, vs...)) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldGT(FieldUpdatedAt, v)) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldGTE(FieldUpdatedAt, v)) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldLT(FieldUpdatedAt, v)) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.WorkflowContract { + return predicate.WorkflowContract(sql.FieldLTE(FieldUpdatedAt, v)) +} + // DeletedAtEQ applies the EQ predicate on the "deleted_at" field. func DeletedAtEQ(v time.Time) predicate.WorkflowContract { return predicate.WorkflowContract(sql.FieldEQ(FieldDeletedAt, v)) diff --git a/app/controlplane/pkg/data/ent/workflowcontract/workflowcontract.go b/app/controlplane/pkg/data/ent/workflowcontract/workflowcontract.go index c3b1fa48c..5ba08a3ae 100644 --- a/app/controlplane/pkg/data/ent/workflowcontract/workflowcontract.go +++ b/app/controlplane/pkg/data/ent/workflowcontract/workflowcontract.go @@ -21,6 +21,8 @@ const ( FieldName = "name" // FieldCreatedAt holds the string denoting the created_at field in the database. FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" // FieldDeletedAt holds the string denoting the deleted_at field in the database. FieldDeletedAt = "deleted_at" // FieldDescription holds the string denoting the description field in the database. @@ -65,6 +67,7 @@ var Columns = []string{ FieldID, FieldName, FieldCreatedAt, + FieldUpdatedAt, FieldDeletedAt, FieldDescription, FieldScopedResourceType, @@ -95,6 +98,8 @@ func ValidColumn(column string) bool { var ( // DefaultCreatedAt holds the default value on creation for the "created_at" field. DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time // DefaultID holds the default value on creation for the "id" field. DefaultID func() uuid.UUID ) @@ -127,6 +132,11 @@ func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() } +// ByUpdatedAt orders the results by the updated_at field. +func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc() +} + // ByDeletedAt orders the results by the deleted_at field. func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldDeletedAt, opts...).ToFunc() diff --git a/app/controlplane/pkg/data/ent/workflowcontract_create.go b/app/controlplane/pkg/data/ent/workflowcontract_create.go index 766cd59bb..e17de188a 100644 --- a/app/controlplane/pkg/data/ent/workflowcontract_create.go +++ b/app/controlplane/pkg/data/ent/workflowcontract_create.go @@ -48,6 +48,20 @@ func (wcc *WorkflowContractCreate) SetNillableCreatedAt(t *time.Time) *WorkflowC return wcc } +// SetUpdatedAt sets the "updated_at" field. +func (wcc *WorkflowContractCreate) SetUpdatedAt(t time.Time) *WorkflowContractCreate { + wcc.mutation.SetUpdatedAt(t) + return wcc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (wcc *WorkflowContractCreate) SetNillableUpdatedAt(t *time.Time) *WorkflowContractCreate { + if t != nil { + wcc.SetUpdatedAt(*t) + } + return wcc +} + // SetDeletedAt sets the "deleted_at" field. func (wcc *WorkflowContractCreate) SetDeletedAt(t time.Time) *WorkflowContractCreate { wcc.mutation.SetDeletedAt(t) @@ -206,6 +220,10 @@ func (wcc *WorkflowContractCreate) defaults() { v := workflowcontract.DefaultCreatedAt() wcc.mutation.SetCreatedAt(v) } + if _, ok := wcc.mutation.UpdatedAt(); !ok { + v := workflowcontract.DefaultUpdatedAt() + wcc.mutation.SetUpdatedAt(v) + } if _, ok := wcc.mutation.ID(); !ok { v := workflowcontract.DefaultID() wcc.mutation.SetID(v) @@ -220,6 +238,9 @@ func (wcc *WorkflowContractCreate) check() error { if _, ok := wcc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "WorkflowContract.created_at"`)} } + if _, ok := wcc.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "WorkflowContract.updated_at"`)} + } if v, ok := wcc.mutation.ScopedResourceType(); ok { if err := workflowcontract.ScopedResourceTypeValidator(v); err != nil { return &ValidationError{Name: "scoped_resource_type", err: fmt.Errorf(`ent: validator failed for field "WorkflowContract.scoped_resource_type": %w`, err)} @@ -269,6 +290,10 @@ func (wcc *WorkflowContractCreate) createSpec() (*WorkflowContract, *sqlgraph.Cr _spec.SetField(workflowcontract.FieldCreatedAt, field.TypeTime, value) _node.CreatedAt = value } + if value, ok := wcc.mutation.UpdatedAt(); ok { + _spec.SetField(workflowcontract.FieldUpdatedAt, field.TypeTime, value) + _node.UpdatedAt = value + } if value, ok := wcc.mutation.DeletedAt(); ok { _spec.SetField(workflowcontract.FieldDeletedAt, field.TypeTime, value) _node.DeletedAt = value @@ -386,6 +411,18 @@ type ( } ) +// SetUpdatedAt sets the "updated_at" field. +func (u *WorkflowContractUpsert) SetUpdatedAt(v time.Time) *WorkflowContractUpsert { + u.Set(workflowcontract.FieldUpdatedAt, v) + return u +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *WorkflowContractUpsert) UpdateUpdatedAt() *WorkflowContractUpsert { + u.SetExcluded(workflowcontract.FieldUpdatedAt) + return u +} + // SetDeletedAt sets the "deleted_at" field. func (u *WorkflowContractUpsert) SetDeletedAt(v time.Time) *WorkflowContractUpsert { u.Set(workflowcontract.FieldDeletedAt, v) @@ -512,6 +549,20 @@ func (u *WorkflowContractUpsertOne) Update(set func(*WorkflowContractUpsert)) *W return u } +// SetUpdatedAt sets the "updated_at" field. +func (u *WorkflowContractUpsertOne) SetUpdatedAt(v time.Time) *WorkflowContractUpsertOne { + return u.Update(func(s *WorkflowContractUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *WorkflowContractUpsertOne) UpdateUpdatedAt() *WorkflowContractUpsertOne { + return u.Update(func(s *WorkflowContractUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetDeletedAt sets the "deleted_at" field. func (u *WorkflowContractUpsertOne) SetDeletedAt(v time.Time) *WorkflowContractUpsertOne { return u.Update(func(s *WorkflowContractUpsert) { @@ -817,6 +868,20 @@ func (u *WorkflowContractUpsertBulk) Update(set func(*WorkflowContractUpsert)) * return u } +// SetUpdatedAt sets the "updated_at" field. +func (u *WorkflowContractUpsertBulk) SetUpdatedAt(v time.Time) *WorkflowContractUpsertBulk { + return u.Update(func(s *WorkflowContractUpsert) { + s.SetUpdatedAt(v) + }) +} + +// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create. +func (u *WorkflowContractUpsertBulk) UpdateUpdatedAt() *WorkflowContractUpsertBulk { + return u.Update(func(s *WorkflowContractUpsert) { + s.UpdateUpdatedAt() + }) +} + // SetDeletedAt sets the "deleted_at" field. func (u *WorkflowContractUpsertBulk) SetDeletedAt(v time.Time) *WorkflowContractUpsertBulk { return u.Update(func(s *WorkflowContractUpsert) { diff --git a/app/controlplane/pkg/data/ent/workflowcontract_update.go b/app/controlplane/pkg/data/ent/workflowcontract_update.go index 5ea09f64b..ee5bdcf2e 100644 --- a/app/controlplane/pkg/data/ent/workflowcontract_update.go +++ b/app/controlplane/pkg/data/ent/workflowcontract_update.go @@ -34,6 +34,20 @@ func (wcu *WorkflowContractUpdate) Where(ps ...predicate.WorkflowContract) *Work return wcu } +// SetUpdatedAt sets the "updated_at" field. +func (wcu *WorkflowContractUpdate) SetUpdatedAt(t time.Time) *WorkflowContractUpdate { + wcu.mutation.SetUpdatedAt(t) + return wcu +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (wcu *WorkflowContractUpdate) SetNillableUpdatedAt(t *time.Time) *WorkflowContractUpdate { + if t != nil { + wcu.SetUpdatedAt(*t) + } + return wcu +} + // SetDeletedAt sets the "deleted_at" field. func (wcu *WorkflowContractUpdate) SetDeletedAt(t time.Time) *WorkflowContractUpdate { wcu.mutation.SetDeletedAt(t) @@ -271,6 +285,9 @@ func (wcu *WorkflowContractUpdate) sqlSave(ctx context.Context) (n int, err erro } } } + if value, ok := wcu.mutation.UpdatedAt(); ok { + _spec.SetField(workflowcontract.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := wcu.mutation.DeletedAt(); ok { _spec.SetField(workflowcontract.FieldDeletedAt, field.TypeTime, value) } @@ -436,6 +453,20 @@ type WorkflowContractUpdateOne struct { modifiers []func(*sql.UpdateBuilder) } +// SetUpdatedAt sets the "updated_at" field. +func (wcuo *WorkflowContractUpdateOne) SetUpdatedAt(t time.Time) *WorkflowContractUpdateOne { + wcuo.mutation.SetUpdatedAt(t) + return wcuo +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (wcuo *WorkflowContractUpdateOne) SetNillableUpdatedAt(t *time.Time) *WorkflowContractUpdateOne { + if t != nil { + wcuo.SetUpdatedAt(*t) + } + return wcuo +} + // SetDeletedAt sets the "deleted_at" field. func (wcuo *WorkflowContractUpdateOne) SetDeletedAt(t time.Time) *WorkflowContractUpdateOne { wcuo.mutation.SetDeletedAt(t) @@ -703,6 +734,9 @@ func (wcuo *WorkflowContractUpdateOne) sqlSave(ctx context.Context) (_node *Work } } } + if value, ok := wcuo.mutation.UpdatedAt(); ok { + _spec.SetField(workflowcontract.FieldUpdatedAt, field.TypeTime, value) + } if value, ok := wcuo.mutation.DeletedAt(); ok { _spec.SetField(workflowcontract.FieldDeletedAt, field.TypeTime, value) } diff --git a/app/controlplane/pkg/data/membership.go b/app/controlplane/pkg/data/membership.go index e658d5d77..66f4a913f 100644 --- a/app/controlplane/pkg/data/membership.go +++ b/app/controlplane/pkg/data/membership.go @@ -297,7 +297,7 @@ func (r *MembershipRepo) SetCurrent(ctx context.Context, membershipID uuid.UUID) } // 2 - Set the referenced membership to current=true - if err = tx.Membership.UpdateOneID(membershipID).SetCurrent(true).Exec(ctx); err != nil { + if err = tx.Membership.UpdateOneID(membershipID).SetCurrent(true).SetUpdatedAt(time.Now()).Exec(ctx); err != nil { return err } return nil @@ -315,7 +315,7 @@ func (r *MembershipRepo) SetCurrent(ctx context.Context, membershipID uuid.UUID) } func (r *MembershipRepo) SetRole(ctx context.Context, membershipID uuid.UUID, role authz.Role) (*biz.Membership, error) { - if err := r.data.DB.Membership.UpdateOneID(membershipID).SetRole(role).Exec(ctx); err != nil { + if err := r.data.DB.Membership.UpdateOneID(membershipID).SetRole(role).SetUpdatedAt(time.Now()).Exec(ctx); err != nil { return nil, fmt.Errorf("failed to update membership: %w", err) } diff --git a/app/controlplane/pkg/data/organization.go b/app/controlplane/pkg/data/organization.go index d61abc2bd..b60606bd2 100644 --- a/app/controlplane/pkg/data/organization.go +++ b/app/controlplane/pkg/data/organization.go @@ -18,6 +18,7 @@ package data import ( "context" "fmt" + "time" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent" @@ -78,7 +79,8 @@ func (r *OrganizationRepo) FindByName(ctx context.Context, name string) (*biz.Or func (r *OrganizationRepo) Update(ctx context.Context, id uuid.UUID, blockOnPolicyViolation *bool, policiesAllowedHostnames []string) (*biz.Organization, error) { opts := r.data.DB.Organization.UpdateOneID(id). - SetNillableBlockOnPolicyViolation(blockOnPolicyViolation) + SetNillableBlockOnPolicyViolation(blockOnPolicyViolation). + SetUpdatedAt(time.Now()) if policiesAllowedHostnames != nil { opts.SetPoliciesAllowedHostnames(policiesAllowedHostnames) @@ -101,6 +103,7 @@ func entOrgToBizOrg(eu *ent.Organization) *biz.Organization { return &biz.Organization{ Name: eu.Name, ID: eu.ID.String(), CreatedAt: toTimePtr(eu.CreatedAt), + UpdatedAt: toTimePtr(eu.UpdatedAt), BlockOnPolicyViolation: eu.BlockOnPolicyViolation, PoliciesAllowedHostnames: eu.PoliciesAllowedHostnames, } diff --git a/app/controlplane/pkg/data/project.go b/app/controlplane/pkg/data/project.go index 1300a6849..2156df3e8 100644 --- a/app/controlplane/pkg/data/project.go +++ b/app/controlplane/pkg/data/project.go @@ -348,7 +348,7 @@ func entProjectToBiz(pro *ent.Project) *biz.Project { Name: pro.Name, OrgID: pro.OrganizationID, CreatedAt: &pro.CreatedAt, - UpdatedAt: &pro.CreatedAt, + UpdatedAt: &pro.UpdatedAt, } } diff --git a/app/controlplane/pkg/data/projectversion.go b/app/controlplane/pkg/data/projectversion.go index 1bebb8878..3c7d50b0b 100644 --- a/app/controlplane/pkg/data/projectversion.go +++ b/app/controlplane/pkg/data/projectversion.go @@ -55,7 +55,7 @@ func (r *ProjectVersionRepo) Update(ctx context.Context, id uuid.UUID, updates * updates = &biz.ProjectVersionUpdateOpts{} } - q := r.data.DB.ProjectVersion.UpdateOneID(id).SetNillablePrerelease(updates.Prerelease) + q := r.data.DB.ProjectVersion.UpdateOneID(id).SetNillablePrerelease(updates.Prerelease).SetUpdatedAt(time.Now()) // we are setting the value either false or true if updates.Prerelease != nil { // We are marking it as a release diff --git a/app/controlplane/pkg/data/user.go b/app/controlplane/pkg/data/user.go index f3bd959d0..262d08a9f 100644 --- a/app/controlplane/pkg/data/user.go +++ b/app/controlplane/pkg/data/user.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package data import ( "context" "fmt" + "time" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent" @@ -66,7 +67,7 @@ func (r *userRepo) CreateByEmail(ctx context.Context, email string, firstName, l // UpdateNameAndLastName updates the first and last name of a user func (r *userRepo) UpdateNameAndLastName(ctx context.Context, userID uuid.UUID, firstName, lastName *string) (*biz.User, error) { - u, err := r.data.DB.User.UpdateOneID(userID).SetNillableFirstName(firstName).SetNillableLastName(lastName).Save(ctx) + u, err := r.data.DB.User.UpdateOneID(userID).SetNillableFirstName(firstName).SetNillableLastName(lastName).SetUpdatedAt(time.Now()).Save(ctx) if err != nil { return nil, fmt.Errorf("error updating user name: %w", err) } @@ -92,7 +93,7 @@ func (r *userRepo) Delete(ctx context.Context, userID uuid.UUID) (err error) { // UpdateAccess updates the access restriction for a user func (r *userRepo) UpdateAccess(ctx context.Context, userID uuid.UUID, isAccessRestricted bool) (*biz.User, error) { - u, err := r.data.DB.User.UpdateOneID(userID).SetHasRestrictedAccess(isAccessRestricted).Save(ctx) + u, err := r.data.DB.User.UpdateOneID(userID).SetHasRestrictedAccess(isAccessRestricted).SetUpdatedAt(time.Now()).Save(ctx) if err != nil { return nil, fmt.Errorf("error updating user access: %w", err) } @@ -156,6 +157,7 @@ func entUserToBizUser(eu *ent.User) *biz.User { FirstName: eu.FirstName, LastName: eu.LastName, CreatedAt: toTimePtr(eu.CreatedAt), + UpdatedAt: toTimePtr(eu.UpdatedAt), } if eu.HasRestrictedAccess != nil { diff --git a/app/controlplane/pkg/data/workflow.go b/app/controlplane/pkg/data/workflow.go index 219f97fe5..0b867b9c5 100644 --- a/app/controlplane/pkg/data/workflow.go +++ b/app/controlplane/pkg/data/workflow.go @@ -180,7 +180,8 @@ func (r *WorkflowRepo) Update(ctx context.Context, id uuid.UUID, opts *biz.Workf req := r.data.DB.Workflow.UpdateOneID(id). SetNillableTeam(opts.Team). SetNillablePublic(opts.Public). - SetNillableDescription(opts.Description) + SetNillableDescription(opts.Description). + SetUpdatedAt(time.Now()) // Update the contract if provided if opts.ContractID != nil { diff --git a/app/controlplane/pkg/data/workflowcontract.go b/app/controlplane/pkg/data/workflowcontract.go index 0f6a8234a..81d589f38 100644 --- a/app/controlplane/pkg/data/workflowcontract.go +++ b/app/controlplane/pkg/data/workflowcontract.go @@ -236,7 +236,7 @@ func (r *WorkflowContractRepo) Update(ctx context.Context, orgID uuid.UUID, name ) if err = WithTx(ctx, r.data.DB, func(tx *ent.Tx) error { - contract, err = contract.Update().SetNillableDescription(opts.Description).Save(ctx) + contract, err = contract.Update().SetNillableDescription(opts.Description).SetUpdatedAt(time.Now()).Save(ctx) if err != nil { return handleError(err) } @@ -329,7 +329,7 @@ func (r *WorkflowContractRepo) FindByNameInOrg(ctx context.Context, orgID uuid.U } func (r *WorkflowContractRepo) SoftDelete(ctx context.Context, id uuid.UUID) error { - return r.data.DB.WorkflowContract.UpdateOneID(id).SetDeletedAt(time.Now()).Exec(ctx) + return r.data.DB.WorkflowContract.UpdateOneID(id).SetDeletedAt(time.Now()).SetUpdatedAt(time.Now()).Exec(ctx) } func entContractVersionToBizContractVersion(w *ent.WorkflowContractVersion) (*biz.WorkflowContractVersion, error) { @@ -427,6 +427,7 @@ func (r *WorkflowContractRepo) entContractToBizContract(ctx context.Context, w * Name: w.Name, ID: w.ID, CreatedAt: toTimePtr(w.CreatedAt), + UpdatedAt: toTimePtr(w.UpdatedAt), LatestRevisionCreatedAt: toTimePtr(version.CreatedAt), WorkflowRefs: workflowReferences, Description: w.Description, From b48d8122b48b485cf0c88367e99c449fee8ad8cd Mon Sep 17 00:00:00 2001 From: Miguel Martinez Date: Fri, 8 Aug 2025 19:51:10 +0200 Subject: [PATCH 2/2] feat: allowed hostnames support Signed-off-by: Miguel Martinez --- .../gen/frontend/google/protobuf/descriptor.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts index 0d2d2fb32..d59b21da4 100644 --- a/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts +++ b/app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts @@ -30,7 +30,7 @@ export enum Edition { EDITION_2024 = 1001, /** * EDITION_1_TEST_ONLY - Placeholder editions for testing feature resolution. These should not be - * used or relyed on outside of tests. + * used or relied on outside of tests. */ EDITION_1_TEST_ONLY = 1, EDITION_2_TEST_ONLY = 2, @@ -875,12 +875,13 @@ export interface MessageOptions { export interface FieldOptions { /** + * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of - * type "bytes" in the open source release -- sorry, we'll try to include - * other types in a future version! + * type "bytes" in the open source release. + * TODO: make ctype actually deprecated. */ ctype: FieldOptions_CType; /** @@ -1052,11 +1053,7 @@ export function fieldOptions_JSTypeToJSON(object: FieldOptions_JSType): string { } } -/** - * If set to RETENTION_SOURCE, the option will be omitted from the binary. - * Note: as of January 2023, support for this is in progress and does not yet - * have an effect (b/264593489). - */ +/** If set to RETENTION_SOURCE, the option will be omitted from the binary. */ export enum FieldOptions_OptionRetention { RETENTION_UNKNOWN = 0, RETENTION_RUNTIME = 1, @@ -1099,8 +1096,7 @@ export function fieldOptions_OptionRetentionToJSON(object: FieldOptions_OptionRe /** * This indicates the types of entities that the field may apply to when used * as an option. If it is unset, then the field may be freely used as an - * option on any kind of entity. Note: as of January 2023, support for this is - * in progress and does not yet have an effect (b/264593489). + * option on any kind of entity. */ export enum FieldOptions_OptionTargetType { TARGET_TYPE_UNKNOWN = 0,