Fas 1a punkt 2: release_gates tabell + go/no-go-vy
This commit is contained in:
@@ -7,3 +7,4 @@ export * from "./locale.js";
|
||||
export * from "./money.js";
|
||||
export * from "./measurement.js";
|
||||
export * from "./analytics.js";
|
||||
export * from "./release-gates.js";
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* Release gate definitions and go/no-go taxonomy (spec §17).
|
||||
*/
|
||||
|
||||
export const RELEASE_GATE_CATEGORIES = [
|
||||
"product",
|
||||
"quality",
|
||||
"retention",
|
||||
"economy",
|
||||
] as const;
|
||||
|
||||
export type ReleaseGateCategory = (typeof RELEASE_GATE_CATEGORIES)[number];
|
||||
|
||||
export const RELEASE_GATE_COMPARISONS = ["gte", "lte", "eq"] as const;
|
||||
|
||||
export type ReleaseGateComparison = (typeof RELEASE_GATE_COMPARISONS)[number];
|
||||
|
||||
export const RELEASE_GATE_STATUSES = [
|
||||
"pending",
|
||||
"passed",
|
||||
"failed",
|
||||
"blocked",
|
||||
"not_measurable",
|
||||
] as const;
|
||||
|
||||
export type ReleaseGateStatus = (typeof RELEASE_GATE_STATUSES)[number];
|
||||
|
||||
/**
|
||||
* Built-in release gates seeded from §17 go/no-go criteria.
|
||||
* Values are starting targets; admins can tune them before launch.
|
||||
*/
|
||||
export const BUILT_IN_RELEASE_GATES: Array<{
|
||||
gateKey: string;
|
||||
category: ReleaseGateCategory;
|
||||
nameSv: string;
|
||||
nameEn: string;
|
||||
descriptionSv: string;
|
||||
descriptionEn: string;
|
||||
targetValue: number;
|
||||
comparison: ReleaseGateComparison;
|
||||
evaluationWindowDays: number;
|
||||
blocking: boolean;
|
||||
}> = [
|
||||
// Product
|
||||
{
|
||||
gateKey: "first_scan_rate",
|
||||
category: "product",
|
||||
nameSv: "Första skanning genomförd",
|
||||
nameEn: "First scan completed",
|
||||
descriptionSv: "Andel användare som genomför minst en skanning efter kontoregistrering.",
|
||||
descriptionEn: "Share of users who complete at least one scan after account creation.",
|
||||
targetValue: 0.7,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "recipe_view_rate",
|
||||
category: "product",
|
||||
nameSv: "Rekommendation visad",
|
||||
nameEn: "Recommendation viewed",
|
||||
descriptionSv: "Andel användare som ser minst ett relevant recept.",
|
||||
descriptionEn: "Share of users who view at least one relevant recipe.",
|
||||
targetValue: 0.5,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "recipe_save_or_cook_day0",
|
||||
category: "product",
|
||||
nameSv: "Recept sparat eller tillagat dag 0",
|
||||
nameEn: "Recipe saved or cooked on day 0",
|
||||
descriptionSv: "Andel användare som sparar eller startar ett recept samma dag som registrering.",
|
||||
descriptionEn: "Share of users who save or start cooking a recipe on registration day.",
|
||||
targetValue: 0.35,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 1,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "second_inventory_event_week1",
|
||||
category: "product",
|
||||
nameSv: "Andra lagerhändelsen inom 7 dagar",
|
||||
nameEn: "Second inventory event within 7 days",
|
||||
descriptionSv: "Andel användare som lägger till, konsumerar eller kasserar en vara inom en vecka.",
|
||||
descriptionEn: "Share of users who add, consume, or discard an item within one week.",
|
||||
targetValue: 0.25,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "household_collaboration_rate",
|
||||
category: "product",
|
||||
nameSv: "Hushållssamarbete",
|
||||
nameEn: "Household collaboration",
|
||||
descriptionSv: "Andel hushåll där en andra medlem bjuds in eller är aktiv.",
|
||||
descriptionEn: "Share of households where a second member is invited or active.",
|
||||
targetValue: 0.2,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 14,
|
||||
blocking: false,
|
||||
},
|
||||
{
|
||||
gateKey: "weekly_trusted_meal_week2",
|
||||
category: "product",
|
||||
nameSv: "Weekly Trusted Meal vecka 2",
|
||||
nameEn: "Weekly trusted meal week 2",
|
||||
descriptionSv: "Andel aktiverade hushåll som lagar minst en måltid under vecka två.",
|
||||
descriptionEn: "Share of activated households that cook at least one meal in week two.",
|
||||
targetValue: 0.3,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 14,
|
||||
blocking: false,
|
||||
},
|
||||
|
||||
// Quality
|
||||
{
|
||||
gateKey: "critical_allergy_errors",
|
||||
category: "quality",
|
||||
nameSv: "Kritiska allergifel",
|
||||
nameEn: "Critical allergy errors",
|
||||
descriptionSv: "Accepterade kritiska allergifel ska vara noll.",
|
||||
descriptionEn: "Accepted critical allergy errors must be zero.",
|
||||
targetValue: 0,
|
||||
comparison: "lte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "correction_rate",
|
||||
category: "quality",
|
||||
nameSv: "Korrigeringsgrad skanning",
|
||||
nameEn: "Scan correction rate",
|
||||
descriptionSv: "Andel skannade varor som korrigeras av användaren.",
|
||||
descriptionEn: "Share of scanned items that the user corrects.",
|
||||
targetValue: 0.15,
|
||||
comparison: "lte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: false,
|
||||
},
|
||||
{
|
||||
gateKey: "sync_conflict_resolution_rate",
|
||||
category: "quality",
|
||||
nameSv: "Sync-konflikter lösta",
|
||||
nameEn: "Sync conflicts resolved",
|
||||
descriptionSv: "Andel sync-konflikter som löses utan dataförlust.",
|
||||
descriptionEn: "Share of sync conflicts resolved without data loss.",
|
||||
targetValue: 0.95,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: false,
|
||||
},
|
||||
|
||||
// Retention
|
||||
{
|
||||
gateKey: "retention_d1",
|
||||
category: "retention",
|
||||
nameSv: "D1-retention",
|
||||
nameEn: "D1 retention",
|
||||
descriptionSv: "Andel användare aktiva dagen efter registrering.",
|
||||
descriptionEn: "Share of users active one day after registration.",
|
||||
targetValue: 0.4,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 7,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "retention_d7",
|
||||
category: "retention",
|
||||
nameSv: "D7-retention",
|
||||
nameEn: "D7 retention",
|
||||
descriptionSv: "Andel användare aktiva sju dagar efter registrering.",
|
||||
descriptionEn: "Share of users active seven days after registration.",
|
||||
targetValue: 0.2,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 14,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "retention_d30",
|
||||
category: "retention",
|
||||
nameSv: "D30-retention",
|
||||
nameEn: "D30 retention",
|
||||
descriptionSv: "Andel användare aktiva 30 dagar efter registrering.",
|
||||
descriptionEn: "Share of users active 30 days after registration.",
|
||||
targetValue: 0.1,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 60,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "retention_week4_household",
|
||||
category: "retention",
|
||||
nameSv: "Hushållsretention vecka 4",
|
||||
nameEn: "Week 4 household retention",
|
||||
descriptionSv: "Andel hushåll aktiva under vecka fyra.",
|
||||
descriptionEn: "Share of households active in week four.",
|
||||
targetValue: 0.15,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 35,
|
||||
blocking: false,
|
||||
},
|
||||
{
|
||||
gateKey: "paid_month2_retention",
|
||||
category: "retention",
|
||||
nameSv: "Betald månad 2-retention",
|
||||
nameEn: "Paid month 2 retention",
|
||||
descriptionSv: "Andel betalande hushåll kvar vid månad två.",
|
||||
descriptionEn: "Share of paying households retained at month two.",
|
||||
targetValue: 0.5,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 90,
|
||||
blocking: true,
|
||||
},
|
||||
|
||||
// Economy
|
||||
{
|
||||
gateKey: "trial_to_paid_rate",
|
||||
category: "economy",
|
||||
nameSv: "Trial till betalande",
|
||||
nameEn: "Trial to paid",
|
||||
descriptionSv: "Andel trial-användare som blir betalande.",
|
||||
descriptionEn: "Share of trial users who convert to paid.",
|
||||
targetValue: 0.25,
|
||||
comparison: "gte",
|
||||
evaluationWindowDays: 30,
|
||||
blocking: true,
|
||||
},
|
||||
{
|
||||
gateKey: "refund_rate",
|
||||
category: "economy",
|
||||
nameSv: "Återbetalningsgrad",
|
||||
nameEn: "Refund rate",
|
||||
descriptionSv: "Andel betalningar som återbetalas.",
|
||||
descriptionEn: "Share of payments refunded.",
|
||||
targetValue: 0.05,
|
||||
comparison: "lte",
|
||||
evaluationWindowDays: 30,
|
||||
blocking: false,
|
||||
},
|
||||
{
|
||||
gateKey: "monthly_churn",
|
||||
category: "economy",
|
||||
nameSv: "Månatlig churn",
|
||||
nameEn: "Monthly churn",
|
||||
descriptionSv: "Andel betalande hushåll som avslutar per månad.",
|
||||
descriptionEn: "Share of paying households that churn per month.",
|
||||
targetValue: 0.1,
|
||||
comparison: "lte",
|
||||
evaluationWindowDays: 60,
|
||||
blocking: false,
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user