From 20989379bb4cccbdf5ad6fe0acb9ea85b73f0f0b Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Thu, 28 May 2026 13:19:41 +0200 Subject: [PATCH] feat(sandbox,branding): prod-parity demo with AI gating + accounted rebrand (#585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(sandbox,branding): prod-parity demo with AI gating + accounted rebrand Sandbox now ships with seeded suppliers, supplier invoices, an asset, a verified agent_profile, and pending operations so the demo company exercises every prod surface. Server-side `guardSandbox()` short- circuits any AI or paid-external API call (Bedrock chat/composer, Resend invoice send, Riksbanken FX, VIES, etc.) and the AgentSheet swaps in a SandboxAgentPreview that explains what's gated and offers a register CTA. DashboardContent no longer mounts the NewUserChecklist when the agent is already built, fixing the path that let sandbox users still trigger /onboarding/agent. Visible branding flips from Gnubok to Accounted: new BrandWordmark component (Hedvig Letters Serif 700), new app/icon.png + PWA icons generated from the accounted icon, default appName updated. URLs, header names, API key prefixes, hostnames, and event/cookie/ localStorage keys keep `gnubok` — the rebrand is visual only. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(sandbox): hardcode supplier-invoice arrival numbers in seed get_next_arrival_number is MAX(arrival_number) + 1 against the same table we're about to insert into. Calling it twice before either row lands made both calls return 1, which then violated the (company_id, arrival_number) unique index — POST /api/sandbox/seed 500'd on first sandbox start. The seeded company is brand new in this branch so 1 and 2 are guaranteed unused; hardcoding side-steps the race entirely. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(sandbox): set paid_amount=0 on unpaid supplier invoice PostgREST normalizes the column set across rows in a bulk insert, so the second supplier invoice (Espresso House, status=registered) was being sent with paid_amount=null because the first row (Telia, paid) set it. supplier_invoices.paid_amount is NOT NULL DEFAULT 0; the default only kicks in when the column is *absent* from the payload, not when it's explicitly null. Set it inline to side-step the normalization. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(sandbox): set actor_type=agent_chat on seeded pending_operations pending_operations only allows user-scoped INSERTs via the `pending_operations_chat_insert` policy, which requires actor_type='agent_chat' alongside auth.uid()=user_id + company membership. The seed was inserting with the default actor_type='user', tripping the RLS check. Also lift risk_level from preview_data (where it was unused) onto the row itself, matching the column added in 20260430120000_pending_operations_actor_and_risk. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(pr-review): address PR #585 review feedback Fixes called out by the core-only CI check, Greptile, and the compliance + Swedish-accounting bots: - AGI Programnamn pinned back to 'gnubok' (CI blocker). The XML Skatteverket receives must keep the stable software identifier regardless of the visual rebrand — same rule as the v1 health endpoint's `service: 'gnubok'` literal. - handleCreateAccount in SandboxAgentPreview + ChatEmptyState now wraps signOut() in try/catch so a transient Supabase failure doesn't strand the user on a dead button (greptile P2 × 2). - /api/currency/rate hard-fails on missing companyId instead of conditionally skipping the sandbox guard (greptile P2 / compliance V8.2.1). - topUpSandboxAdditions now delegates to ensureSandboxAgentProfile; the assistant persona lives in exactly one place across the seed, layout backfills, and top-up path (greptile P2 outside-diff / compliance SOC2 CC6.1). - ensureSandboxAgentProfile drops the userId param and sets verified_by_user_id to NULL — synthetic seed data should not attribute verification to a real user (compliance V8.2.1 / GDPR Art. 25(2)). Errors now logged via the structured logger instead of being silently swallowed (V16). - Sandbox seed swaps real-world company names (Telia, Espresso House) for clearly-synthetic Demo-prefixed brands using the 5559... documentation org-number range (compliance A.8.33). Asset cost bumped 24 000 → 35 000 SEK so the demo clears the förbrukningsinventarier threshold and illustrates capitalization unambiguously (swedish-asset-accounting). - Representation pending-operation preview corrected: VAT label fixed from 6% → 12%, and input VAT split between the avdragsgill (2641) and ej-avdragsgill (5811) portions to match swedish-vat / ML 8 kap rules (swedish-vat). Co-Authored-By: Claude Opus 4.7 (1M context) * fix(pr-review): seed preview consistency + AGI Programnamn constant Two last review-bot items before merge: - Sandbox seed: the representation pending-operation preview was splitting the 240 SEK café meal 60/180 between 5810 and 5811, which is wrong for a single attendee under the 300 SEK / person avdragsgill cap (ML 8 kap) — the entire amount is fully avdragsgill in that case. Collapse the preview to a single 5810 + 2641 + 2440 entry so it matches the supplier_invoice_items row 1:1 and stops teaching demo users an incorrect bookkeeping pattern. - Hoist the AGI Programnamn 'gnubok' literal into a named constant with a comment pointing to potential future Skatteverket vendor registration (per the swedish-compliance bot's nit). Co-Authored-By: Claude Opus 4.7 (1M context) * fix(sandbox): avoid BFL duplicate-verification on pending op + fix VAT cap comment Swedish-compliance bot caught two final nits: - The pending operation for the Demokafé representation was using the same supplier_invoice_number as the already-seeded supplier_invoices row (88245). If the sandbox user approved the staged operation, the insert would have created (or attempted) a duplicate verification — BFL 5 kap. requires each affärshändelse be recorded exactly once. Swap the staged operation's invoice number to a distinct value (INKOMMANDE-2026-001) so approval cleanly creates a new row. - The preview comment described the 300 SEK threshold as an "avdragsgill cap". The actual rule (ML 8 kap. 9 §) caps the deductible VAT at 25 % × 300 SEK × antal_personer = 75 SEK per person — the 300 SEK is the tax base, not the total. Math here is correct either way, but the comment now states the correct formula so future seed edits don't propagate the wrong understanding. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- app/(auth)/login/page.tsx | 11 +- app/(auth)/register/page.tsx | 11 +- .../year-end/arsredovisning/page.tsx | 2 +- app/(dashboard)/chat/layout.tsx | 23 +- app/(dashboard)/layout.tsx | 24 +- app/(dashboard)/page.tsx | 18 +- app/(onboarding)/onboarding/agent/page.tsx | 11 + app/api/agent/composer/route.ts | 4 + app/api/agent/invoke/route.ts | 6 + app/api/agent/onboarding/stream/route.ts | 6 + app/api/currency/rate/route.ts | 12 + .../[id]/send/__tests__/route.test.ts | 9 + app/api/invoices/[id]/send/route.ts | 6 + app/api/sandbox/seed/route.ts | 270 +++++++++++++++++- .../[id]/refresh-exchange-rate/route.ts | 4 + .../[id]/send/__tests__/route.test.ts | 9 + .../[companyId]/invoices/[id]/send/route.ts | 6 + app/api/vat/validate/route.ts | 6 + app/companies/new/page.tsx | 12 +- app/docs/api/changelog/page.tsx | 4 +- app/docs/api/cookbook/[slug]/page.tsx | 2 +- app/docs/api/errors/page.tsx | 4 +- app/docs/api/page.tsx | 2 +- app/docs/api/reference/[slug]/page.tsx | 2 +- app/docs/api/reference/page.tsx | 4 +- app/docs/api/versioning/page.tsx | 2 +- app/docs/api/webhooks/page.tsx | 4 +- app/favicon.ico | Bin 15406 -> 0 bytes app/icon.png | Bin 0 -> 97318 bytes app/invite/[token]/page.tsx | 12 +- app/layout.tsx | 3 + app/sandbox/page.tsx | 44 +-- components/agent/AgentChat.tsx | 2 +- components/agent/AgentSheet.tsx | 24 +- components/agent/ChatConversationView.tsx | 25 +- components/agent/ChatEmptyState.tsx | 43 ++- components/agent/ChatIntakeStarter.tsx | 46 +-- components/agent/ChatNewStarter.tsx | 44 +-- components/agent/SandboxAgentPreview.tsx | 111 +++++++ components/branding/BrandWordmark.tsx | 45 +++ components/dashboard/DashboardContent.tsx | 16 +- components/dashboard/SandboxBanner.tsx | 2 +- components/docs/DocsLayout.tsx | 6 +- .../general/InvoiceInboxWorkspace.tsx | 2 +- components/invoices/SendInvoiceDialog.tsx | 12 +- components/salary/AGIPanel.tsx | 2 +- lib/branding/__tests__/service.test.ts | 10 +- lib/branding/service.ts | 9 +- lib/docs/content/landing.ts | 8 +- lib/salary/agi/xml-generator.ts | 10 +- lib/sandbox/__tests__/guard.test.ts | 59 ++++ lib/sandbox/ensure-agent.ts | 63 ++++ lib/sandbox/guard.ts | 60 ++++ messages/en.json | 10 +- messages/sv.json | 10 +- public/accounted-icon.png | Bin 0 -> 97318 bytes public/gnubokiceon-removebg-preview.png | Bin 108424 -> 0 bytes public/icons/icon-128.png | Bin 1246 -> 10642 bytes public/icons/icon-144.png | Bin 1438 -> 12774 bytes public/icons/icon-152.png | Bin 1541 -> 13844 bytes public/icons/icon-192.png | Bin 2066 -> 19345 bytes public/icons/icon-384.png | Bin 5586 -> 57528 bytes public/icons/icon-512.png | Bin 8625 -> 90980 bytes public/icons/icon-72.png | Bin 599 -> 4687 bytes public/icons/icon-96.png | Bin 843 -> 7061 bytes 65 files changed, 976 insertions(+), 176 deletions(-) delete mode 100644 app/favicon.ico create mode 100644 app/icon.png create mode 100644 components/agent/SandboxAgentPreview.tsx create mode 100644 components/branding/BrandWordmark.tsx create mode 100644 lib/sandbox/__tests__/guard.test.ts create mode 100644 lib/sandbox/ensure-agent.ts create mode 100644 lib/sandbox/guard.ts create mode 100644 public/accounted-icon.png delete mode 100644 public/gnubokiceon-removebg-preview.png diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index 629a1b76..2582262d 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -10,7 +10,7 @@ import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useToast } from '@/components/ui/use-toast' import { Loader2, Mail, ArrowLeft, KeyRound, ExternalLink } from 'lucide-react' -import Image from 'next/image' +import { BrandWordmark } from '@/components/branding/BrandWordmark' import { getErrorMessage, type ErrorLocale } from '@/lib/errors/get-error-message' import { isBankIdEnabled } from '@/lib/auth/bankid' import { BankIdAuth } from '@/components/auth/BankIdAuth' @@ -376,14 +376,7 @@ function LoginPageContent() {
- {branding.appName} +

{tAuth('login_subtitle')}

diff --git a/app/(auth)/register/page.tsx b/app/(auth)/register/page.tsx index c1473f0d..0fe8221f 100644 --- a/app/(auth)/register/page.tsx +++ b/app/(auth)/register/page.tsx @@ -10,7 +10,7 @@ import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useToast } from '@/components/ui/use-toast' import { Loader2, Mail, ArrowLeft, ExternalLink } from 'lucide-react' -import Image from 'next/image' +import { BrandWordmark } from '@/components/branding/BrandWordmark' import { getErrorMessage, type ErrorLocale } from '@/lib/errors/get-error-message' import { isBankIdEnabled } from '@/lib/auth/bankid' import { BankIdAuth } from '@/components/auth/BankIdAuth' @@ -410,14 +410,7 @@ function RegisterPageContent() {
- {branding.appName} +

{t('subtitle')}

diff --git a/app/(dashboard)/bookkeeping/year-end/arsredovisning/page.tsx b/app/(dashboard)/bookkeeping/year-end/arsredovisning/page.tsx index 2e1e6049..a0a4dc4b 100644 --- a/app/(dashboard)/bookkeeping/year-end/arsredovisning/page.tsx +++ b/app/(dashboard)/bookkeeping/year-end/arsredovisning/page.tsx @@ -700,7 +700,7 @@ export default function ArsredovisningPage() { Notis om digital inlämning: Bolagsverket har föreslagit att digital inlämning (iXBRL) av årsredovisning för aktiebolag ska bli obligatorisk — beslut och ikraftträdande är ännu inte fastställda. Idag är - PDF-inlämning fortfarande godkänd. Gnubok stödjer för närvarande endast + PDF-inlämning fortfarande godkänd. Accounted stödjer för närvarande endast PDF-utkast; iXBRL-generering är planerad till en kommande version.
diff --git a/app/(dashboard)/chat/layout.tsx b/app/(dashboard)/chat/layout.tsx index 1883ec0b..232fc8ba 100644 --- a/app/(dashboard)/chat/layout.tsx +++ b/app/(dashboard)/chat/layout.tsx @@ -1,6 +1,7 @@ import { createClient } from '@/lib/supabase/server' import { redirect } from 'next/navigation' import { getActiveCompanyId } from '@/lib/company/context' +import { ensureSandboxAgentProfile } from '@/lib/sandbox/ensure-agent' import ChatSidebar from '@/components/agent/ChatSidebar' export const dynamic = 'force-dynamic' @@ -21,11 +22,31 @@ export default async function ChatLayout({ children }: { children: React.ReactNo // empty conversations list with no Anna to talk to. The home route at / // renders NewUserChecklist for the same state, so we forward there // instead of duplicating the welcome screen here. - const { data: agent } = await supabase + let { data: agent } = await supabase .from('agent_profiles') .select('verified_at') .eq('company_id', companyId) .maybeSingle() + + // Sandbox sessions get a pre-built assistant — backfill if a pre-seed + // session is missing it so /chat doesn't bounce back to / in a loop. + if (!agent?.verified_at) { + const { data: settings } = await supabase + .from('company_settings') + .select('is_sandbox') + .eq('company_id', companyId) + .maybeSingle() + if (settings?.is_sandbox) { + await ensureSandboxAgentProfile(supabase, companyId) + const refresh = await supabase + .from('agent_profiles') + .select('verified_at') + .eq('company_id', companyId) + .maybeSingle() + agent = refresh.data + } + } + if (!agent?.verified_at) redirect('/') const { data: conversations } = await supabase diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index c6494210..a5ac505f 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -12,6 +12,7 @@ import { getExtensionNavItems } from '@/lib/extensions/sectors' import { CompanyProvider } from '@/contexts/CompanyContext' import { getActiveCompanyId } from '@/lib/company/context' import { getBranding } from '@/lib/branding/service' +import { ensureSandboxAgentProfile } from '@/lib/sandbox/ensure-agent' import type { EntityType, CompanyRole, Team } from '@/types' /** @@ -209,6 +210,23 @@ export default async function DashboardLayout({ const isSandbox = settings?.is_sandbox === true + // Backfill a verified agent_profile for sandbox sessions that pre-date the + // seed change. Without this an old anonymous session shows the "Bygg din + // bokföringsassistent" CTA in three places (dashboard hero, NewUserChecklist + // step 4, /chat layout redirect) and the user can still kick off a build + // flow that the server now 403s. Best-effort; doesn't block the layout + // even if the insert fails. + let resolvedAgentIdentity = agentProfileIdentity + if (isSandbox && !agentProfileIdentity?.verified_at) { + await ensureSandboxAgentProfile(supabase, companyId) + const { data: refreshed } = await supabase + .from('agent_profiles') + .select('display_name, avatar_id, verified_at') + .eq('company_id', companyId) + .maybeSingle() + resolvedAgentIdentity = refreshed ?? agentProfileIdentity + } + const companyContextValue = { company: companyWithName, role: memberRow.role as CompanyRole, @@ -229,9 +247,9 @@ export default async function DashboardLayout({ diff --git a/app/(dashboard)/page.tsx b/app/(dashboard)/page.tsx index 5b6af597..0c027382 100644 --- a/app/(dashboard)/page.tsx +++ b/app/(dashboard)/page.tsx @@ -5,6 +5,7 @@ import DashboardContent from '@/components/dashboard/DashboardContent' import WelcomeGate from '@/components/onboarding/WelcomeGate' import { getActiveCompanyId } from '@/lib/company/context' import { getDisplayTotal } from '@/lib/invoices/rounding' +import { ensureSandboxAgentProfile } from '@/lib/sandbox/ensure-agent' import type { Deadline, ReceiptQueueSummary, OnboardingProgress } from '@/types' export const dynamic = 'force-dynamic' @@ -122,7 +123,22 @@ export default async function DashboardPage() { redirect('/onboarding') } - const agentBuilt = Boolean(agentProfile?.verified_at) + // Sandbox sessions that pre-date the agent_profile seeding step would + // otherwise still see the "Bygg din bokföringsassistent" hero + the + // NewUserChecklist's agent step lit up. Backfill here so the next render + // sees a verified profile and treats the sandbox as fully set up. + let effectiveAgentVerified = agentProfile?.verified_at ?? null + if (settings?.is_sandbox === true && !effectiveAgentVerified) { + await ensureSandboxAgentProfile(supabase, companyId) + const { data: refreshed } = await supabase + .from('agent_profiles') + .select('verified_at') + .eq('company_id', companyId) + .maybeSingle() + effectiveAgentVerified = refreshed?.verified_at ?? null + } + + const agentBuilt = Boolean(effectiveAgentVerified) // "Has the company already been used?" Any real business data means we must // NOT hijack the dashboard with the full-screen onboarding gate — existing diff --git a/app/(onboarding)/onboarding/agent/page.tsx b/app/(onboarding)/onboarding/agent/page.tsx index 552846dd..941ae7d5 100644 --- a/app/(onboarding)/onboarding/agent/page.tsx +++ b/app/(onboarding)/onboarding/agent/page.tsx @@ -21,6 +21,17 @@ export default async function AgentOnboardingPage() { const companyId = await getActiveCompanyId(supabase, user.id) if (!companyId) redirect('/onboarding') + // Sandbox companies ship with a pre-built verified agent_profile — the + // build flow on this page would call TIC and the gated composer stream, + // both of which 403. Send them back to the dashboard where the demo + // assistant is already visible via the sheet preview. + const { data: settingsForSandbox } = await supabase + .from('company_settings') + .select('is_sandbox') + .eq('company_id', companyId) + .maybeSingle() + if (settingsForSandbox?.is_sandbox) redirect('/') + // Trigger the TIC live-fetch + cache before the field-resolving query // below. ensureTicSnapshot is fast on cache-hit (single SELECT) and // best-effort on miss — it never throws. Phase A still runs through the diff --git a/app/api/agent/composer/route.ts b/app/api/agent/composer/route.ts index 7c5c1de9..e1bd3ba3 100644 --- a/app/api/agent/composer/route.ts +++ b/app/api/agent/composer/route.ts @@ -4,6 +4,7 @@ import { z } from 'zod' import { getActiveCompanyId } from '@/lib/company/context' import { checkAgentRateLimit, agentRateLimitResponseBody } from '@/lib/rate-limits/agent' import { composeAgentProfile } from '@/lib/agent/composer' +import { guardSandbox } from '@/lib/sandbox/guard' const BodySchema = z.object({ // Optional override; if absent we use the user's active_company_id. @@ -63,6 +64,9 @@ export async function POST(request: Request) { return NextResponse.json({ error: 'Not a member of this company' }, { status: 403 }) } + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + try { const composed = await composeAgentProfile(supabase, companyId, { dryRun: body.dry_run }) return NextResponse.json({ data: composed }) diff --git a/app/api/agent/invoke/route.ts b/app/api/agent/invoke/route.ts index 061c35b0..d2fb0e80 100644 --- a/app/api/agent/invoke/route.ts +++ b/app/api/agent/invoke/route.ts @@ -6,6 +6,7 @@ import { getActiveCompanyId } from '@/lib/company/context' import { getIntent } from '@/lib/agent/intents/registry' import { checkAgentRateLimit, agentRateLimitResponseBody } from '@/lib/rate-limits/agent' import { runChatTurn, friendlyModelError } from '@/lib/agent/chat/run-turn' +import { guardSandbox } from '@/lib/sandbox/guard' // Make sure extensions are loaded — the chat loop dispatches against the // agent tool registry which is populated by the mcp-server extension at load. @@ -105,6 +106,11 @@ export async function POST(request: Request) { .maybeSingle() if (!membership) return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) + // No Anthropic Bedrock calls in the sandbox — the demo runs entirely on + // seed data and the assistant is gated to a "look, don't touch" preview. + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + // onboarding.intake completion signal — once the user has actually // engaged (typed a real reply, not the auto-fired greeting prompt that // mounts the chat), stamp intake_completed_at on the profile so re-entry diff --git a/app/api/agent/onboarding/stream/route.ts b/app/api/agent/onboarding/stream/route.ts index 5d119796..913d8b8d 100644 --- a/app/api/agent/onboarding/stream/route.ts +++ b/app/api/agent/onboarding/stream/route.ts @@ -2,6 +2,7 @@ import { createClient } from '@/lib/supabase/server' import { NextResponse } from 'next/server' import { z } from 'zod' import { getActiveCompanyId } from '@/lib/company/context' +import { guardSandbox } from '@/lib/sandbox/guard' import { checkAgentRateLimit, agentRateLimitResponseBody } from '@/lib/rate-limits/agent' import { gatherComposerInputs, inputsToSourceSignals } from '@/lib/agent/composer/inputs' import { selectAtoms } from '@/lib/agent/composer/atom-selection' @@ -100,6 +101,11 @@ export async function POST(request: Request) { return NextResponse.json({ error: 'Not a member of this company' }, { status: 403 }) } + // No live composer run for sandbox companies — they ship with a pre-built + // verified agent_profile so the chrome is visible without burning Bedrock. + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + const stream = new ReadableStream({ async start(controller) { const encoder = new TextEncoder() diff --git a/app/api/currency/rate/route.ts b/app/api/currency/rate/route.ts index c7208e42..16997579 100644 --- a/app/api/currency/rate/route.ts +++ b/app/api/currency/rate/route.ts @@ -1,6 +1,8 @@ import { NextResponse } from 'next/server' import { createClient } from '@/lib/supabase/server' import { fetchExchangeRate } from '@/lib/currency/riksbanken' +import { getActiveCompanyId } from '@/lib/company/context' +import { guardSandbox } from '@/lib/sandbox/guard' import type { Currency } from '@/types' const VALID_CURRENCIES: Currency[] = ['EUR', 'USD', 'GBP', 'NOK', 'DKK'] @@ -12,6 +14,16 @@ export async function GET(request: Request) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } + const companyId = await getActiveCompanyId(supabase, user.id) + // Refuse the request when no active company resolves rather than letting + // a session without one slip past the sandbox guard. Riksbanken's open + // API is IP rate-limited; we don't want demo traffic eating that budget. + if (!companyId) { + return NextResponse.json({ error: 'No active company' }, { status: 400 }) + } + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + const { searchParams } = new URL(request.url) const currency = searchParams.get('currency') as Currency | null const dateStr = searchParams.get('date') diff --git a/app/api/invoices/[id]/send/__tests__/route.test.ts b/app/api/invoices/[id]/send/__tests__/route.test.ts index adac2750..e84131d4 100644 --- a/app/api/invoices/[id]/send/__tests__/route.test.ts +++ b/app/api/invoices/[id]/send/__tests__/route.test.ts @@ -65,6 +65,15 @@ vi.mock('@/lib/bookkeeping/invoice-entries', () => ({ mockCreateInvoiceJournalEntry(...args), })) +// The sandbox guard issues a company_settings query at the top of the route; +// short-circuit it in tests since the queued mock-supabase is shaped for the +// route's existing fetch chain, not an extra pre-flight read. +vi.mock('@/lib/sandbox/guard', () => ({ + guardSandbox: vi.fn().mockResolvedValue(null), + isSandboxCompany: vi.fn().mockResolvedValue(false), + sandboxBlockedResponse: vi.fn(), +})) + import { POST } from '../route' describe('POST /api/invoices/[id]/send', () => { diff --git a/app/api/invoices/[id]/send/route.ts b/app/api/invoices/[id]/send/route.ts index 28b6a70f..11002936 100644 --- a/app/api/invoices/[id]/send/route.ts +++ b/app/api/invoices/[id]/send/route.ts @@ -15,6 +15,7 @@ import { uploadDocument } from '@/lib/core/documents/document-service' import { ensureInvoiceNumber } from '@/lib/invoices/ensure-invoice-number' import { withRouteContext } from '@/lib/api/with-route-context' import { errorResponseFromCode } from '@/lib/errors/get-structured-error' +import { guardSandbox } from '@/lib/sandbox/guard' import type { Invoice, InvoiceItem, Customer, CompanySettings } from '@/types' ensureInitialized() @@ -26,6 +27,11 @@ export const POST = withRouteContext( const { user, supabase, companyId, log, requestId } = ctx const opLog = log.child({ invoiceId: id }) + // The sandbox must never deliver a real email to a real customer — block + // the entire send pipeline (PDF render + Resend send + status flip). + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + const emailService = getEmailService() if (!emailService.isConfigured()) { return errorResponseFromCode('INVOICE_SEND_EMAIL_NOT_CONFIGURED', opLog, { requestId }) diff --git a/app/api/sandbox/seed/route.ts b/app/api/sandbox/seed/route.ts index cc47eef1..42d46024 100644 --- a/app/api/sandbox/seed/route.ts +++ b/app/api/sandbox/seed/route.ts @@ -1,10 +1,12 @@ import crypto from 'crypto' +import type { SupabaseClient } from '@supabase/supabase-js' import { createClient } from '@/lib/supabase/server' import { NextResponse } from 'next/server' import { getActiveCompanyId } from '@/lib/company/context' import { createLogger } from '@/lib/logger' import { checkRateLimit } from '@/lib/auth/rate-limit-http' import { truncateIp } from '@/lib/api/v1/with-api-v1' +import { ensureSandboxAgentProfile } from '@/lib/sandbox/ensure-agent' // Anonymous sign-in is enabled in all environments so visitors can try the // product; a per-/24 cap on the seed endpoint keeps a single network from @@ -80,7 +82,11 @@ export async function POST(request: Request) { companyId = newCompanyId as string } - // Idempotency: if already seeded, return early + // Idempotency: if the core seed already ran (company_settings exists), skip + // the bulk insert path. We still TOP UP the newer surfaces (agent_profile, + // suppliers, asset, pending operations) afterwards so an old sandbox session + // — created before those were added to the seed — picks them up on the next + // call instead of being stuck without a verified assistant. const { data: existing } = await supabase .from('company_settings') .select('id') @@ -88,7 +94,13 @@ export async function POST(request: Request) { .maybeSingle() if (existing) { - return NextResponse.json({ seeded: false }) + try { + await topUpSandboxAdditions(supabase, companyId) + return NextResponse.json({ seeded: false, topped_up: true }) + } catch (err) { + log.error('failed to top up sandbox additions', { error: err, userId: user.id, companyId }) + return NextResponse.json({ seeded: false, topped_up: false }) + } } try { @@ -581,6 +593,246 @@ export async function POST(request: Request) { if (dlError) throw dlError + // 13. Seed suppliers + one registered supplier invoice + one paid one. + // Supplier invoices are arguably the second-most-used surface after + // bank transactions; without them the /suppliers and /supplier-invoices + // pages render the empty state and the demo loses a big chunk of the + // accounts-payable story. + // Supplier names use the "Demo" prefix and the documentation-reserved + // 5559... org-number range so the seeded rows cannot be confused with + // production data should they ever leak into a real environment. + const { data: suppliers, error: supError } = await supabase + .from('suppliers') + .insert([ + { + user_id: userId, + company_id: companyId, + name: 'Demo Telekom AB', + supplier_type: 'swedish_business', + org_number: '5559000001', + vat_number: 'SE555900000101', + email: 'demo+telekom@example.com', + bankgiro: '5559-0001', + address_line1: 'Demovägen 10', + postal_code: '111 22', + city: 'Stockholm', + country: 'SE', + default_payment_terms: 30, + }, + { + user_id: userId, + company_id: companyId, + name: 'Demokafé AB', + supplier_type: 'swedish_business', + org_number: '5559000002', + vat_number: 'SE555900000201', + bankgiro: '5559-0002', + address_line1: 'Demovägen 11', + postal_code: '111 22', + city: 'Stockholm', + country: 'SE', + default_payment_terms: 15, + }, + ]) + .select('id, name') + + if (supError) throw supError + const supplierMap = Object.fromEntries(suppliers.map(s => [s.name, s.id])) + + // Supplier invoice #1 — Telia, paid 15 days ago (mobile + bredband, 25% VAT). + const sevenDaysFromNow = new Date(today) + sevenDaysFromNow.setDate(today.getDate() + 7) + + // Hardcode 1 and 2 — get_next_arrival_number is MAX+1 against the same + // table we're about to insert into, so calling it twice before the first + // insert lands gives the same value for both rows and violates the + // (company_id, arrival_number) unique index. The company is brand new + // here, so 1 and 2 are guaranteed to be free. + const { data: supInvoices, error: supInvError } = await supabase + .from('supplier_invoices') + .insert([ + { + user_id: userId, + company_id: companyId, + supplier_id: supplierMap['Demo Telekom AB'], + arrival_number: 1, + supplier_invoice_number: '4711-2026-03', + invoice_date: toDateStr(thirtyDaysAgo), + due_date: toDateStr(today), + received_date: toDateStr(thirtyDaysAgo), + status: 'paid', + currency: 'SEK', + subtotal: 480, + vat_amount: 120, + total: 600, + payment_reference: '47112026031', + paid_at: toDateStr(fifteenDaysAgo), + paid_amount: 600, + }, + { + user_id: userId, + company_id: companyId, + supplier_id: supplierMap['Demokafé AB'], + arrival_number: 2, + supplier_invoice_number: '88245', + invoice_date: toDateStr(fiveDaysAgo), + due_date: toDateStr(sevenDaysFromNow), + received_date: toDateStr(fiveDaysAgo), + status: 'registered', + currency: 'SEK', + subtotal: 240, + vat_amount: 28.80, + total: 268.80, + // Must be set explicitly: PostgREST normalizes columns across + // rows in a bulk insert, so omitting paid_amount here while the + // first row sets it sends null instead of falling through to the + // schema default (0), violating the NOT NULL constraint. + paid_amount: 0, + }, + ]) + .select('id, supplier_invoice_number') + + if (supInvError) throw supInvError + const supInvoiceMap = Object.fromEntries( + supInvoices.map(s => [s.supplier_invoice_number, s.id]) + ) + + // Supplier invoice line items. Note: supplier_invoice_items.vat_rate is + // stored as a decimal (0.25 = 25%); invoice_items.vat_rate above uses + // integer percent (25). Two different conventions inherited from earlier + // migrations — don't try to "fix" it here. + const { error: supItemsError } = await supabase + .from('supplier_invoice_items') + .insert([ + { + supplier_invoice_id: supInvoiceMap['4711-2026-03'], + description: 'Mobil + bredband — mars', + quantity: 1, + unit_price: 480, + line_total: 480, + vat_rate: 0.25, + vat_amount: 120, + account_number: '6212', + }, + { + supplier_invoice_id: supInvoiceMap['88245'], + description: 'Kundmöte Demokafé (representation)', + quantity: 1, + unit_price: 240, + line_total: 240, + vat_rate: 0.12, + vat_amount: 28.80, + account_number: '5810', + }, + ]) + + if (supItemsError) throw supItemsError + + // 14. Add one fully-depreciable asset (laptop) so /assets shows + // something other than a Package empty state. Acquired 18 months ago, + // 60-month linear depreciation. Cost set above the 2026 + // förbrukningsinventarier threshold (half prisbasbelopp ≈ 29 600 SEK) + // so the demo unambiguously illustrates capitalization rather than + // direct expensing. + const eighteenMonthsAgo = new Date(today) + eighteenMonthsAgo.setMonth(today.getMonth() - 18) + const { error: assetError } = await supabase + .from('assets') + .insert({ + user_id: userId, + company_id: companyId, + name: 'Demo-laptop', + category: 'computer', + acquisition_date: toDateStr(eighteenMonthsAgo), + acquisition_cost: 35000, + salvage_value: 0, + useful_life_months: 60, + depreciation_method: 'linear', + bas_asset_account: '1250', + bas_accumulated_account: '1259', + bas_expense_account: '7831', + notes: 'Demo-tillgång — visar planenlig avskrivning över 5 år.', + }) + + if (assetError) throw assetError + + // 15. Pre-built, verified agent_profile so the assistant chrome (FAB, + // /chat surface, agent identity in nav) renders without firing a + // composer run. The chat itself is server-gated by guardSandbox(). + // Delegated to ensureSandboxAgentProfile so the persona lives in one + // place (this seed, the dashboard/chat layout backfill, and the seed + // top-up path all use the same helper). + await ensureSandboxAgentProfile(supabase, companyId) + + // 16. Pre-staged pending_operations so /pending isn't empty. + // These are the kind of operation the AI agent would stage; pre-seeded + // here so the user can see the approval queue UI (preview, period + // status, risk level) without having to invoke the disabled AI. + // actor_type='agent_chat' + risk_level on the row itself is required by + // pending_operations_chat_insert (the only RLS policy that lets a + // user-scoped client INSERT into this table). + const { error: pendOpsError } = await supabase + .from('pending_operations') + .insert([ + { + user_id: userId, + company_id: companyId, + operation_type: 'create_supplier_invoice_from_inbox', + status: 'pending', + actor_type: 'agent_chat', + risk_level: 'low', + // Uses a distinct supplier_invoice_number so approving this + // pending operation creates a NEW supplier_invoices row instead + // of colliding with the Demokafé '88245' already booked above + // (BFL 5 kap — each affärshändelse must be recorded exactly once). + title: 'Registrera leverantörsfaktura — Demokafé (representation, nytt underlag)', + params: { + supplier_id: supplierMap['Demokafé AB'], + supplier_invoice_number: 'INKOMMANDE-2026-001', + invoice_date: toDateStr(fiveDaysAgo), + due_date: toDateStr(sevenDaysFromNow), + total: 268.80, + vat_amount: 28.80, + account_number: '5810', + }, + preview_data: { + // Representation @ 12% VAT (café meal), 240 SEK excl. VAT for + // a single attendee. The avdragsrätt cap is 25% × 300 SEK × + // antal_personer = 75 SEK / person (ML 8 kap. 9 §); since the + // VAT here is 28.80 SEK the full amount is deductible and the + // cost lands in 5810 — no split needed. + preview_lines: [ + { account: '5810', description: 'Representation (12% moms, ≤ 75 SEK moms/pers)', debit: 240, credit: 0 }, + { account: '2641', description: 'Ingående moms', debit: 28.80, credit: 0 }, + { account: '2440', description: 'Leverantörsskulder', debit: 0, credit: 268.80 }, + ], + }, + }, + { + user_id: userId, + company_id: companyId, + operation_type: 'categorize_transaction', + status: 'pending', + actor_type: 'agent_chat', + risk_level: 'low', + title: 'Bokför insättning — bankgiro', + params: { + account_number: '3001', + is_business: true, + vat_treatment: 'standard_25', + }, + preview_data: { + preview_lines: [ + { account: '1930', description: 'Företagskonto', debit: 1200, credit: 0 }, + { account: '2611', description: 'Utgående moms 25%', debit: 0, credit: 240 }, + { account: '3001', description: 'Försäljning 25% moms', debit: 0, credit: 960 }, + ], + }, + }, + ]) + + if (pendOpsError) throw pendOpsError + return NextResponse.json({ seeded: true }) } catch (err) { log.error('failed to seed sandbox data', { error: err, userId: user.id, companyId }) @@ -590,3 +842,17 @@ export async function POST(request: Request) { ) } } + +/** + * Idempotent top-up for sandboxes that pre-date the agent_profile addition + * to the seed. Re-running the seed on those older sandboxes short-circuits + * at the company_settings idempotency check above, so they never get the + * agent_profile without this hook. Delegates to ensureSandboxAgentProfile + * so the profile data stays in exactly one place. + */ +async function topUpSandboxAdditions( + supabase: SupabaseClient, + companyId: string, +): Promise { + await ensureSandboxAgentProfile(supabase, companyId) +} diff --git a/app/api/transactions/[id]/refresh-exchange-rate/route.ts b/app/api/transactions/[id]/refresh-exchange-rate/route.ts index b685752a..d61d3e5a 100644 --- a/app/api/transactions/[id]/refresh-exchange-rate/route.ts +++ b/app/api/transactions/[id]/refresh-exchange-rate/route.ts @@ -2,6 +2,7 @@ import { NextResponse } from 'next/server' import { withRouteContext } from '@/lib/api/with-route-context' import { errorResponse, errorResponseFromCode } from '@/lib/errors/get-structured-error' import { fetchExchangeRate } from '@/lib/currency/riksbanken' +import { guardSandbox } from '@/lib/sandbox/guard' import type { Currency, Transaction } from '@/types' export const POST = withRouteContext( @@ -10,6 +11,9 @@ export const POST = withRouteContext( const { id } = await params const { supabase, companyId, log, requestId } = ctx + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + const { data: transaction, error: fetchError } = await supabase .from('transactions') .select('*') diff --git a/app/api/v1/companies/[companyId]/invoices/[id]/send/__tests__/route.test.ts b/app/api/v1/companies/[companyId]/invoices/[id]/send/__tests__/route.test.ts index 364d0013..d3c7857b 100644 --- a/app/api/v1/companies/[companyId]/invoices/[id]/send/__tests__/route.test.ts +++ b/app/api/v1/companies/[companyId]/invoices/[id]/send/__tests__/route.test.ts @@ -73,6 +73,15 @@ vi.mock('@/lib/invoices/pdf-template', () => ({ InvoicePDF: vi.fn().mockReturnValue({}), brandingFromCompanySettings: vi.fn().mockReturnValue({}), })) + +// The sandbox guard reads company_settings.is_sandbox at the top of the +// route; the per-table mock supabase below has no row for that lookup so +// short-circuit the guard in tests. +vi.mock('@/lib/sandbox/guard', () => ({ + guardSandbox: vi.fn().mockResolvedValue(null), + isSandboxCompany: vi.fn().mockResolvedValue(false), + sandboxBlockedResponse: vi.fn(), +})) import { InvoicePDF } from '@/lib/invoices/pdf-template' import { validateApiKey, createServiceClientNoCookies } from '@/lib/auth/api-keys' diff --git a/app/api/v1/companies/[companyId]/invoices/[id]/send/route.ts b/app/api/v1/companies/[companyId]/invoices/[id]/send/route.ts index eb58fa4b..536e11bd 100644 --- a/app/api/v1/companies/[companyId]/invoices/[id]/send/route.ts +++ b/app/api/v1/companies/[companyId]/invoices/[id]/send/route.ts @@ -54,6 +54,7 @@ import { createInvoiceJournalEntry } from '@/lib/bookkeeping/invoice-entries' import { uploadDocument } from '@/lib/core/documents/document-service' import { ensureInvoiceNumber } from '@/lib/invoices/ensure-invoice-number' import { eventBus } from '@/lib/events' +import { guardSandbox } from '@/lib/sandbox/guard' import type { CompanySettings, Customer, EntityType, Invoice, InvoiceItem } from '@/types' const INVOICE_SEND_RESPONSE_COLUMNS = @@ -136,6 +137,11 @@ export const POST = withApiV1<{ params: Promise<{ companyId: string; id: string }) } + // Sandbox demo never sends a real email — guard the whole pipeline + // before any number is allocated or PDF is rendered. + const blocked = await guardSandbox(ctx.supabase, ctx.companyId!) + if (blocked) return blocked + // Step 1: email service configured? const emailService = getEmailService() if (!emailService.isConfigured()) { diff --git a/app/api/vat/validate/route.ts b/app/api/vat/validate/route.ts index 82d87a8d..6e3e323d 100644 --- a/app/api/vat/validate/route.ts +++ b/app/api/vat/validate/route.ts @@ -4,6 +4,7 @@ import { validateBody } from '@/lib/api/validate' import { ValidateVatNumberSchema } from '@/lib/api/schemas' import { validateVatNumber } from '@/lib/vat/vies-client' import { requireCompanyId } from '@/lib/company/context' +import { guardSandbox } from '@/lib/sandbox/guard' export async function POST(request: Request) { const supabase = await createClient() @@ -16,6 +17,11 @@ export async function POST(request: Request) { const companyId = await requireCompanyId(supabase, user.id) + // VIES is a live external call to the EU Commission — block in the sandbox + // so the demo can't generate background traffic against it. + const blocked = await guardSandbox(supabase, companyId) + if (blocked) return blocked + const result = await validateBody(request, ValidateVatNumberSchema) if (!result.success) return result.response const { vat_number, customer_id } = result.data diff --git a/app/companies/new/page.tsx b/app/companies/new/page.tsx index faf27bba..d17b96db 100644 --- a/app/companies/new/page.tsx +++ b/app/companies/new/page.tsx @@ -3,7 +3,6 @@ import { useState, useEffect, Suspense } from 'react' import { useRouter } from 'next/navigation' import { useTranslations } from 'next-intl' -import Image from 'next/image' import Link from 'next/link' import { createClient } from '@/lib/supabase/client' import { createCompanyFromOnboarding } from '@/lib/company/actions' @@ -238,14 +237,9 @@ function NewCompanyContent() { > - {branding.appName} - {branding.appName.toLowerCase()} + + {branding.appName.toLowerCase()} +
{STEP_INFO.map((_, i) => { diff --git a/app/docs/api/changelog/page.tsx b/app/docs/api/changelog/page.tsx index 9510c14a..cbffd740 100644 --- a/app/docs/api/changelog/page.tsx +++ b/app/docs/api/changelog/page.tsx @@ -4,8 +4,8 @@ import { DocsMarkdown } from '@/lib/docs/markdown' import { CHANGELOG_MD } from '@/lib/docs/content/changelog' export const metadata: Metadata = { - title: 'Changelog · gnubok API', - description: 'Reverse-chronological release notes for the gnubok REST API.', + title: 'Changelog · accounted API', + description: 'Reverse-chronological release notes for the accounted REST API.', } export default function DocsApiChangelogPage() { diff --git a/app/docs/api/cookbook/[slug]/page.tsx b/app/docs/api/cookbook/[slug]/page.tsx index cf07cad9..a400a7d9 100644 --- a/app/docs/api/cookbook/[slug]/page.tsx +++ b/app/docs/api/cookbook/[slug]/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str const entry = findRecipe(slug) if (!entry) return { title: 'Not found' } return { - title: `${entry.title} · gnubok API cookbook`, + title: `${entry.title} · accounted API cookbook`, description: entry.description, } } diff --git a/app/docs/api/errors/page.tsx b/app/docs/api/errors/page.tsx index 31e0061c..d253e0e2 100644 --- a/app/docs/api/errors/page.tsx +++ b/app/docs/api/errors/page.tsx @@ -4,8 +4,8 @@ import { DocsMarkdown } from '@/lib/docs/markdown' import { buildErrorReferenceMd } from '@/lib/docs/content/errors' export const metadata: Metadata = { - title: 'Errors · gnubok API', - description: 'Every stable error code returned by the gnubok REST API, with HTTP status, description, and remediation.', + title: 'Errors · accounted API', + description: 'Every stable error code returned by the accounted REST API, with HTTP status, description, and remediation.', } export default function DocsApiErrorsPage() { diff --git a/app/docs/api/page.tsx b/app/docs/api/page.tsx index c6d9ac1b..647c12e8 100644 --- a/app/docs/api/page.tsx +++ b/app/docs/api/page.tsx @@ -6,7 +6,7 @@ import { LANDING_MD } from '@/lib/docs/content/landing' import Link from 'next/link' export const metadata: Metadata = { - title: 'gnubok API · Documentation', + title: 'accounted API · Documentation', description: 'Swedish double-entry bookkeeping as a public REST API for agents and integrations.', } diff --git a/app/docs/api/reference/[slug]/page.tsx b/app/docs/api/reference/[slug]/page.tsx index d9af6baa..0b835393 100644 --- a/app/docs/api/reference/[slug]/page.tsx +++ b/app/docs/api/reference/[slug]/page.tsx @@ -13,7 +13,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str const page = buildResourcePages().find((p) => p.slug === slug) if (!page) return { title: 'Not found' } return { - title: `${page.label} · gnubok API`, + title: `${page.label} · accounted API`, description: page.description, } } diff --git a/app/docs/api/reference/page.tsx b/app/docs/api/reference/page.tsx index 54ab6297..013ec82f 100644 --- a/app/docs/api/reference/page.tsx +++ b/app/docs/api/reference/page.tsx @@ -4,8 +4,8 @@ import { DocsMarkdown } from '@/lib/docs/markdown' import { buildReferenceOverviewMd } from '@/lib/docs/content/reference' export const metadata: Metadata = { - title: 'API reference · gnubok API', - description: 'Every endpoint exposed by the gnubok REST API, grouped by resource.', + title: 'API reference · accounted API', + description: 'Every endpoint exposed by the accounted REST API, grouped by resource.', } export default function DocsApiReferencePage() { diff --git a/app/docs/api/versioning/page.tsx b/app/docs/api/versioning/page.tsx index 618f383d..bf5680b2 100644 --- a/app/docs/api/versioning/page.tsx +++ b/app/docs/api/versioning/page.tsx @@ -4,7 +4,7 @@ import { DocsMarkdown } from '@/lib/docs/markdown' import { VERSIONING_MD } from '@/lib/docs/content/versioning' export const metadata: Metadata = { - title: 'Versioning · gnubok API', + title: 'Versioning · accounted API', description: 'How API versions are pinned, upgraded, and deprecated. Plus idempotency, dry-run, and strict-mode write semantics.', } diff --git a/app/docs/api/webhooks/page.tsx b/app/docs/api/webhooks/page.tsx index 7ec047bd..29fa6a8e 100644 --- a/app/docs/api/webhooks/page.tsx +++ b/app/docs/api/webhooks/page.tsx @@ -4,8 +4,8 @@ import { DocsMarkdown } from '@/lib/docs/markdown' import { WEBHOOKS_MD } from '@/lib/docs/content/webhooks' export const metadata: Metadata = { - title: 'Webhooks · gnubok API', - description: 'Receive HMAC-signed POST notifications when state changes in gnubok. Includes signature verification samples in Node.js and Python.', + title: 'Webhooks · accounted API', + description: 'Receive HMAC-signed POST notifications when state changes in accounted. Includes signature verification samples in Node.js and Python.', } export default function DocsApiWebhooksPage() { diff --git a/app/favicon.ico b/app/favicon.ico deleted file mode 100644 index 2e6728b32d9156e8f204ecd57cfeddc78edd0a59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 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 ax6;5E?)|_T&i$5pJ?Nj$KPB*+CGg*>+?3D& diff --git a/app/icon.png b/app/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d6702e4e80619ac77afe6a0395609402ec1e624c GIT binary patch literal 97318 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 z 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 literal 0 HcmV?d00001 diff --git a/app/invite/[token]/page.tsx b/app/invite/[token]/page.tsx index 0fff66ec..eed5b761 100644 --- a/app/invite/[token]/page.tsx +++ b/app/invite/[token]/page.tsx @@ -3,7 +3,6 @@ import { useState, useEffect } from 'react' import { useParams, useRouter } from 'next/navigation' import { useTranslations } from 'next-intl' -import Image from 'next/image' import Link from 'next/link' import { Button } from '@/components/ui/button' import { Card } from '@/components/ui/card' @@ -168,14 +167,9 @@ export default function InvitePage() {
- {branding.appName} - {branding.appName.toLowerCase()} + + {branding.appName.toLowerCase()} +

diff --git a/app/layout.tsx b/app/layout.tsx index 650bb18c..159e8a52 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -29,6 +29,9 @@ const hedvigSerif = Hedvig_Letters_Serif({ variable: "--font-hedvig-serif", subsets: ["latin"], display: "swap", + // Hedvig Letters Serif on Google Fonts only ships 400; the brand wordmark + // requests 700, which browsers synthesize from this file. Keep the load + // single-file to stay within the existing display-font budget. weight: "400", }); diff --git a/app/sandbox/page.tsx b/app/sandbox/page.tsx index cb5b9024..5af5160e 100644 --- a/app/sandbox/page.tsx +++ b/app/sandbox/page.tsx @@ -3,12 +3,12 @@ import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import Link from 'next/link' -import Image from 'next/image' import { createClient } from '@/lib/supabase/client' import { Button } from '@/components/ui/button' import { useToast } from '@/components/ui/use-toast' -import { Loader2, Receipt, ArrowLeftRight, BookOpen, BarChart3 } from 'lucide-react' +import { Loader2 } from 'lucide-react' import { getBranding } from '@/lib/branding/service' +import { BrandWordmark } from '@/components/branding/BrandWordmark' const branding = getBranding() @@ -81,14 +81,7 @@ export default function SandboxPage() {
- {branding.appName} +
@@ -116,14 +109,7 @@ export default function SandboxPage() {
- {branding.appName} +

Testa {branding.appName.toLowerCase()} utan att registrera dig

@@ -133,23 +119,11 @@ export default function SandboxPage() {
- {/* Feature highlights */} -
- {[ - { icon: Receipt, label: 'Fakturor' }, - { icon: ArrowLeftRight, label: 'Transaktioner' }, - { icon: BookOpen, label: 'Bokföring' }, - { icon: BarChart3, label: 'Rapporter' }, - ].map(({ icon: Icon, label }) => ( -
- - {label} -
- ))} -
+

+ AI-assistenten och externa tjänster (e-post, bankuppkoppling, + valutakurser, Skatteverket) är avstängda i sandlådan — de + kräver ett riktigt konto. +

), )} diff --git a/components/agent/AgentSheet.tsx b/components/agent/AgentSheet.tsx index d9b9f69c..6c8da3b8 100644 --- a/components/agent/AgentSheet.tsx +++ b/components/agent/AgentSheet.tsx @@ -5,7 +5,9 @@ import { X, Expand } from 'lucide-react' import Link from 'next/link' import AgentChat from './AgentChat' import AgentAvatar from './AgentAvatar' +import SandboxAgentPreview from './SandboxAgentPreview' import { useAgentSheet } from './AgentSheetProvider' +import { useCompanyOptional } from '@/contexts/CompanyContext' // Undimmed non-modal side sheet — sits above the page on a hairline border + // shadow, but the page underneath stays fully interactive. Plan §3b. @@ -31,6 +33,8 @@ export default function AgentSheet({ }: Props) { const [conversationId, setConversationId] = useState(null) const { identity } = useAgentSheet() + const companyCtx = useCompanyOptional() + const isSandbox = companyCtx?.isSandbox ?? false const agentName = identity.displayName?.trim() || null const sheetTitle = intentToTitle(intentId, agentName) @@ -60,7 +64,7 @@ export default function AgentSheet({

{sheetTitle}

- {conversationId && ( + {conversationId && !isSandbox && ( - setConversationId(id)} - /> + {isSandbox ? ( + + ) : ( + setConversationId(id)} + /> + )}
) } diff --git a/components/agent/ChatConversationView.tsx b/components/agent/ChatConversationView.tsx index 6338ceba..c84b67f5 100644 --- a/components/agent/ChatConversationView.tsx +++ b/components/agent/ChatConversationView.tsx @@ -5,7 +5,9 @@ import Link from 'next/link' import { ArrowLeft } from 'lucide-react' import AgentChat, { normalizeStoredMessages } from './AgentChat' import AgentAvatar from './AgentAvatar' +import SandboxAgentPreview from './SandboxAgentPreview' import { useAgentSheet } from './AgentSheetProvider' +import { useCompanyOptional } from '@/contexts/CompanyContext' interface Props { conversationId: string @@ -26,6 +28,9 @@ export default function ChatConversationView({ }: Props) { const initialMessages = useMemo(() => normalizeStoredMessages(rawMessages), [rawMessages]) const { identity } = useAgentSheet() + const companyCtx = useCompanyOptional() + const isSandbox = companyCtx?.isSandbox ?? false + const agentName = identity.displayName?.trim() || null return ( <> @@ -52,14 +57,18 @@ export default function ChatConversationView({
-
- +
+ {isSandbox ? ( + + ) : ( + + )}
) diff --git a/components/agent/ChatEmptyState.tsx b/components/agent/ChatEmptyState.tsx index 4594baa0..5918ad69 100644 --- a/components/agent/ChatEmptyState.tsx +++ b/components/agent/ChatEmptyState.tsx @@ -1,10 +1,13 @@ 'use client' -import { ArrowUpRight } from 'lucide-react' +import { ArrowUpRight, Sparkles } from 'lucide-react' import Link from 'next/link' +import { useRouter } from 'next/navigation' import { Button } from '@/components/ui/button' import { useAgentSheet } from './AgentSheetProvider' import AgentAvatar from './AgentAvatar' +import { useCompanyOptional } from '@/contexts/CompanyContext' +import { createClient } from '@/lib/supabase/client' // Tiny client component for /chat empty state. Reads the agent identity from // the provider so it can show the user's chosen avatar + name above the @@ -31,8 +34,46 @@ const SUGGESTIONS: { label: string; prompt: string }[] = [ export default function ChatEmptyState() { const { identity } = useAgentSheet() + const companyCtx = useCompanyOptional() + const router = useRouter() + const isSandbox = companyCtx?.isSandbox ?? false const name = identity.displayName?.trim() || 'din assistent' + if (isSandbox) { + const handleCreateAccount = async () => { + const supabase = createClient() + // Sign-out is best-effort — navigate even if Supabase is unreachable + // so the button never looks dead. + try { + await supabase.auth.signOut() + } catch { + // Intentionally swallowed. + } + router.push('/register') + } + return ( +
+ +

Fråga {name}

+
+
+ + Avstängd i sandlådan +
+

+ AI-assistenten använder en betald molntjänst och är därför + inaktiverad här. I den fullständiga produkten kan {name} kategorisera + transaktioner, granska leverantörsfakturor och svara på frågor om + din bokföring. +

+
+ +
+ ) + } + // Hidden on mobile — the sidebar IS the page when no conversation is open. // On desktop, fills the right pane with a centered prompt. return ( diff --git a/components/agent/ChatIntakeStarter.tsx b/components/agent/ChatIntakeStarter.tsx index d8050bfe..75151e3a 100644 --- a/components/agent/ChatIntakeStarter.tsx +++ b/components/agent/ChatIntakeStarter.tsx @@ -4,7 +4,9 @@ import { useRouter } from 'next/navigation' import { useState } from 'react' import AgentChat from './AgentChat' import AgentAvatar from './AgentAvatar' +import SandboxAgentPreview from './SandboxAgentPreview' import { useAgentSheet } from './AgentSheetProvider' +import { useCompanyOptional } from '@/contexts/CompanyContext' // Phase C entry surface. Lands here from ReviewCard's "kör" after Phase B // verify succeeds. Renders AgentChat in fresh-start mode — no @@ -17,6 +19,8 @@ import { useAgentSheet } from './AgentSheetProvider' export default function ChatIntakeStarter() { const router = useRouter() const { identity } = useAgentSheet() + const companyCtx = useCompanyOptional() + const isSandbox = companyCtx?.isSandbox ?? false const agentName = identity.displayName?.trim() || 'Din assistent' // Lock the swap to the first id we see — defensive guard against the // AgentChat callback firing twice during React 19 Strict Mode reruns. @@ -29,28 +33,34 @@ export default function ChatIntakeStarter() {

{agentName} är redo

- Några frågor för att lära känna din verksamhet — svara i din egen takt, du kan avsluta när du vill. + {isSandbox + ? 'Förhandsvisning — den verkliga konversationen kräver ett konto.' + : 'Några frågor för att lära känna din verksamhet — svara i din egen takt, du kan avsluta när du vill.'}

-
- { - // Wait for the greeting to finish streaming AND persist before - // swapping the URL. Swapping on the early `conversation` event - // unmounts AgentChat mid-stream, so the greeting is never saved - // and /chat/[id] hydrates empty — the bug where the chat lands - // blank and only shows the intro on a later visit. - if (swapped) return - setSwapped(true) - router.replace(`/chat/${id}`) - }} - scrollerClassName="px-6 py-8" - /> +
+ {isSandbox ? ( + + ) : ( + { + // Wait for the greeting to finish streaming AND persist before + // swapping the URL. Swapping on the early `conversation` event + // unmounts AgentChat mid-stream, so the greeting is never saved + // and /chat/[id] hydrates empty — the bug where the chat lands + // blank and only shows the intro on a later visit. + if (swapped) return + setSwapped(true) + router.replace(`/chat/${id}`) + }} + scrollerClassName="px-6 py-8" + /> + )}
) diff --git a/components/agent/ChatNewStarter.tsx b/components/agent/ChatNewStarter.tsx index 739ee656..7d598fb4 100644 --- a/components/agent/ChatNewStarter.tsx +++ b/components/agent/ChatNewStarter.tsx @@ -4,7 +4,9 @@ import { useRouter } from 'next/navigation' import { useState } from 'react' import AgentChat from './AgentChat' import AgentAvatar from './AgentAvatar' +import SandboxAgentPreview from './SandboxAgentPreview' import { useAgentSheet } from './AgentSheetProvider' +import { useCompanyOptional } from '@/contexts/CompanyContext' // Inline starter used by suggestion chips and ⌘K. Mirrors ChatIntakeStarter // but accepts any intent + seed so we don't fork the intake-specific @@ -19,6 +21,8 @@ export default function ChatNewStarter({ }) { const router = useRouter() const { identity } = useAgentSheet() + const companyCtx = useCompanyOptional() + const isSandbox = companyCtx?.isSandbox ?? false const agentName = identity.displayName?.trim() || 'Din assistent' const [swapped, setSwapped] = useState(false) @@ -28,26 +32,32 @@ export default function ChatNewStarter({

{agentName}

-

Ny konversation

+

+ {isSandbox ? 'Förhandsvisning — avstängd i sandlådan' : 'Ny konversation'} +

-
- { - // Wait for the first turn to finish before swapping the URL — - // otherwise the unmount aborts the in-flight stream and - // /chat/[id] hydrates with only the user message. - if (swapped) return - setSwapped(true) - router.replace(`/chat/${id}`) - }} - scrollerClassName="px-6 py-8" - /> +
+ {isSandbox ? ( + + ) : ( + { + // Wait for the first turn to finish before swapping the URL — + // otherwise the unmount aborts the in-flight stream and + // /chat/[id] hydrates with only the user message. + if (swapped) return + setSwapped(true) + router.replace(`/chat/${id}`) + }} + scrollerClassName="px-6 py-8" + /> + )}
) diff --git a/components/agent/SandboxAgentPreview.tsx b/components/agent/SandboxAgentPreview.tsx new file mode 100644 index 00000000..1bf8e6f5 --- /dev/null +++ b/components/agent/SandboxAgentPreview.tsx @@ -0,0 +1,111 @@ +'use client' + +import Link from 'next/link' +import { useRouter } from 'next/navigation' +import { Sparkles, ArrowRight } from 'lucide-react' +import { createClient } from '@/lib/supabase/client' +import { Button } from '@/components/ui/button' + +/** + * Stand-in for AgentChat in the sandbox. The real chat surface POSTs to + * /api/agent/invoke which is server-gated by guardSandbox(), so the input + * would just produce a 403. Instead of showing that as a raw error, we + * render a brief description of what the assistant does in prod and a + * single "Skapa konto" CTA. Same chrome (header) as the real chat — only + * the body swaps out. + * + * Mirrors the look of the empty-state but with an explanation block so the + * sandbox user understands what they're seeing without typing into a + * dead-end input. + */ +export default function SandboxAgentPreview({ + agentName, +}: { + agentName: string | null +}) { + const router = useRouter() + const name = agentName?.trim() || 'din assistent' + + async function handleCreateAccount() { + const supabase = createClient() + // Sign-out is best-effort — a transient Supabase failure shouldn't + // strand the user on a dead button; navigate to /register either way + // and let the registration flow re-init auth state. + try { + await supabase.auth.signOut() + } catch { + // Intentionally swallowed — see comment above. + } + router.push('/register') + } + + return ( +
+
+
+
+
+ + Förhandsvisning i sandlådan +
+

+ {name} är en specialiserad bokföringsassistent som kan + kategorisera transaktioner, granska leverantörsfakturor och + svara på frågor om din bokföring — kalibrerad mot dina + kontoplaner, verksamhet och svensk skattelagstiftning. +

+

+ I sandlådan är AI-funktionerna avstängda eftersom de använder + externa AI-tjänster som kostar pengar att köra. Skapa ett + konto för att aktivera assistenten på riktigt. +

+
+ +
    +
  • + · + + Föreslår bokföring{' '} + för oklassificerade transaktioner — du godkänner i ett klick. + +
  • +
  • + · + + Förklarar momsrutor, + årets resultat och vad som driver KPI:erna. + +
  • +
  • + · + + Granskar verifikat{' '} + och föreslår rättningar enligt BFL och K2. + +
  • +
+
+
+ +
+
+ +
+

+ Sandlådedata raderas efter 24 timmar.{' '} + + Skapa konto + + . +

+
+
+ ) +} diff --git a/components/branding/BrandWordmark.tsx b/components/branding/BrandWordmark.tsx new file mode 100644 index 00000000..539e4f28 --- /dev/null +++ b/components/branding/BrandWordmark.tsx @@ -0,0 +1,45 @@ +import { cn } from '@/lib/utils' +import { getBranding } from '@/lib/branding/service' + +interface BrandWordmarkProps { + /** + * Visual size. `'hero'` is for landing/auth/onboarding hero slots (~the + * same vertical weight as the old 240px logo image). `'inline'` matches + * the old 30px image used in top-left nav contexts. + */ + size?: 'hero' | 'inline' + /** + * Force lowercase rendering. Defaults to true to match the existing + * font-display + `.toLowerCase()` pattern used elsewhere in the app. + */ + lowercase?: boolean + className?: string +} + +/** + * Text-only wordmark used in place of the legacy logo image on auth / + * onboarding / sandbox / invite surfaces. Renders the active brand's + * `appName` in Hedvig Letters Serif at weight 700 — the display font is + * single-weight on Google Fonts so 700 ends up synthetically bolded, but + * that matches the requested aesthetic. + */ +export function BrandWordmark({ + size = 'hero', + lowercase = true, + className, +}: BrandWordmarkProps) { + const branding = getBranding() + const name = lowercase ? branding.appName.toLowerCase() : branding.appName + return ( + + {name} + + ) +} diff --git a/components/dashboard/DashboardContent.tsx b/components/dashboard/DashboardContent.tsx index 1346108d..2807a966 100644 --- a/components/dashboard/DashboardContent.tsx +++ b/components/dashboard/DashboardContent.tsx @@ -59,7 +59,18 @@ export default function DashboardContent({ companyId, summary, onboardingProgres const [showAllAlerts, setShowAllAlerts] = useState(false) const t = useTranslations('dashboard') - const needsSetup = onboardingProgress && !onboardingProgress.hasBankConnected && !onboardingProgress.hasSIEImport + // The setup gate exists to nudge brand-new users into a data-import step + // before they hit the dashboard. Once the assistant is built we treat the + // user as past that phase — they've already committed to using the tool — + // and let the dashboard render normally. This also keeps the sandbox + // (which ships with a pre-built assistant + seeded data but no bank + // connection / SIE import) from showing a checklist that re-links to + // /onboarding/agent. + const needsSetup = + !agentBuilt && + onboardingProgress && + !onboardingProgress.hasBankConnected && + !onboardingProgress.hasSIEImport const [setupGateActive, setSetupGateActive] = useState(!!needsSetup) useEffect(() => { @@ -82,7 +93,10 @@ export default function DashboardContent({ companyId, summary, onboardingProgres if (setupGateActive) { return ( { localStorage.setItem(setupFreshStartKey(companyId), 'true') setSetupGateActive(false) diff --git a/components/dashboard/SandboxBanner.tsx b/components/dashboard/SandboxBanner.tsx index 016f1f56..f8d828c0 100644 --- a/components/dashboard/SandboxBanner.tsx +++ b/components/dashboard/SandboxBanner.tsx @@ -20,7 +20,7 @@ export function SandboxBanner() { return (
- Sandlådemiljö — data raderas efter 24h + Sandlådemiljö — AI och externa tjänster är avstängda. Data raderas efter 24h.