/** * P1-17 hypercare “report missing / wrong data” deep-link into support ticket create. * Window is gated by API `/healthz` `hypercare` (HYPERCARE_MODE); dismiss is local-only. */ import type { SupportTicketCategory, SupportTicketPriority } from "$lib/support/types"; export const HYPERCARE_DISMISS_KEY = "descrybe.hypercare-report.dismissed.v1"; /** Stable triage tag — included in create payload + subject for admin `q=` search. */ export const HYPERCARE_TAG = "hypercare"; export const HYPERCARE_CATEGORY: SupportTicketCategory = "migration"; export const HYPERCARE_PRIORITY: SupportTicketPriority = "high"; export const HYPERCARE_SUBJECT = "Hypercare: missing or wrong data"; export const HYPERCARE_ADMIN_QUEUE_HREF = "/admin/support?status=open&scope=all&q=Hypercare"; export type HypercareReportPrefill = { category: SupportTicketCategory; priority: SupportTicketPriority; subject: string; tags: string; body: string; }; export function hypercareReportPrefill(): HypercareReportPrefill { return { category: HYPERCARE_CATEGORY, priority: HYPERCARE_PRIORITY, subject: HYPERCARE_SUBJECT, tags: `${HYPERCARE_TAG},migration-data`, body: [ "What is missing or wrong after the Descrybe cutover?", "", "- Area (products / feeds / exports / stores / billing / team / other):", "- Expected:", "- Actual:", "- Example SKU / feed / store (if any):", "" ].join("\n") }; } /** Deep-link to `/support/new` with category + prefilled fields for ticket create reuse. */ export function hypercareReportHref(): string { const prefill = hypercareReportPrefill(); const params = new URLSearchParams({ category: prefill.category, priority: prefill.priority, subject: prefill.subject, tags: prefill.tags, body: prefill.body, source: "hypercare" }); return `/support/new?${params.toString()}`; } export function isHypercareReportDismissed(): boolean { if (typeof window === "undefined") return false; try { return window.localStorage.getItem(HYPERCARE_DISMISS_KEY) === "1"; } catch { return false; } } export function dismissHypercareReport(): void { if (typeof window === "undefined") return; try { window.localStorage.setItem(HYPERCARE_DISMISS_KEY, "1"); } catch { /* ignore quota / private mode */ } } export function clearHypercareReportDismiss(): void { if (typeof window === "undefined") return; try { window.localStorage.removeItem(HYPERCARE_DISMISS_KEY); } catch { /* ignore */ } } /** Parse allowed support category from a query string value. */ export function parseSupportCategoryParam( raw: string | null | undefined, allowed: readonly SupportTicketCategory[] ): SupportTicketCategory | null { const value = (raw ?? "").trim().toLowerCase(); if (!value) return null; return (allowed as readonly string[]).includes(value) ? (value as SupportTicketCategory) : null; } export function parseSupportPriorityParam( raw: string | null | undefined, allowed: readonly SupportTicketPriority[] ): SupportTicketPriority | null { const value = (raw ?? "").trim().toLowerCase(); if (!value) return null; return (allowed as readonly string[]).includes(value) ? (value as SupportTicketPriority) : null; }