ci: trigga på master + formatfix inför Gitea Actions
CI / Typecheck, test & build (push) Failing after 2s

This commit is contained in:
Sven (AAMOS AI)
2026-08-13 17:25:14 +07:00
parent 61d60931ad
commit c32a7e33c7
141 changed files with 40555 additions and 45210 deletions
@@ -18,7 +18,12 @@ export interface ExistingProfile {
averageEatenPortions: number | null;
averageLeftoverPortions: number | null;
observationCount: number;
lastSessionAnswers?: Array<{ sessionId: string; eaten: number; leftovers: number; date: string }> | null;
lastSessionAnswers?: Array<{
sessionId: string;
eaten: number;
leftovers: number;
date: string;
}> | null;
}
/**
@@ -48,7 +48,9 @@ const MS_PER_DAY = 86_400_000;
* Deterministisk, UTC, alltid samma svar för samma input.
*/
export function buildReconciliationCandidates(
items: Array<InventoryItemLike & { id: string; displayName: string; unit: string; locationName: string }>,
items: Array<
InventoryItemLike & { id: string; displayName: string; unit: string; locationName: string }
>,
context: ReconciliationContext,
now: Date = new Date(),
maxItems = 15,
+1 -6
View File
@@ -19,12 +19,7 @@ export interface NewScanObservation {
observationConfidence: number;
}
export type ScanDiffRowKind =
| "new_item"
| "moved"
| "quantity_changed"
| "vanished"
| "unchanged";
export type ScanDiffRowKind = "new_item" | "moved" | "quantity_changed" | "vanished" | "unchanged";
export interface ScanDiffRow {
kind: ScanDiffRowKind;
+4 -5
View File
@@ -175,7 +175,8 @@ export function householdTrustScore(
// 3. Andel uppskattade mängder (0100, 100 = alla har confidence 1)
const confidenceScore =
items.reduce((sum, i) => sum + Math.min(1, Math.max(0, i.confidence)), 0) / items.length * 100;
(items.reduce((sum, i) => sum + Math.min(1, Math.max(0, i.confidence)), 0) / items.length) *
100;
// 4. Poster som borde vara slut (0100, 100 = inga låga kvantiteter)
const depletionScore =
@@ -189,15 +190,13 @@ export function householdTrustScore(
// 5. Korrigeringsfrekvens (0100, 100 = inga korrigeringar)
const correctionRatio =
input.transactionCount30d > 0
? input.correctionCount30d / input.transactionCount30d
: 0;
input.transactionCount30d > 0 ? input.correctionCount30d / input.transactionCount30d : 0;
const correctionScore = Math.max(0, 100 - correctionRatio * 200);
const score = Math.round(
verifiedScore * 0.25 +
ageScore * 0.25 +
confidenceScore * 0.20 +
confidenceScore * 0.2 +
depletionScore * 0.15 +
correctionScore * 0.15,
);
@@ -44,8 +44,22 @@ describe("updateCookingAssumptionProfile", () => {
});
it("keeps a rolling history of last 10 sessions", () => {
type Profile = { averageEatenPortions: number | null; averageLeftoverPortions: number | null; observationCount: number; lastSessionAnswers?: Array<{ sessionId: string; eaten: number; leftovers: number; date: string }> | null };
let existing: Profile = { averageEatenPortions: null, averageLeftoverPortions: null, observationCount: 0 };
type Profile = {
averageEatenPortions: number | null;
averageLeftoverPortions: number | null;
observationCount: number;
lastSessionAnswers?: Array<{
sessionId: string;
eaten: number;
leftovers: number;
date: string;
}> | null;
};
let existing: Profile = {
averageEatenPortions: null,
averageLeftoverPortions: null,
observationCount: 0,
};
for (let i = 0; i < 12; i++) {
existing = updateCookingAssumptionProfile(
{
@@ -91,7 +105,12 @@ describe("rollbackCookingAssumptionProfile", () => {
averageEatenPortions: number | null;
averageLeftoverPortions: number | null;
observationCount: number;
lastSessionAnswers?: Array<{ sessionId: string; eaten: number; leftovers: number; date: string }> | null;
lastSessionAnswers?: Array<{
sessionId: string;
eaten: number;
leftovers: number;
date: string;
}> | null;
} = { averageEatenPortions: null, averageLeftoverPortions: null, observationCount: 0 };
// Three chronological observations.
@@ -134,7 +153,12 @@ describe("rollbackCookingAssumptionProfile", () => {
averageEatenPortions: number | null;
averageLeftoverPortions: number | null;
observationCount: number;
lastSessionAnswers?: Array<{ sessionId: string; eaten: number; leftovers: number; date: string }> | null;
lastSessionAnswers?: Array<{
sessionId: string;
eaten: number;
leftovers: number;
date: string;
}> | null;
} = { averageEatenPortions: null, averageLeftoverPortions: null, observationCount: 0 };
existing = updateCookingAssumptionProfile(
{
@@ -3,7 +3,9 @@ import { buildReconciliationCandidates } from "../src/reconciliation.js";
const PINNED = new Date("2026-08-07T00:00:00.000Z");
function baseItem(overrides: Partial<Parameters<typeof buildReconciliationCandidates>[0][number]> = {}) {
function baseItem(
overrides: Partial<Parameters<typeof buildReconciliationCandidates>[0][number]> = {},
) {
return {
id: "itm-1",
displayName: "Mjölk",
@@ -22,7 +24,12 @@ describe("buildReconciliationCandidates", () => {
it("returns empty when no items match", () => {
const result = buildReconciliationCandidates(
[baseItem({ quantity: 0, depletedAt: PINNED })],
{ plannedRecipeIngredientIds: new Map(), daysLeftByItemId: new Map(), dailyConsumptionRate: new Map(), priceMinorByItemId: new Map() },
{
plannedRecipeIngredientIds: new Map(),
daysLeftByItemId: new Map(),
dailyConsumptionRate: new Map(),
priceMinorByItemId: new Map(),
},
PINNED,
);
expect(result).toEqual([]);
@@ -69,7 +76,12 @@ describe("buildReconciliationCandidates", () => {
const item = baseItem({ confidence: 0.3, verifiedByUser: false });
const result = buildReconciliationCandidates(
[item],
{ plannedRecipeIngredientIds: new Map(), daysLeftByItemId: new Map(), dailyConsumptionRate: new Map(), priceMinorByItemId: new Map() },
{
plannedRecipeIngredientIds: new Map(),
daysLeftByItemId: new Map(),
dailyConsumptionRate: new Map(),
priceMinorByItemId: new Map(),
},
PINNED,
);
expect(result[0]?.reasons).toContainEqual({ kind: "low_confidence", confidence: 0.3 });
@@ -92,11 +104,20 @@ describe("buildReconciliationCandidates", () => {
it("caps results at maxItems", () => {
const items = Array.from({ length: 20 }, (_, i) =>
baseItem({ id: `itm-${i}`, displayName: `Vara ${String(i).padStart(2, "0")}`, confidence: 0.1 }),
baseItem({
id: `itm-${i}`,
displayName: `Vara ${String(i).padStart(2, "0")}`,
confidence: 0.1,
}),
);
const result = buildReconciliationCandidates(
items,
{ plannedRecipeIngredientIds: new Map(), daysLeftByItemId: new Map(), dailyConsumptionRate: new Map(), priceMinorByItemId: new Map() },
{
plannedRecipeIngredientIds: new Map(),
daysLeftByItemId: new Map(),
dailyConsumptionRate: new Map(),
priceMinorByItemId: new Map(),
},
PINNED,
5,
);
+39 -6
View File
@@ -98,7 +98,10 @@ describe("computeTrust", () => {
describe("householdTrustScore", () => {
it("returns 100 / up_to_date for empty inventory", () => {
const result = householdTrustScore({ items: [], correctionCount30d: 0, transactionCount30d: 0 }, PINNED);
const result = householdTrustScore(
{ items: [], correctionCount30d: 0, transactionCount30d: 0 },
PINNED,
);
expect(result.score).toBe(100);
expect(result.status).toBe("up_to_date");
});
@@ -107,8 +110,20 @@ describe("householdTrustScore", () => {
const result = householdTrustScore(
{
items: [
{ confidence: 1, verifiedByUser: true, lastVerifiedAt: PINNED, quantity: 2, updatedAt: PINNED },
{ confidence: 1, verifiedByUser: true, lastVerifiedAt: PINNED, quantity: 3, updatedAt: PINNED },
{
confidence: 1,
verifiedByUser: true,
lastVerifiedAt: PINNED,
quantity: 2,
updatedAt: PINNED,
},
{
confidence: 1,
verifiedByUser: true,
lastVerifiedAt: PINNED,
quantity: 3,
updatedAt: PINNED,
},
],
correctionCount30d: 0,
transactionCount30d: 0,
@@ -124,7 +139,13 @@ describe("householdTrustScore", () => {
const result = householdTrustScore(
{
items: [
{ confidence: 0.3, verifiedByUser: false, lastVerifiedAt: null, quantity: 0.1, updatedAt: old },
{
confidence: 0.3,
verifiedByUser: false,
lastVerifiedAt: null,
quantity: 0.1,
updatedAt: old,
},
],
correctionCount30d: 5,
transactionCount30d: 10,
@@ -140,8 +161,20 @@ describe("householdTrustScore", () => {
const result = householdTrustScore(
{
items: [
{ confidence: 0.8, verifiedByUser: true, lastVerifiedAt: weekAgo, quantity: 1, updatedAt: weekAgo },
{ confidence: 0.5, verifiedByUser: false, lastVerifiedAt: null, quantity: 1, updatedAt: weekAgo },
{
confidence: 0.8,
verifiedByUser: true,
lastVerifiedAt: weekAgo,
quantity: 1,
updatedAt: weekAgo,
},
{
confidence: 0.5,
verifiedByUser: false,
lastVerifiedAt: null,
quantity: 1,
updatedAt: weekAgo,
},
],
correctionCount30d: 1,
transactionCount30d: 5,