Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
/**
* 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;
}