# Placeful 2.5.0

## Highlights

- **Supplier-document reconciliation** — scan bolla and fatture by phone or upload, AI-assisted data extraction (multi-page sessions, FatturaPA XML), and a three-way match queue that ties each supplier invoice to its delivery note and bank movement. PSD2 bank feeds via GoCardless/Enable Banking keep transactions in sync.
- **Voucher sales & redemption** — sell balance vouchers on promo codes, track purchases, and let guests redeem them at checkout with remainder collection. Legacy codes re-mint to the stronger 12-character space on next save.
- **Assistant everywhere** — the AI assistant gains 23 read tools and 20 staged write tools spanning orders, staff ops, door queue, marketing and reconciliation; every write is previewed and confirmed before it lands.

## Security

- **Full-codebase security audit** — every staff and guest surface was re-audited: cross-tenant reads are pinned to the mounted company, server-owned Livewire props are locked against tampering, and privileged actions re-authorize on every request.
- **Credential & token hygiene** — API tokens carry scoped abilities and expire on a configurable TTL; widget claim links bind to the browser that started them; social sign-in passes the two-factor challenge; password-reset URLs are disallowed in robots.txt so a leaked link is never crawled.
- **Data-protection depth** — erasure and access requests require a verified mailbox before running, demo personas can never mint sessions or API tokens, and exports land on a private disk with 7-day retention instead of public URLs.
- **Safer integrations** — outbound webhooks sign payloads and re-validate endpoints against SSRF on every delivery, and Google Calendar teardown skips remote deletes when the connection is already gone instead of erroring per mirror.

## Operations

- **Webhook platform** — outbound signed webhooks with HMAC verification, per-secret rotation, replay, and a delivery log; endpoints are SSRF-validated at registration and re-checked at every delivery.
- **Kitchen printing** — ESC/POS over a local print bridge or the browser, per-station routing, job leases with an autonomous reaper, and print-job retention.

## WhatsApp & messaging

- **WhatsApp outbound** — Meta-approved template sends for booking confirmations, reminders and reconfirmation links, a campaign leg with per-recipient delivery state, and an inbox that groups threads by counterparty with consent-safe staff replies (STOP always wins).
- **Consent receipts** — every channel grant/revoke writes an append-only receipt; START opens the channel only — marketing needs an explicit opt-in (guest editor toggle or the booking-form checkbox). Message bodies and payloads are scrubbed past the retention horizon.

## Widgets & embedding

- **Unified embed builder** — one settings surface generates script, button and iframe embeds for every widget: booking calendar, gift vouchers, private-event inquiries and email capture. Per-widget styling and audience filters stay, now behind a single mode picker.
- **Every widget rides the secure pipeline** — inquiry and capture embeds now mint the same short-lived, origin-bound session as the booking calendar and render inside `/embed`, with locale, UTM attribution and live kill-switch checks on every render.
- **Per-mode kill switches** — switch off any single widget surface from settings and every embed, snippet, direct URL and bare public page refuses it instantly, without touching the others.
- **Direct forms go allowlist-bound** — `/capture/{company}` and `/inquiry/{company}` stay publicly reachable, but once allowed domains are configured they can only be framed by those sites (frame-ancestors), closing the clickjacking gap on lead and signup forms. The `/embed` iframe itself is now bound to the validated host too, and the stable `/w/{key}` URL shows a readable "Widget unavailable" page instead of raw JSON when a plan, domain or kill switch refuses it.
- **Cross-company widget isolation** — a signed-in user of another company renders a public widget as an ordinary visitor (no staff powers, company context never switches); the validated embed origin is re-checked against a timestamped marker that stays fresh for six idle hours while the iframe token still expires after 15 minutes; and `php artisan widget:allowlist-audit` reports active widget-enabled integrations with an empty allowed-domains list before rollout.

## Privacy & data

- **Erasure & export coverage** — aggregator inbounds, supplier document lines, and kitchen-print rows join the company export archive and anonymization graphs.
- **Audit hardening** — bank account and match-state mutations, plus promo redemption decisions, are now audited with the actor stamped.


---
> Source: https://placeful-app.com/en/changelog/2.5.0
