update ai insight migration for all page
This commit is contained in:
1 parent
07d36081ce
commit
18790ab8f6
69 files changed
+9457
-399
No files matched your search
@@ -0,0 +1,80 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { scopeScalarsToTimeframe, UNAVAILABLE } from '../insightScope.ts';
|
||||
|
||||
/**
|
||||
* Real shape of the FCR page's 7-day history for this cycle: the IoT scale
|
||||
* stopped reporting at day 38 and has written 0 ever since, and the flock was
|
||||
* fully harvested on day 48 so `ayam` ends at 0 too.
|
||||
*/
|
||||
const ROWS = [
|
||||
{ day: 42, fcr: 1.8, pakan: 1064, bobot_kg: 0, ayam: 1424 },
|
||||
{ day: 44, fcr: 1.81, pakan: 1067, bobot_kg: 0, ayam: 1314 },
|
||||
{ day: 46, fcr: 1.82, pakan: 1072, bobot_kg: 0, ayam: 1253 },
|
||||
{ day: 47, fcr: 1.78, pakan: 1073, bobot_kg: 1.38, ayam: 822 },
|
||||
{ day: 48, fcr: 1.7, pakan: 1073, bobot_kg: 0, ayam: 0 },
|
||||
];
|
||||
|
||||
const spec = (agg: 'last' | 'lastValid') => ({
|
||||
historyKey: 'tren',
|
||||
derive: {
|
||||
bobot_kg_out: { field: 'bobot_kg', agg },
|
||||
ayam_out: { field: 'ayam', agg },
|
||||
},
|
||||
});
|
||||
|
||||
describe('lastValid aggregation', () => {
|
||||
it('last takes the trailing zero — the reported bug', () => {
|
||||
const out = scopeScalarsToTimeframe({ tren: ROWS }, 'mingguan', spec('last'));
|
||||
expect(out.bobot_kg_out).toBe(0);
|
||||
expect(out.ayam_out).toBe(0);
|
||||
});
|
||||
|
||||
it('lastValid walks back past the zeros', () => {
|
||||
const out = scopeScalarsToTimeframe({ tren: ROWS }, 'mingguan', spec('lastValid'));
|
||||
expect(out.bobot_kg_out).toBe(1.38);
|
||||
expect(out.ayam_out).toBe(822);
|
||||
});
|
||||
|
||||
it('reports unavailable when every reading in the window is zero', () => {
|
||||
const allZero = [
|
||||
{ day: 47, bobot_kg: 0, ayam: 0 },
|
||||
{ day: 48, bobot_kg: 0, ayam: 0 },
|
||||
];
|
||||
const out = scopeScalarsToTimeframe({ tren: allZero }, 'mingguan', spec('lastValid'));
|
||||
expect(out.bobot_kg_out).toBe(UNAVAILABLE);
|
||||
expect(out.ayam_out).toBe(UNAVAILABLE);
|
||||
});
|
||||
|
||||
it('leaves a genuine non-zero final reading alone', () => {
|
||||
const rows = [
|
||||
{ day: 47, bobot_kg: 1.3, ayam: 900 },
|
||||
{ day: 48, bobot_kg: 1.45, ayam: 850 },
|
||||
];
|
||||
const out = scopeScalarsToTimeframe({ tren: rows }, 'mingguan', spec('lastValid'));
|
||||
expect(out.bobot_kg_out).toBe(1.45);
|
||||
expect(out.ayam_out).toBe(850);
|
||||
});
|
||||
});
|
||||
|
||||
describe('harian periode label starts at day 0', () => {
|
||||
it('labels cumulative window as hari ke-0 s/d ke-N even if first row is day 2', () => {
|
||||
const rows = [
|
||||
{ day: 2, fcr: 1.1 },
|
||||
{ day: 5, fcr: 1.2 },
|
||||
{ day: 8, fcr: 1.3 },
|
||||
];
|
||||
const out = scopeScalarsToTimeframe(
|
||||
{ tren: rows, fcr_terakhir: 1.3 },
|
||||
'harian',
|
||||
{
|
||||
historyKey: 'tren',
|
||||
derive: {
|
||||
fcr_out: { field: 'fcr', agg: 'lastValid', replaces: 'fcr_terakhir' },
|
||||
},
|
||||
},
|
||||
8
|
||||
);
|
||||
expect(out.periode).toBe('hari ke-0 s/d ke-8');
|
||||
expect(out.fcr_out).toBe(1.3);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user