fix(templates): explain the Kostnad/Intäkt vs Betalning choice in the mall editor (#1325)

* fix(templates): explain the radtyp choice, and give the assistant product knowledge

A user reported not knowing when to pick Kostnad vs Betalning on a
template line, and that the in-app assistant could not answer either.

UI, at the point of choice:
- The editor dropdown said "Kostnad" while the template list said
  "Kostnad/Intäkt" for the same tag; both now use type_cost_revenue.
- An InfoTooltip on the Rader label explains the three radtyper: what
  each one means, that the tag never changes which account is booked,
  and the exactly-one-of-each rule that makes a template pickable
  directly on a bank transaction.

Assistant, structurally: a new always-active 'product' atom tier for
knowledge about Accounted's own features, which no existing tier could
hold (horizontal/vertical/modifier are accounting-domain and
composer-owned). First atom: product/bokforingsmallar. The tier CHECK
migration must precede the generated seed; product atoms are
composer-invisible because every composer filter picks a specific tier.
The general-help and settings-help intents now route feature questions
to product atoms instead of guessing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(agent): widen the remaining tier unions the product tier missed

The zero-extensions build caught emitSkillLoaded pinning a literal copy of
the old SkillTier union. The same sweep found two surfaces the type system
could not flag: the mcp.skill_loaded event type, and the Vad din agent vet
overview (agent-competence + CompetenceCard), which queries the registry
with no tier filter and would have rendered product atoms as dormant.
Product atoms are always active there too, labelled with a new tier_product
string in both locales.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(agent): cover empty-slug 400 and curation-off 404; mention product knowledge in the panel help

Review follow-ups: the 404 test only covered a missing row, not a row
with mcp_exposed=false, and the empty-slug validation path was untested.
The Kunskap panel's help popover still described the library as only
Swedish accounting and tax knowledge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* revert(agent): pull assistant product knowledge back out; ship the UI clarification only

Founder call 2026-07-31: the assistant gets no internal knowledge of
Accounted's own features yet. This removes the product atom tier, the
bokforingsmallar atom, both migrations, the discovery/MCP/panel wiring,
and the intent routing added in the earlier commits; the working
implementation stays in this branch's history (green at bb65224c) and is
tracked in a follow-up issue. What ships: the unified Kostnad/Intäkt
label and the radtyp InfoTooltip in the template editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Jakob Wennberg <jakob.wennberg@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-01 15:57:24 +02:00
committed by GitHub
co-authored by Claude Fable 5 Jakob Wennberg
parent 4933fae7a9
commit f24e1076cf
4 changed files with 9 additions and 4 deletions
+2
View File
@@ -721,3 +721,5 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-07-30] The sandbox lock on a paid extension workspace is checked BEFORE the capability gate, and gets its own state (ExtensionSandboxLockState), not the billing upsell. Every new company, sandbox included, gets a 30-day trial grant from the seed_trial trigger, so the paywall waves a demo company straight through onto a workspace whose external services lib/sandbox/guard.ts blocks. And an anonymous demo user has no billing to upgrade: the exit is "Skapa konto", which must sign the anonymous session out first (registering on top of it registers into the sandbox).
[2026-07-31] Seeded chart names corrected to BAS 2026 where the label contradicted what the engine books on the account (7210 'Semesterlöner' -> 'Löner till tjänstemän', 7010, 3001/3002), with an exact-literal + is_system_account backfill so user renames survive. The mislabel class fixed here is "name says X, bookings are Y": payroll books salaries to 7210, 12% revenue books to 3002. The 3100 'Momsfri försäljning' deviation from BAS ('Försäljning av varor utanför Sverige') stays: there the label and the ruta 42 mapping agree by design, so renaming to BAS would create the mismatch, not fix one.
[2026-07-31] Assistant product knowledge REVERTED before merge (founder call): the assistant gets no internal knowledge of Accounted's own features yet. The working product-tier implementation (agent_atom_registry CHECK widening, product/bokforingsmallar atom, discovery, MCP + panel wiring, all CI green at bb65224c) lives in fix/mall-line-type-clarity branch history and a follow-up issue for when it is wanted. Only the UI clarification ships for the radtyp confusion: unified "Kostnad/Intäkt" label and an InfoTooltip explaining the three radtyper at the point of choice.
+5 -2
View File
@@ -229,7 +229,10 @@ export function TemplateForm({
</div>
<div>
<Label>{t('lines_label')}</Label>
<div className="flex items-center gap-1">
<Label>{t('lines_label')}</Label>
<InfoTooltip content={t('line_types_help')} />
</div>
<div className="space-y-2 mt-1">
{lines.map((line, i) => {
const showRatioInput = showRatio && line.type === 'business'
@@ -271,7 +274,7 @@ export function TemplateForm({
<Select value={line.type} onValueChange={(v) => updateLineType(i, v as BookingTemplateLibraryLine['type'])}>
<SelectTrigger className="flex-1"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="business">{t('type_cost')}</SelectItem>
<SelectItem value="business">{t('type_cost_revenue')}</SelectItem>
<SelectItem value="vat">{t('type_vat')}</SelectItem>
<SelectItem value="settlement">{t('type_settlement')}</SelectItem>
</SelectContent>
+1 -1
View File
@@ -1931,7 +1931,6 @@
"vat_with_rate": "VAT {rate}%",
"type_settlement": "Payment",
"type_cost_revenue": "Cost/Revenue",
"type_cost": "Cost",
"type_vat": "VAT",
"debit_short": "D",
"credit_short": "C",
@@ -1943,6 +1942,7 @@
"category_label": "Category",
"entity_type_label": "Company type",
"lines_label": "Lines",
"line_types_help": "The line type controls how the amount is split, not which account is booked. Payment is the line where the money actually moves (e.g. 1930 business account) and takes the full amount. Cost/Revenue is what the purchase or sale is about (e.g. 5410 or 3011). VAT is calculated automatically from the total. To be selectable directly on a bank transaction, the template needs exactly one cost/revenue line and one payment line on opposite sides.",
"account_placeholder": "Account",
"description_short_placeholder": "Description",
"debit_label": "Debit",
+1 -1
View File
@@ -1931,7 +1931,6 @@
"vat_with_rate": "Moms {rate}%",
"type_settlement": "Betalning",
"type_cost_revenue": "Kostnad/Intäkt",
"type_cost": "Kostnad",
"type_vat": "Moms",
"debit_short": "D",
"credit_short": "K",
@@ -1943,6 +1942,7 @@
"category_label": "Kategori",
"entity_type_label": "Företagstyp",
"lines_label": "Rader",
"line_types_help": "Radtypen styr hur beloppet fördelas, inte vilket konto som bokförs. Betalning är raden där pengarna faktiskt rör sig (t.ex. 1930 Företagskonto) och får hela beloppet. Kostnad/Intäkt är det som köpet eller försäljningen avser (t.ex. 5410 eller 3011). Moms räknas ut automatiskt ur totalbeloppet. För att mallen ska kunna väljas direkt på en banktransaktion krävs exakt en kostnads-/intäktsrad och en betalningsrad på motsatt sida.",
"account_placeholder": "Konto",
"description_short_placeholder": "Beskrivning",
"debit_label": "Debet",