feat: store-level "Group bursts" toggle + idle-window field
Adds group_burst (0/1) + burst_window_sec to the Store type and the StoreModal editor. Drives finbot's Amazon burst-grouping: when ON, finbot collapses rapid same-merchant charge bursts into one Firefly transaction group; the optional idle window (blank = 180s) closes the group. Backend INSERT/UPDATE carry the fields; GET is SELECT * so reads are free. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5fc745edd3
commit
9f901ec50d
2 changed files with 42 additions and 0 deletions
|
|
@ -23,6 +23,8 @@ export function StoreModal({ store, categories, availableTags, onSave, onClose }
|
||||||
tagList: parseTags(store?.tags ?? ''),
|
tagList: parseTags(store?.tags ?? ''),
|
||||||
route: (store?.route ?? 'auto') as Route,
|
route: (store?.route ?? 'auto') as Route,
|
||||||
display_order: store?.display_order ?? 0,
|
display_order: store?.display_order ?? 0,
|
||||||
|
group_burst: store?.group_burst ?? 0,
|
||||||
|
burst_window_sec: store?.burst_window_sec ?? null,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Keep category default once categories load
|
// Keep category default once categories load
|
||||||
|
|
@ -137,6 +139,41 @@ export function StoreModal({ store, categories, availableTags, onSave, onClose }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Burst grouping */}
|
||||||
|
<div className="space-y-1.5">
|
||||||
|
<label className="text-xs font-medium text-slate-400 uppercase tracking-wider">
|
||||||
|
Burst Grouping
|
||||||
|
</label>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => set('group_burst', form.group_burst ? 0 : 1)}
|
||||||
|
className={`w-full flex items-center justify-between rounded-xl px-3.5 py-2.5 text-sm border transition-colors ${
|
||||||
|
form.group_burst
|
||||||
|
? 'bg-blue-500/15 border-blue-500/50 text-slate-100'
|
||||||
|
: 'bg-surface-800 border-white/8 text-slate-400 hover:text-slate-300'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>Group rapid same-merchant charges</span>
|
||||||
|
<span className={`text-xs font-semibold ${form.group_burst ? 'text-blue-400' : 'text-slate-500'}`}>
|
||||||
|
{form.group_burst ? 'ON' : 'OFF'}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{form.group_burst ? (
|
||||||
|
<div className="flex items-center gap-2 pt-1">
|
||||||
|
<label className="text-xs text-slate-500 whitespace-nowrap">Idle window (sec)</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min={10}
|
||||||
|
value={form.burst_window_sec ?? ''}
|
||||||
|
onChange={e => set('burst_window_sec', e.target.value === '' ? null : Number(e.target.value))}
|
||||||
|
placeholder="180"
|
||||||
|
className="w-24 bg-surface-800 border border-white/8 rounded-lg px-2.5 py-1.5 text-sm text-slate-200 placeholder:text-slate-600 focus:outline-none focus:border-blue-500/60"
|
||||||
|
/>
|
||||||
|
<span className="text-xs text-slate-600">blank = 180s</span>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Actions */}
|
{/* Actions */}
|
||||||
<div className="flex gap-2 pt-1">
|
<div className="flex gap-2 pt-1">
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@ export interface Store {
|
||||||
tags: string
|
tags: string
|
||||||
route: Route
|
route: Route
|
||||||
display_order: number
|
display_order: number
|
||||||
|
// Burst-grouping: when 1, finbot collapses same-merchant charge bursts
|
||||||
|
// (e.g. Amazon Subscribe & Save) into one Firefly transaction group.
|
||||||
|
// burst_window_sec = idle gap that closes the group (NULL = global 180s).
|
||||||
|
group_burst: number
|
||||||
|
burst_window_sec: number | null
|
||||||
created_at: string
|
created_at: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue