fix: day as nested object, not dotted paths
and touching the same field (day.km) caused MongoDB to throw a 500, holding all cached chunks back. Seed the whole day subdocument instead. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,13 +7,13 @@ export const runtime = "nodejs";
|
|||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upsert on (installationId, date), incrementally. The car sends a 30-minute delta chunk
|
* Upsert on (installationId, date), incrementally. The car sends a 2-minute delta chunk
|
||||||
* (not a cumulative total), so each PUT adds to the day's running totals rather than
|
* (not a cumulative total), so each PUT adds to the day's running totals rather than
|
||||||
* overwriting them. Lifetime is a snapshot — the latest one wins, so it is $set not $inc.
|
* overwriting them. Lifetime is a snapshot — the latest one wins, so it is $set not $inc.
|
||||||
*
|
*
|
||||||
* The old cumulative-overwrite format still works: a record whose day totals already
|
* $setOnInsert seeds the whole `day` subdocument as a nested object (not dotted paths)
|
||||||
* represent the full day simply adds them again, which is wrong — but the app no longer
|
* because $inc and $setOnInsert cannot touch the same field — MongoDB rejects that with
|
||||||
* sends that format, and the legacy 189 km document is never re-sent. New data only.
|
* a 500, which is what held the 20 cached chunks back.
|
||||||
*/
|
*/
|
||||||
export async function PUT(request: Request) {
|
export async function PUT(request: Request) {
|
||||||
const denied = requireIngest(request);
|
const denied = requireIngest(request);
|
||||||
@@ -23,27 +23,26 @@ export async function PUT(request: Request) {
|
|||||||
await ensureIndexes();
|
await ensureIndexes();
|
||||||
const collection = await consumptionCollection();
|
const collection = await consumptionCollection();
|
||||||
const updatedAt = new Date();
|
const updatedAt = new Date();
|
||||||
const setOnInsert: Record<string, unknown> = {
|
const $set: Record<string, unknown> = { updatedAt };
|
||||||
createdAt: updatedAt,
|
if (record.lifetime) $set.lifetime = record.lifetime;
|
||||||
installationId: record.installationId,
|
if (record.sohPercent !== undefined) $set.sohPercent = record.sohPercent;
|
||||||
date: record.date,
|
|
||||||
"day.km": 0, "day.kwh": 0, "day.hours": 0, "day.socDrop": 0,
|
|
||||||
};
|
|
||||||
const update: Record<string, Record<string, unknown>> = {
|
|
||||||
$inc: {
|
|
||||||
"day.km": record.day.km,
|
|
||||||
"day.kwh": record.day.kwh,
|
|
||||||
"day.hours": record.day.hours,
|
|
||||||
"day.socDrop": record.day.socDrop,
|
|
||||||
},
|
|
||||||
$set: { updatedAt },
|
|
||||||
$setOnInsert: setOnInsert,
|
|
||||||
};
|
|
||||||
if (record.lifetime) update.$set.lifetime = record.lifetime;
|
|
||||||
if (record.sohPercent !== undefined) update.$set.sohPercent = record.sohPercent;
|
|
||||||
await collection.updateOne(
|
await collection.updateOne(
|
||||||
{ installationId: record.installationId, date: record.date },
|
{ installationId: record.installationId, date: record.date },
|
||||||
update,
|
{
|
||||||
|
$inc: {
|
||||||
|
"day.km": record.day.km,
|
||||||
|
"day.kwh": record.day.kwh,
|
||||||
|
"day.hours": record.day.hours,
|
||||||
|
"day.socDrop": record.day.socDrop,
|
||||||
|
},
|
||||||
|
$set,
|
||||||
|
$setOnInsert: {
|
||||||
|
createdAt: updatedAt,
|
||||||
|
installationId: record.installationId,
|
||||||
|
date: record.date,
|
||||||
|
day: { km: 0, kwh: 0, hours: 0, socDrop: 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
return new NextResponse(null, { status: 204 });
|
return new NextResponse(null, { status: 204 });
|
||||||
|
|||||||
Reference in New Issue
Block a user