Let trust-portal data subjects submit and track GDPR/CCPA rights requests. The new Data Requests page lists the viewer's own requests and a dialog submits new ones, scoped server-side to the verified viewer email so former or inactive users can still exercise their rights. Submission requires magic-link sign-in (reusing the existing gate) but not the NDA gate. Extend the shared rights_request enums with RECTIFICATION, OBJECTION and COMPLAINT types plus a REJECTED state, and keep the console GraphQL, @probo/helpers and the MCP specification in sync. Expose a trust GraphQL surface (myRightsRequests query, createRightsRequest mutation) backed by a trust service and contact-scoped coredata loaders. Add the missing v2 UI kit primitives the dialog needs on top of Base UI: a SegmentedControl radio-cards group, a form Textarea, and a Field wrapper. Signed-off-by: Émile Ré <emile@probo.com>
152 lines
4.0 KiB
GraphQL
152 lines
4.0 KiB
GraphQL
enum RightsRequestType
|
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.RightsRequestType") {
|
|
ACCESS
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypeAccess"
|
|
)
|
|
DELETION
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypeDeletion"
|
|
)
|
|
RECTIFICATION
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypeRectification"
|
|
)
|
|
PORTABILITY
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypePortability"
|
|
)
|
|
OBJECTION
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypeObjection"
|
|
)
|
|
COMPLAINT
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestTypeComplaint"
|
|
)
|
|
}
|
|
|
|
enum RightsRequestState
|
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.RightsRequestState") {
|
|
TODO
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.RightsRequestStateTodo")
|
|
IN_PROGRESS
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestStateInProgress"
|
|
)
|
|
DONE
|
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.RightsRequestStateDone")
|
|
REJECTED
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestStateRejected"
|
|
)
|
|
}
|
|
|
|
enum RightsRequestOrderField
|
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.RightsRequestOrderField") {
|
|
CREATED_AT
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestOrderFieldCreatedAt"
|
|
)
|
|
DEADLINE
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestOrderFieldDeadline"
|
|
)
|
|
STATE
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestOrderFieldState"
|
|
)
|
|
TYPE
|
|
@goEnum(
|
|
value: "go.probo.inc/probo/pkg/coredata.RightsRequestOrderFieldType"
|
|
)
|
|
}
|
|
|
|
input RightsRequestOrder
|
|
@goModel(
|
|
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.RightsRequestOrderBy"
|
|
) {
|
|
direction: OrderDirection!
|
|
field: RightsRequestOrderField!
|
|
}
|
|
|
|
type RightsRequest implements Node {
|
|
id: ID!
|
|
organization: Organization! @goField(forceResolver: true)
|
|
requestType: RightsRequestType!
|
|
requestState: RightsRequestState!
|
|
dataSubject: String
|
|
contact: String
|
|
details: String
|
|
deadline: Datetime
|
|
actionTaken: String
|
|
createdAt: Datetime!
|
|
updatedAt: Datetime!
|
|
|
|
permission(action: String!): Boolean! @goField(forceResolver: true)
|
|
}
|
|
|
|
type RightsRequestConnection
|
|
@goModel(
|
|
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.RightsRequestConnection"
|
|
) {
|
|
totalCount: Int! @goField(forceResolver: true)
|
|
edges: [RightsRequestEdge!]!
|
|
pageInfo: PageInfo!
|
|
}
|
|
|
|
type RightsRequestEdge {
|
|
cursor: CursorKey!
|
|
node: RightsRequest!
|
|
}
|
|
|
|
extend type Mutation {
|
|
createRightsRequest(
|
|
input: CreateRightsRequestInput!
|
|
): CreateRightsRequestPayload!
|
|
updateRightsRequest(
|
|
input: UpdateRightsRequestInput!
|
|
): UpdateRightsRequestPayload!
|
|
deleteRightsRequest(
|
|
input: DeleteRightsRequestInput!
|
|
): DeleteRightsRequestPayload!
|
|
}
|
|
|
|
input CreateRightsRequestInput {
|
|
organizationId: ID!
|
|
requestType: RightsRequestType!
|
|
requestState: RightsRequestState!
|
|
dataSubject: String
|
|
contact: String
|
|
details: String
|
|
deadline: Datetime
|
|
actionTaken: String
|
|
}
|
|
|
|
input UpdateRightsRequestInput {
|
|
id: ID!
|
|
requestType: RightsRequestType
|
|
requestState: RightsRequestState
|
|
dataSubject: String @goField(omittable: true)
|
|
contact: String @goField(omittable: true)
|
|
details: String @goField(omittable: true)
|
|
deadline: Datetime @goField(omittable: true)
|
|
actionTaken: String @goField(omittable: true)
|
|
}
|
|
|
|
input DeleteRightsRequestInput {
|
|
rightsRequestId: ID!
|
|
}
|
|
|
|
type CreateRightsRequestPayload {
|
|
rightsRequestEdge: RightsRequestEdge!
|
|
}
|
|
|
|
type UpdateRightsRequestPayload {
|
|
rightsRequest: RightsRequest!
|
|
}
|
|
|
|
type DeleteRightsRequestPayload {
|
|
deletedRightsRequestId: ID!
|
|
}
|