Let imports opt out of AI classification

Classification preferences gains "Classify newly imported transactions with
AI", stored as classify_on_import in config.toml and on by default, so existing
configurations keep their behaviour. It covers CSV imports and bank
synchronization alike.

With it off, no import path contacts the provider: classification falls to the
new provider-free rules path, where an opted-in merchant rule still applies its
category and tags, an alias match still attaches its merchant, and everything
else arrives on the editable fallback without a provenance error that would
suggest the provider had failed. Analyse remains available on demand.
This commit is contained in:
Lars Nolden
2026-09-11 18:10:05 +02:00
parent dc767799bc
commit dece0d5b79
10 changed files with 217 additions and 30 deletions
+22 -1
View File
@@ -16,6 +16,9 @@ export function Settings({ state, mutate }: { state: State; mutate: Mutate }) {
const [includeAmount, setIncludeAmount] = useState(
state.settings.include_amount,
);
const [classifyOnImport, setClassifyOnImport] = useState(
state.settings.classify_on_import,
);
const [busy, setBusy] = useState(false);
const [error, setError] = useState("");
const [rebuild, setRebuild] = useState(false);
@@ -334,7 +337,11 @@ export function Settings({ state, mutate }: { state: State; mutate: Mutate }) {
try {
await mutate(
"/api/settings",
{ model: model.trim(), include_amount: includeAmount },
{
model: model.trim(),
include_amount: includeAmount,
classify_on_import: classifyOnImport,
},
"Classification preferences saved",
);
} catch (err) {
@@ -366,6 +373,20 @@ export function Settings({ state, mutate }: { state: State; mutate: Mutate }) {
Disabled by default for privacy. Enabling this shares the amount
with the configured AI provider to help classification.
</p>
<label className="checkbox">
<input
type="checkbox"
checked={classifyOnImport}
onChange={(e) => setClassifyOnImport(e.target.checked)}
/>
Classify newly imported transactions with AI
</label>
<p className="muted small">
Applies to CSV imports and bank synchronization. When off, no
import contacts your AI provider: enabled merchant rules still
classify, and everything else arrives unclassified and editable.
AI classification Analyse is unaffected.
</p>
<button
className="button primary"
disabled={busy || credentialsBusy}