Support org
All checks were successful
Build and Push / build (push) Successful in 1m30s

This commit is contained in:
2026-05-02 10:50:06 +02:00
parent b023c068eb
commit 8273d08f15
19 changed files with 1974 additions and 5 deletions

View File

@@ -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[];
}