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 ?? ''),
|
||||
route: (store?.route ?? 'auto') as Route,
|
||||
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
|
||||
|
|
@ -137,6 +139,41 @@ export function StoreModal({ store, categories, availableTags, onSave, onClose }
|
|||
/>
|
||||
</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 */}
|
||||
<div className="flex gap-2 pt-1">
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ export interface Store {
|
|||
tags: string
|
||||
route: Route
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue