Add/customer mcp (#1055)
* feat(mcp): kontoplan account tools + verifikat notes exposure Two gaps reported by an MCP-driven user: no account management in the API, and verifikat notes invisible to agents (they exist in the product but MCP could neither read nor write them). - add staged gnubok_create_account / gnubok_update_account (BAS 2026 prefill for catalog numbers; rename/VAT-default/SRU/activate via update; both LOW risk reference data) - add staged gnubok_set_voucher_note (notes-only annotation, legal on posted entries per the 20260608120000 trigger carve-out) and return entry_notes from gnubok_query_journal - new pending_operations types create_account / update_account / set_voucher_note (CHECK migration + validate companion, applied to staging) - tools/list payload ceiling 54K -> 56K (documented; wire contract, descriptions trimmed first) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(skatteverket): unstick BankID connect flow and stale connection views - respond to the OAuth callback immediately and run the post-connect refresh after the response (next/server after()): users no longer stare at Skatteverket's consumed consent page for up to 40s - open the consent flow in a full tab instead of a 600x750 popup that hid the approve button below the fold - disable connect buttons while the OAuth tab is open (parallel flows overwrote oauth_state + the PKCE verifier) and recover via a closed-tab watcher plus a delayed status refetch - persist MISSING_SCOPE token health from the post-connect sync and show an actionable "approve all permissions" notice - refetch connection state on tab visibility (settings connect panel, enable-banking panel, /skattekonto) so a connect completed in another tab or after a mobile app-switch shows up without a manual reload; fix /skattekonto never clearing its not-connected state Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(article-form): add article number field with validation to ArticleForm * feat(account): enforce account type consistency with BAS class and add validation --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bfd5b42eb1
commit
0e9cca2750
@@ -131,6 +131,7 @@ export default function ArticleForm({
|
||||
const schema = useMemo(
|
||||
() =>
|
||||
z.object({
|
||||
article_number: z.string().trim().max(64, t('number_too_long')).optional(),
|
||||
name: z.string().min(1, t('name_required')),
|
||||
name_en: z.string().optional(),
|
||||
type: z.enum(['vara', 'tjanst']),
|
||||
@@ -161,6 +162,7 @@ export default function ArticleForm({
|
||||
} = useForm<FormData>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
article_number: initialData?.article_number || '',
|
||||
name: initialData?.name || '',
|
||||
name_en: initialData?.name_en || '',
|
||||
type: initialData?.type || 'tjanst',
|
||||
@@ -180,6 +182,7 @@ export default function ArticleForm({
|
||||
|
||||
const onFormSubmit = (data: FormData) => {
|
||||
onSubmit({
|
||||
article_number: data.article_number?.trim() || null,
|
||||
name: data.name,
|
||||
name_en: data.name_en || null,
|
||||
type: data.type,
|
||||
@@ -197,24 +200,39 @@ export default function ArticleForm({
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onFormSubmit)} className="space-y-6">
|
||||
{/* Type */}
|
||||
<div className="space-y-2">
|
||||
<Label>{t('type_label')}</Label>
|
||||
<Controller
|
||||
name="type"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select value={field.value} onValueChange={(v) => { if (v) field.onChange(v) }}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('type_placeholder')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="vara">{t('type_vara')}</SelectItem>
|
||||
<SelectItem value="tjanst">{t('type_tjanst')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{/* Type + article number */}
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<Label>{t('type_label')}</Label>
|
||||
<Controller
|
||||
name="type"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select value={field.value} onValueChange={(v) => { if (v) field.onChange(v) }}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('type_placeholder')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="vara">{t('type_vara')}</SelectItem>
|
||||
<SelectItem value="tjanst">{t('type_tjanst')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="article_number">{t('number_label')}</Label>
|
||||
<Input
|
||||
id="article_number"
|
||||
className="tabular-nums"
|
||||
{...register('article_number')}
|
||||
/>
|
||||
{errors.article_number ? (
|
||||
<p className="text-sm text-destructive">{errors.article_number.message}</p>
|
||||
) : (
|
||||
<p className="text-xs text-muted-foreground">{t('number_hint')}</p>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Name */}
|
||||
|
||||
Reference in New Issue
Block a user