Gap 1 (spec §5): ExpectedBand only listed this month's occurrences, so a lastCharge bill whose pending slot had rolled into next month (the phone-bill flagship case) was not confirmable without navigating there first. Extend the walk 12 months past the displayed month (occurrencesByMonth's own upToMonth bound; foldBalances is untouched) and surface a "Coming up" group: at most one row per recurring cost, its next unconfirmed occurrence. That row confirms EARLY, so it records today rather than the future slot date — which is exactly what rebases a lastCharge series — and shows both dates so the owner can see what will be written. `today` is exported from src/store/index.ts next to `currentMonth`, keeping the clock out of src/domain/. expectedGroups() is the pure, exported core (pending/overdue/comingUp); ExpectedBand renders it and still returns null when all three are empty.
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { monthOf } from "../domain/months.ts";
|
|
import { readDataset, writeDataset } from "./db.ts";
|
|
import { createSnapshotStore } from "./snapshot.ts";
|
|
import { BAKED_FX_RATES } from "./bakedRates.ts";
|
|
import type { IsoDate } from "../domain/types.ts";
|
|
|
|
/** The current month, read at module load. The UI owns the clock; the domain does not. */
|
|
export const currentMonth = monthOf(new Date().toISOString().slice(0, 10));
|
|
|
|
/**
|
|
* Today, day-granular, read at module load. The UI owns the clock; the domain
|
|
* does not. `ExpectedBand`'s "Coming up" group needs the actual day — a
|
|
* coming-up occurrence is confirmed EARLY, so the purchase it writes must be
|
|
* dated today rather than the future slot, which is exactly what rebases a
|
|
* `lastCharge` series.
|
|
*/
|
|
export const today: IsoDate = new Date().toISOString().slice(0, 10);
|
|
|
|
export const store = createSnapshotStore(
|
|
{ read: readDataset, write: writeDataset },
|
|
currentMonth,
|
|
// First run only, so a fresh install can convert a EUR purchase on day one.
|
|
// Never a backstop for a rate the user has cleared.
|
|
BAKED_FX_RATES,
|
|
);
|
|
|
|
export * from "./snapshot.ts";
|
|
export { UnsupportedSchemaError } from "./migrations.ts";
|