S5: onboarding → minne + smaksignaler (user_stated)

This commit is contained in:
Sven (AAMOS AI)
2026-08-11 04:43:43 +07:00
parent 1e18146665
commit f86a37dd33
26 changed files with 10812 additions and 2 deletions
+7 -1
View File
@@ -6,6 +6,7 @@ import {
pgTable,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import {
@@ -47,6 +48,7 @@ export const memoryItems = pgTable(
index("memory_items_user_idx").on(t.userId, t.kind),
index("memory_items_household_idx").on(t.householdId, t.kind),
index("memory_items_key_idx").on(t.key),
uniqueIndex("memory_items_user_key_unique").on(t.userId, t.key),
],
);
@@ -59,13 +61,17 @@ export const tasteSignals = pgTable(
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
axis: tasteAxisEnum("axis").notNull(),
target: text("target"),
direction: doublePrecision("direction").notNull(),
strength: doublePrecision("strength").notNull().default(0.5),
origin: signalOriginEnum("origin").notNull(),
refRecipeId: uuid("ref_recipe_id").references(() => recipes.id, { onDelete: "set null" }),
createdAt: createdAt(),
},
(t) => [index("taste_signals_user_idx").on(t.userId, t.axis)],
(t) => [
index("taste_signals_user_idx").on(t.userId, t.axis),
uniqueIndex("taste_signals_user_axis_target_unique").on(t.userId, t.axis, t.target),
],
);
/** Food Memory (spec §39): långsiktiga matminnen kopplade till högtider och betyg. */
+15
View File
@@ -320,6 +320,21 @@ export function renderMemorySummary(
if (typeof v.spicePreference === "string") {
return `Spice preference: ${String(v.spicePreference)}`;
}
if (typeof v.goal === "string") {
return `Goal: ${String(v.goal)}`;
}
if (typeof v.primaryGoal === "string") {
return `Primary goal: ${String(v.primaryGoal)}`;
}
if (typeof v.allergen === "string") {
return `Allergy: ${String(v.allergen)}`;
}
if (typeof v.avoidIngredientId === "string") {
return `Avoids ingredient: ${String(v.avoidIngredientId)}`;
}
if (typeof v.spiceLevelMax === "number") {
return `Max spice level: ${v.spiceLevelMax}`;
}
}
return item.summarySv;
}
+2
View File
@@ -599,6 +599,8 @@ export interface TasteSignal {
direction: number;
strength: number;
origin: SignalOrigin;
/** Axis-specific target, e.g. a cuisine slug or canonical ingredient id. */
target?: string;
refRecipeId?: string;
createdAt: string;
}
+2
View File
@@ -477,6 +477,8 @@ export const TASTE_AXES = [
"sweetness",
"herbs",
"umami",
"cuisine",
"ingredient_avoid",
] as const;
export type TasteAxis = (typeof TASTE_AXES)[number];