This commit is contained in:
@@ -322,3 +322,74 @@ export interface OnboardingInput {
|
||||
billingAddress?: BillingAddress;
|
||||
billingNotes?: string;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Feature 5: support tickets (lightweight customer support / feedback channel)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type SupportTicketCategory =
|
||||
| "bug"
|
||||
| "feature_request"
|
||||
| "question"
|
||||
| "billing"
|
||||
| "other";
|
||||
|
||||
export type SupportTicketStatus =
|
||||
| "open" // new, awaiting first admin response
|
||||
| "in_progress" // admin is actively working on it
|
||||
| "waiting_for_customer" // admin replied, customer's turn
|
||||
| "resolved" // closed
|
||||
| "reopened"; // customer replied to a resolved ticket → flipped back
|
||||
|
||||
/**
|
||||
* Tickets are scoped strictly per-user, not per-org. A customer's
|
||||
* coworkers (even within the same org) cannot see each other's
|
||||
* tickets — confirmed design choice from Feature 5 discussion. This
|
||||
* is enforced both at the DB query layer (filter by zitadel_user_id)
|
||||
* and at the API layer (authorization checks).
|
||||
*
|
||||
* `contactEmail` and `contactName` are frozen at creation time so
|
||||
* the email-thread reply addresses still work after a user changes
|
||||
* their display name or email in ZITADEL. Standard ticketing pattern.
|
||||
*/
|
||||
export interface SupportTicket {
|
||||
id: string;
|
||||
zitadelOrgId: string;
|
||||
zitadelUserId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
category: SupportTicketCategory;
|
||||
status: SupportTicketStatus;
|
||||
contactEmail: string;
|
||||
contactName: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export type SupportTicketCommentAuthorKind = "customer" | "admin";
|
||||
|
||||
/**
|
||||
* Comment on a support ticket. Public (visible to both ends) — no
|
||||
* internal-notes feature in v1. `authorKind` drives styling (customer
|
||||
* vs admin bubble) and which email goes out.
|
||||
*
|
||||
* `authorName` is frozen at write time. If a user later changes their
|
||||
* display name, old comments still render with the name they had at
|
||||
* the time of writing — which is what you usually want for an audit
|
||||
* trail of conversations.
|
||||
*/
|
||||
export interface SupportTicketComment {
|
||||
id: string;
|
||||
ticketId: string;
|
||||
authorUserId: string;
|
||||
authorName: string;
|
||||
authorKind: SupportTicketCommentAuthorKind;
|
||||
body: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
/** Detail view: the ticket plus its full chronological comment thread. */
|
||||
export interface SupportTicketDetail {
|
||||
ticket: SupportTicket;
|
||||
comments: SupportTicketComment[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user