# Threema UX rework + QR code ## Files ``` src/lib/threema-gateway-config.ts # NEW — single source of truth for gateway ID + QR path src/components/channel-users/threema-setup.tsx # NEW — QR + 3-step instructions component src/components/channel-users/channel-users.tsx # MODIFIED — renders for the threema channel deploy/patch-i18n-threema.mjs # REPLACES earlier version — customer-friendly texts in 4 langs public/threema/qr_code_AIAGENT.png # NEW — the QR you uploaded ``` ## What changed (UX, customer-facing) 1. **Package description / instructions / disclaimer.** No mention of "Gateway account", "Gateway credentials", or anything about asterisks. The disclaimer now explicitly says messages are end-to-end encrypted only up to PieCed's messaging service (where they get decrypted to route to the assistant) — accurate, not overclaiming. Crucially it also says **Threema charges per message** so customers know that sending/receiving on this channel has a cost separate from their PieCed subscription. 2. **Threema ID help text.** Now tells the customer to add **their own** ID, with explicit instructions for finding it in the Threema app (Settings → My Threema ID). Drops the asterisk / Gateway-prefix explanation entirely. 3. **QR code component (NEW).** Shown above the help text in the channel-users panel when the threema channel is enabled. Three-step flow: open Threema, scan, add your own ID below. 4. **All four languages** (en/de/fr/it) updated consistently. ## What changed (technical) - Gateway constants centralised in `src/lib/threema-gateway-config.ts`. Today hardcoded to `*AIAGENT` + `/threema/qr_code_AIAGENT.png`. When you need multiple gateway accounts, edit that one file (and the inline TODO block tells the next person how). - The component uses Next.js `` — automatic optimisation, lazy-loaded by default (no `priority`). - The PNG goes in `public/threema/`, served as a static asset under `/threema/qr_code_AIAGENT.png` — no API route, no auth wrapper, the QR encodes a Threema invitation anyone can scan anyway. ## Apply ```bash cd /path/to/pieced-portal # Drop in new files (overwrites prior channel-users.tsx and i18n script) cp -r /* . # Quick TS check (the new component uses next/image — should be fine) npx tsc --noEmit # Patch the message files node deploy/patch-i18n-threema.mjs # Should print 4 lines, one per language # Commit + push git add -A git status # eyeball the changes git commit -m "Threema: customer-friendly texts + QR setup component" git push ``` ## Verify after redeploy 1. Open the portal as a customer admin, pick the test tenant. 2. Disable + re-enable Threema in the package list (or just look at the channel-users panel — the QR shows there regardless). 3. Authorized Users → threema section should show: - QR code on the left - "AIAGENT" label under the QR (no asterisk) - 3-step instruction list - Help text below: "Enter your own Threema ID..." - Existing user pills + Add input Scan the QR with your phone — it should prompt to add `*AIAGENT` as a contact in Threema with trust level "verified by the operator" (the QR encodes the contact's public key). ## Billing log query (re-run after sending a few messages) ```bash POD=$(kubectl -n threema-gateway get pods -l 'cnpg.io/cluster=pieced-threema-gateway-db,role=primary' -o jsonpath='{.items[0].metadata.name}') DBPASS=$(kubectl -n threema-gateway get secret pieced-threema-gateway-db-app -o jsonpath='{.data.password}' | base64 -d) # Per-tenant in/out counts kubectl -n threema-gateway exec $POD -- env PGPASSWORD="$DBPASS" \ psql -U relay -d relay -c \ "SELECT tenant_name, direction, count(*), max(created_at) FROM messages GROUP BY tenant_name, direction ORDER BY tenant_name, direction;" ``` That's your billing source — count(*) × Threema's per-message rate × direction-specific multiplier = customer charge. ## Future: dynamic gateway accounts Today's hardcoded `*AIAGENT` works for one shared gateway. When you move to per-tenant gateway accounts (Threema's bigger plans, or to isolate billing per tenant): 1. Update `src/lib/threema-gateway-config.ts`: - Make the constants a lookup keyed by tenant - Or fetch from `/api/tenants//threema` (new admin route) 2. Update `threema-setup.tsx` to accept gateway info as props 3. Update the parent `channel-users.tsx` to pass tenant-specific values 4. Replace the static PNG with a server route that generates per-tenant QR codes from each gateway's `id` + `publicKey` The single config file means this refactor is contained — every consumer reads from one place, so once that one place returns the right values, everything else falls in line.