- Accounting nav section + relocate Tax report out of CRM
- Accounting settings tab (km / per-diem rate, require-proof)
- add a Banana "Income & Expense" (cash-book) export format
- backend rework - incoming invoices vs internal expenses (stage 2)
- bill editor VAT dropdown + GET returns vat_code snapshot
- clearer tax-export window + gate journal export on accounting flag
- consolidate VAT/financial config into Settings → Accounting
2.7.0 (2026-07-08)
Features
- accounting: Accounting nav section + relocate Tax report out of CRM (30c0007)
- accounting: Accounting settings tab (km / per-diem rate, require-proof) (2b7495e)
- accounting: add a Banana "Income & Expense" (cash-book) export format (445d6d7)
- accounting: backend rework - incoming invoices vs internal expenses (stage 2) (5e78fb6)
- accounting: bill editor VAT dropdown + GET returns vat_code snapshot (2479d87)
- accounting: clearer tax-export window + gate journal export on accounting flag (3edd832)
- accounting: consolidate VAT/financial config into Settings → Accounting (dc7b87b)
- accounting: data-driven revenue-rate VAT map (multi-country) (873be91)
- accounting: event booking via dropdown (Company or an event) (81af445)
- accounting: expense invoiced/paid lifecycle + edit-until-invoiced; decouple tax report from bills flag (2e8e4a0)
- accounting: expenses ledger + supplier-payment toggle (0c35ac4)
- accounting: explain dispositions inline, drop markup from pass-through (9a023c0)
- accounting: frontend rework - separate Incoming invoices vs Expenses (stage 2) (f305541)
- accounting: inbound supplier-invoice capture + expense re-bill (backend) (c305492)
- accounting: incoming-invoice triage refinements (paid badge, click-to-categorize, reference, categorize+pay) (72b784c)
- accounting: incoming-invoice workflow v2 + VAT/financial settings consolidation (b527915)
- accounting: incoming-invoices inbox with camera capture + triage/re-bill (2b5efeb)
- accounting: invoices force-enable the Accounting master (51837c3)
- accounting: Layer A backend — chart of accounts, VAT codes, Treuhänder export (03cc250)
- accounting: Layer A frontend — chart of accounts CRUD + Treuhänder export UI (7e0098e)
- accounting: manual "add expense" (no document) on the ledger (703f727)
- accounting: move Chart of accounts into Settings → Accounting (97795f6)
- accounting: move Treuhänder export onto the Tax page (b1f73c1)
- accounting: PDF/image preview in triage, opened at the QR-bill (no OCR) (502fbad)
- accounting: rasterise inbound PDFs server-side (never serve raw to browser) (e111522)
- accounting: re-categorize incoming invoices, note field, pending re-bill pool (36a8e42)
- accounting: re-viewable incoming invoices + expense invoiced/paid lifecycle UI (727bdab)
- accounting: relocate VAT codes + rate maps into Settings → Accounting (4ff5b84)
- accounting: scope the tax-report export to income-only or cost-only (9f3b286)
- accounting: snapshot the chosen VAT code on quote/invoice create + storno (5b52969)
- accounting: snapshot vat_code on quotes/invoices + export prefers it (foundation) (0a7dc1c)
- accounting: split Incoming invoices vs Expenses - flags, schema, settings (stage 1) (c59df52)
- accounting: supplier-country tax default + configurable default output VAT code (267b121)
- accounting: tax report VAT-payable honours registration + reclaim (d7107aa)
- accounting: tax window shows all costs (incoming invoices + expenses) alongside revenue (545ef33)
- accounting: unify tax report into one signed, typed, sortable ledger (fd1dd81)
- accounting: VAT registration + reclaim-country settings in the Accounting tab (4d87684)
- accounting: VAT registration/reclaim settings + un-gated VAT-codes read (fbbbb8a)
- accounting: VAT-code dropdown in the quote editor (+ reusable VatRateSelect) (6e1924b)
- admin photos list/grid toggle + upload failure report (#707, #708) (e873f7c)
- admin photos list/grid toggle + upload failure report (#707, #708) (6f95796)
- admin two-factor authentication (TOTP) with recovery codes + CLI reset (cf07361)
- admin-configurable workflow engine + dunning/Mahngebühr rework (RFC — feedback welcome) (15be3b8)
- admin-ui: TOTP MFA enrollment + two-step login; remove stub 2FA toggle (96e3c68)
- admin/exports: inline preview modal with copy-to-clipboard (#631) (fc5c1ae)
- admin/exports: inline preview modal with copy-to-clipboard (#631) (27b5f7e)
- admin: in-app migration banner for the org rename (0213347)
- admin: in-app migration banner for the org rename (#669) (2a4bf3b)
- analytics: pluggable trackers — Umami + Rybbit + Custom (#663 Phase 1) (83461fe)
- analytics: pluggable trackers — Umami + Rybbit + Custom (#663 Phase 1) (ab50145)
- auth: admin TOTP MFA — enrollment, login challenge, recovery, CLI reset (72e2ef6)
- backup: .picpeak download + upload-restore UI in Backup Manager (66d61c8)
- backup: .picpeak import/restore (full override, keeps current account) (2920d82)
- backup: .picpeak portable export (engine-neutral logical snapshot) (38b3aef)
- backup: fold .picpeak restore into the Restore wizard's Upload source (86324e7)
- backup: upload + restore endpoint for .picpeak (2b66f6d)
- branding: force color mode = standard look; hide overridden theme controls (4749e22)
- categories: per-category download permissions (#640 part B) (820f483)
- common: generic Promise-based ConfirmDialog primitive (#640 part C) (a3fcb5b)
- crm: 3-reminder dunning + flat/percent Mahngebühr on 2nd & 3rd + AGB notice (dcdbeb9)
- crm: cash-basis revenue + backdatable payment date on mark-paid (82ec238)
- crm: event-type dropdown on quotes; quote→event uses it (no more hardcoded 'wedding') (f78671f)
- crm: Mahngebühr on a separate Mahnung document; invoice stays immutable (5ed2fec)
- crm: pre-event reminder falls back to the assigned customer account (3ccaed0)
- crm: Project Overview phase 1 — projects schema (efa47d6)
- crm: Project Overview phase 2 — project service + routes (eb26313)
- crm: Project Overview phase 3 — persist sent email HTML (874c91f)
- crm: toggle for VAT on late fees (jurisdiction-dependent) (eaceb7e)
- dashboard: revenue "year" tile toggles 365 days ↔ calendar YTD (d1c9e02)
- email: add 'Test connection' to incoming mail + tidy IMAP label (f017649)
- email: incoming mail (IMAP) intake - backend + standalone flag (5645c30)
- email: incoming mail UI - IMAP config block + Received emails tab (31280e1)
- email: round-trip test — send via SMTP to the IMAP mailbox and confirm arrival (04be51a)
- events: duplicate-gallery action (#626) (e985d25)
- feedback: export shape toggle — per-action vs per-guest pivot (#640 part E) (fabd67a)
- feedback: per-guest favorite + like caps with mobile-friendly limit modal (#655) (3ac7017)
- feedback: per-guest favorite + like caps with mobile-friendly limit modal (#655) (f2814e4)
- first-run setup wizard (feature selection + config) and portable .picpeak backup roundtrip (e513e83)
- gallery: branded URL shortener — /s/<slug> with OG injection (#699) (a0f7033)
- gallery: branded URL shortener — /s/<slug> with OG injection (#699) (56c2386)
- gallery: publish notifies assigned customer accounts via the account email (c657892)
- invoices: optional sub-cent rounding reconciliation ("Rundung" row) (4670292)
- invoices: surface monthly/manual accumulator drafts in the Bills list (e457656)
- Live Slideshow ("Diashow") — fullscreen, auto-updating projector view for live events (4356393)
- messages: create/select quote, contract, invoice, gallery from a message (0dbf863)
- messages: Outlook-style Messages email client (3 phases, flag-gated) (d0bdcb1)
- messages: Phase 1 read-only Messages viewer (email client shell) (26eeb76)
- messages: Phase 2 — customer (hello@) mailbox + inbound body capture (ee46cf2)
- messages: Phase 3 — editable-template composer, reply + create actions (768e847)
- messages: search bar + Archive/Delete with Archived & Deleted folders (99d5996)
- messages: unified Messages email client (flag-gated, default off) (a71b9b5)
- projects: attach-event control in the cockpit (dffcf62)
- projects: flag re-rendered emails in the feed (94f2c01)
- projects: gate Project Overview behind a projects feature flag + cockpit email actions (1bf0b34)
- projects: gated project pickers on quote/contract/hours editors (0175007)
- projects: link quotes & contracts to a project (precise cockpit rollup) (6420047)
- projects: linking a quote/contract cascades the whole deal into the project (a702f33)
- projects: Project Overview cockpit — link (multiple) quotes/contracts/hours into projects (58f93ae)
- projects: Project Overview cockpit UI + CRM nav entry (81553aa)
- projects: rolled-up project value (newest stage wins per deal, cumulative) (7ca2437)
- setup wizard + argument-driven unattended install (681619f)
- setup: add "How will you use PicPeak?" feature-selection step (422dfe1)
- setup: add restore-from-backup branch to the first-run wizard (a95ee47)
- setup: brand first-run screen and split into two-step wizard (d9b0eb7)
- setup: final community step (#732) + fix create-admin button overflow (#730) (a5f49e3)
- setup: final community/thank-you step (#732); fix create-admin button overflow (#730) (dadaaee)
- setup: per-feature config step after feature selection (07b450a)
- setup: step-by-step wizard + argument-driven unattended install (d35c413)
- setup: validate setup token at step 1 before advancing (b0912c7)
- slideshow: add image fit setting (fill vs black bars) (b5c73e0)
- slideshow: admin ui for live slideshow (385b05a)
- slideshow: backend api for live slideshow (dea5e0f)
- slideshow: db columns for live slideshow (1029dd0)
- slideshow: en/de strings for live slideshow (cb761ee)
- slideshow: gate behind a feature flag + move globals to a Settings tab (69367b4)
- slideshow: public fullscreen slideshow viewer (fd02254)
- updates: "What's New" highlights after update + pre-update teaser (a1a73bf)
- updates: "What's New" highlights after update + pre-update teaser (500cf85)
- whatsapp: admin-selectable template parameters + reorder (#647 follow-up) (80e8ec5)
- whatsapp: admin-selectable template parameters + reorder (#647 follow-up) (16055cd)
- whatsapp: WhatsApp Business API notification channel (#640 part D) (78c8e9d)
- workflows: 'Clean up layout' auto-arrange button (dagre) (79607c5)
- workflows: add workflows feature flag + Features-tab toggle (ff47861)
- workflows: admin CRUD + run-history + approvals-inbox API (1a0d6de)
- workflows: admin review gates before sends + migrate lifecycle/time triggers (fa7b1ba)
- workflows: advanced text mode — export/import the flow as JSON (289568f)
- workflows: approval gates — email confirm/deny + token resume (b48d8c2)
- workflows: booking cutover — wire booking actions + hold documents behind approval gates (ec33ec7)
- workflows: collections-handoff block after dunning exhausts (b78bd97)
- workflows: crash recovery — resume runs orphaned mid-flow (192d2cb)
- workflows: data-touching action + condition handlers (96fb440)
- workflows: emit lifecycle events from invoice + quote services (cc0ba53)
- workflows: execution engine core + registry + tests (1eaef67)
- workflows: hard cutover of gallery-expiry + dunning + pre-event to flows (0b6c33e)
- workflows: implement prepare_event so booking_full/booking_simple are enableable (4faf5a3)
- workflows: implement remaining stub actions (prepare_quote, prepare_gallery, reserve_date) (9414b42)
- workflows: invoice prepared+approved early, dispatch waits; daysBefore in editor; dashboard approvals (182e655)
- workflows: make approval rows clickable to open the underlying document (7727b67)
- workflows: migrate the dunning ladder onto the engine (cutover) (5259ee9)
- workflows: per-quote booking-workflow picker + quote→invoice (no gallery) built-in (d14f1d8)
- workflows: pre-event reminder picks the template GROUP on the block, type stays automatic (10d091b)
- workflows: React Flow canvas editor + list + approvals UI (5c0396d)
- workflows: route webhook node through the delivery pipeline (full Option 1) (675e41a)
- workflows: scheduler resumes elapsed wait nodes (610a3df)
- workflows: schema + permissions (migration 142) (c818c25)
- workflows: seed booking + pre-event built-ins, wire event.date_approaching (62ba905)
- workflows: seed invoice-dunning ladder as an editable built-in flow (9b557ef)
- workflows: test-fire — safe dry-run of any flow on demand (e70ddd3)
- workflows: warn when disabling a built-in (reverts to legacy, not off) (c5f131c)
- workflows: wire booking document actions (prepare_invoice/contract + send_document) (cf424ef)
- zero-config first run — in-browser admin bootstrap + auto-generated secrets (bafc96f)
- zero-config first run — in-browser admin bootstrap + auto-generated secrets (415bffa)
Bug Fixes
- accounting: 'Save & mark paid' actually pays; incoming invoices appear in tax/export (3b70a09)
- accounting: address the-luap PR #636 review (707c5d0)
- accounting: always show Income/Costs/Result summary on tax page (even with zero costs) (663daf5)
- accounting: Banana export is now a tab-separated .txt (actually importable) (a195067)
- accounting: Banana I&E export uses the 'Category' column (not 'ContraAccount') (53a16f9)
- accounting: distinguish Categorized (purple) from Paid (green) (9514f5c)
- accounting: emit ISO dates in exports (Postgres returns Date objects) (0c0fb29)
- accounting: label the outgoing-invoice totals block in the tax summary (f3e77e7)
- accounting: lock company-expense to company, first-page categorise preview, auto-refresh inbox (cee692c)
- accounting: migration 127 must not insert created_at/updated_at into app_settings (31867ef)
- accounting: PDF pager always shown, click categorized→pay, drop duplicate Paid chip (5fcb96c)
- accounting: PR #622 blockers — CSV formula injection + IMAP double-ingest race (cd6d578)
- accounting: PR #622 concerns — flag-cache, customer master gate, VAT-unconfigured, helpers, page cap (a93b6dc)
- accounting: tax report 500 on Postgres — drop SQL date() from cost queries (ea8f6bc)
- accounting: tax report cost side queried a non-existent column (ab65a47)
- accounting: tax report degrades gracefully if cost side fails (+ surface the error) (9f85111)
- accounting: tax-report storno totals + hours-line date on Postgres (db9e41d)
- accounting: tidy the tax-export scope selector styling (8deb7e0)
- accounting: UTF-8 BOM on the ledger export so Banana reads it correctly (74144da)
- admin-header: skeleton brand block + move LanguageSelector into profile menu on <sm (#523 follow-up) (b48b5b0)
- admin-header: skeleton brand block + move LanguageSelector into profile menu on <sm (#523 follow-up) (fe10191)
- admin/events: delete cascade orphaned photo folders because it read a non-existent column (#608) (284680e)
- admin/events: delete cascade orphaned photo folders because it read a non-existent column (#608) (457c956)
- admin/exports: Lightroom TXT export joins with comma + drops extension (#623) (a239fec)
- admin: graceful logo-img fallback + show sidebar widgets during perm hydration (#523 follow-up 2) (f51b9cf)
- admin: logo-img fallback + sidebar perm hydration + filename NFD transliteration (#523 follow-up 2, #607) (fcd3ca3)
- admin: stack publish-gallery dialog CTAs so the German label fits (#670) (748af98)
- admin: stack publish-gallery dialog CTAs so the German label fits (#670) (ea2852d)
- admin: stop the event-date field crashing the page on backspace (760a201)
- admin: stray literal "0" rendered from SQLite integer booleans (760c3d7)
- analytics: admin dashboard reads correct fields + Umami device API (#661) (349f566)
- analytics: admin dashboard reads correct fields + Umami device API (#661) (7534447)
- archives: stream-extract restore for >2 GiB + preserve original_filename via manifest (#640) (e4e79a0)
- auto-publish release-please PRs without manual approval (fb64ec0)
- backup: address .picpeak review — table filter, superuser guard, tests (fa7665c)
- backup: make .picpeak roundtrip work on Postgres (f57462f)
- branding+whatsapp: preserve customCss through preset switches (#645) + admin-pinned WhatsApp template language (#647) (cde028e)
- branding: force lock = light/dark only; Branding stays the full preset, galleries hide color+mode (a7c1913)
- branding: make 'Show logo in hero' a true global toggle with per-event override (#756) (a88da99)
- branding: make 'Show logo in hero' a true global toggle with per-event override (#756) (96fe478)
- branding: point HTML favicon link at /favicon.ico (the real Safari fix) (c60e34e)
- branding: preserve customCss through preset switches + theme changes (#645) (7cf2679)
- branding: serve favicon via backend route so Safari picks it up (db3e327)
- branding: stream favicon bytes directly (Safari ignores the 302) (7ccfdc1)
- branding: unify hero logo SIZE the same way as visibility (#756) (60b03b1)
- branding: when a force lock is active, collapse the theme customizer to just the Force control (1ac653a)
- ci: auto-publish release-please PRs without manual approval (#719) (a3e7232)
- ci: enable release-PR auto-merge with the PAT, not GITHUB_TOKEN (e08a33d)
- ci: set GH_REPO in release-please auto-merge step (0cab43e)
- ci: whatsnew highlights — set GH_REPO so gh runs without a checkout (3feed0f)
- ci: whatsnew highlights — set GH_REPO so gh runs without a checkout (2a5f0a8)
- conform moved code to eslint indent/quotes, 4-arg mutation callbacks (2ea26a4)
- crm: admin surfaces follow the admin light/dark toggle, not the gallery theme (#620) (d3266a0)
- crm: commit LocalizedDateInput value live, not only on blur (0b4690a)
- crm: country dropdown on customer onboarding, placed after State/region (18ffff2)
- crm: country dropdown on customer profile billing address too (fe56d24)
- crm: drop redundant 'Country (full name)' field (a2b5ae1)
- crm: editor totals box computed VAT 100× too small (e9b297c)
- crm: localize scheduled-send + installment date + timezone picker (43b10f9)
- crm: PR #603 review follow-ups + Outlook-proof email design (a2b2d3f)
- crm: pre-event reminder passes raw event_date (fixes "Invalid Date" in the email) (250b240)
- crm: pre-event reminder resolves recipient from the event row, not a non-existent column (5fbe514)
- crm: quote→event fallback resolves an ACTIVE event type, never hardcoded 'wedding' (2309812)
- crm: recent-activity email placeholder + customer-dashboard locale dates (ea09a86)
- crm: recognise imported-invoice revenue on issue_date, not paid_at (5e79c69)
- deps: bump qs/brace-expansion overrides + add uuid override for node-cron (d705059)
- downloads: transliterate accented characters in filename via NFD instead of dropping them (#607) (620163f)
- email,ui: billing emails follow customer language + readable pay… (ea86871)
- email,ui: billing emails follow customer language + readable payment-check confirmation (0c2d319)
- email,ui: billing emails follow customer language + readable payment-check confirmation (fcc3e91)
- email: always log incoming mail to received_emails (was lost on insert error) (9c18dcf)
- email: fail-fast IMAP timeouts + manual 'Check now' poll (8a54c6f)
- email: guard round-trip test when IMAP username isn't an email (e258472)
- email: IMAP Security dropdown auto-fills the conventional port (bd402d2)
- email: IMAP Security dropdown matches outgoing — no port in label, manual port (d04a697)
- email: log all received mail, not just unseen (90-day lookback + dedup) (c36797d)
- email: mark required fields on incoming mail to match outgoing SMTP (fb48ba4)
- email: match IMAP card to SMTP styling + auto-detect mailbox folders (abb23f0)
- email: recover stuck queue — reinit transporter on config save + manual flush ignores retry cap (68c967f)
- email: resolve recipient language from the queue row's event_id, not just email_data (10559fd)
- email: sibling billing emails follow customer language too (c0008be)
- email: surface the real error on test/save/flush instead of generic toast (47edbf6)
- enable release-PR auto-merge with the PAT so releases actually publish (97b9853)
- event creation 500s on PostgreSQL (NaN slideshow seed) + stray "0" boolean renders (b187f58)
- event-reminder, email-language & gallery-publish bugs surfaced during workflow testing (c8714ca)
- event-types: renaming a type's slug cascades to events, quotes + reminder template (415c93a)
- events: NaN from slideshow seed breaks event creation on PostgreSQL (8c86518)
- events: publish-from-draft email carries the real password (#627) (83b568e)
- events: wire customer notifications into both public API entry points (#647) (f017542)
- events: wire customer notifications into both public API entry points (#647) (511d647)
- flags: close CRM/accounting feature-gating gaps from the audit (03fa3d8)
- gallery: admin edits to welcome_message land for returning guests (#625) (ea6245c)
- gallery: guest upload honours general_max_files_per_upload + i18n placeholder interpolates (#613) (40a4aa2)
- gallery: guest upload honours general_max_files_per_upload + i18n placeholder interpolates (#613) (69b5186)
- gallery: leave a visible gap between filter bar and hero header (#624) (178d6da)
- gallery: publish dialog stuck for password-protected galleries with no inline email (aa3471e)
- gallery: unbreak password entry in Instagram in-app browser (#654) (6193ab7)
- gallery: unbreak password entry in Instagram in-app browser (#654) (b1bfd48)
- hours: move logActivity out of the entry transactions (SQLite deadlock) (348955b)
- i18n: replace ASCII quote with U+201D in DE perGuestLimitsDesc (98e97e3)
- i18n: sweep activity-type translations + Events / API Tokens / Webhooks settings tabs (f17c654)
- i18n: sweep activity-type translations + smart notification fallback (bc8d333)
- i18n: sweep Events / API Tokens / Webhooks settings tabs (997a412)
- i18n: wrap WhatsApp token show/hide aria-label through t() (a8bb7b4)
- invoices: add bank transfer to the mark-paid method list (e96ef4c)
- invoices: badge held (unsent, no send date) invoices as "Draft" (e4367e0)
- invoices: correct payment-check email template key so dunning email sends (9a76333)
- invoices: correct payment-check email template key so dunning email sends (3682de1)
- invoices: show "Draft" on the invoice detail page for accumulator drafts (ca09442)
- invoices: show sub-cent Rundung in the editor totals preview (c2bc2b0)
- maintenance: enabling maintenance mode no longer locks admins out (2493130)
- maintenance: never block /admin/* with the maintenance screen (fdde469)
- messages: dynamic addresses, branding accent, compose/sync, per-identity SMTP (7cc1c59)
- messages: dynamic addresses, branding accent, compose/sync, per-identity SMTP (f9c2b4e)
- messages: make the Messaging feature flag toggleable (b96ad36)
- messages: PR #769 nits — server-side search, bare-email recipient, DE i18n (1e08a4f)
- messages: PR #769 review — escape reply sender (XSS), gate backend routes, exact customer match (bb235e7)
- messages: show only the mailbox local part in the sidebar (full … (c622a35)
- messages: show only the mailbox local part in the sidebar (full address on hover) (88fe9f9)
- messages: show the resolved customer's name in the doc-action modal (2c5c1d5)
- mirror #734 onto decomposed files (PG NaN slideshow seed, SQLite bool renders) (766351b)
- og: broaden social-crawler coverage (Bluesky Cardyb, WeChat-scraper, fediverse, etc.) (a0a28a4)
- og: rich social previews for share-token + slideshow URLs (#699) (25bf7bb)
- og: rich social previews for share-token + slideshow URLs (#699) (1b8747d)
- og: route branded short URLs + slideshow links to OG, add Viber (#699) (0dffe0c)
- og: route branded short URLs + slideshow to OG handler, add Viber (#699) (a87ad77)
- pdf: correct multi-page invoice/quote layout + drop IBAN dup under Swiss QR (2205b0b)
- projects: "one customer matches" rule for deal-lineage attach (f74d8d4)
- projects: address review — cross-customer guards + email/queue hardening (9d13880)
- projects: clickable milestones/feed, email rollup by customer, PG amount coercion (c0b6d14)
- projects: enforce single-customer projects (guard event attach + re-label) (4b1e85c)
- projects: make email preview fully read-only (no clickable links) (fa622cf)
- projects: make the whole email row clickable (opens preview) (84b4a5f)
- projects: only link cockpit rows when the target feature is enabled (2369323)
- projects: render email preview with its own brand colors, not forced light (b9a9c01)
- projects: scope 'book to project' to the current customer (89bfb6c)
- projects: scope email rollup to CRM types + re-render unstored previews (f02fba6)
- projects: use real events.edit permission for project writes (f71243e)
- projects: wrap long URLs in email preview (no horizontal scroll) (0cc52f3)
- reminders: wrap is_active/is_archived wheres in formatBoolean (b9d9138)
- security: close BOLA on photo-export + NAT64 SSRF in URL guard (b8211e9)
- security: close cross-event thumbnail leak, bulk-op ownership bypass, + hardening (081f3ed)
- security: close NAT64 SSRF + photo-export BOLA + sweep Trivy alerts (GHSA-wmjx-pc37-272r, GHSA-9v4w-jrhx-g5wr) (6f40db8)
- security: cross-event thumbnail leak, bulk-op ownership bypass + auth hardening (b732974)
- security: re-apply SVG CSP on the direct favicon route (PR #603 blocker) (1214b6b)
- set GH_REPO in release-please auto-merge step (d00d52a)
- settings: don't insert non-existent created_at into app_settings (8621338)
- settings: hoist tab-visibility useEffect above isLoading early return (49bfb45)
- settings: remove duplicate Mail import that broke the dev server (5b535f8)
- settings: remove duplicate Mail import that crashes the dev server (4aa6583)
- setup: address PR #714 review — password UX, script token, race, nits (286975d)
- setup: keep the first-run wizard light regardless of dark mode (d4b143f)
- setup: match first-run logo size to the login page default (3e69c5d)
- slideshow: deny display-only token on download/upload/feedback (PR #646 review) (e36b330)
- slideshow: dip-to-white/black no longer flickers the image (db8388c)
- slideshow: drop updated_at from event writes (1e40f82)
- slideshow: feature flag is a master kill-switch, not just admin UI (759784a)
- slideshow: fill the viewport instead of black bars (6ec46de)
- slideshow: read globals from app_settings, not the missing settings table (0f4388d)
- slideshow: surface backend error in the live slideshow card (056f938)
- test: raise bootCrmDb beforeAll timeout on slideshow suites (f4b6b89)
- upload: auto-throttle on low-memory hosts + correct documented RAM minimum (#628) (714a9f6)
- whatsapp: admin-pinned template language + Arabic locale support (#647) (4fd7709)
- whatsnew: decode HTML entities and trim em-dash detail in fallback bullets (5582644)
- workflows: backfill existing invoices + anchor dunning grace to due date when enabled (#750) (9596342)
- workflows: backfill existing invoices + anchor grace to due date when dunning is enabled (#750) (2c7b351)
- workflows: close review blockers — prefetch-safe approvals + loud gate-edge failure (98ab717)
- workflows: dark-mode canvas + readable nodes + structured config (1734aba)
- workflows: defer quote.accepted/declined emit until the 15-min response window locks (539a837)
- workflows: harden graph validation + refuse enabling unimplemented flows (d927464)
- workflows: held booking invoices are 'scheduled', not 'pending_delivery' — so send_document can issue them (882cfc0)
- workflows: make the dashboard pending-approvals card items clickable too (6e20d58)
- workflows: matchFilter strict equality + accurate comment (dee8d40)
- workflows: Postgres-safe id capture on workflow inserts (cede885)
- workflows: scope dunning backfill to its own flow via targetWorkflowId (da3a77d)
- workflows: ship built-ins disabled for first beta + enabled-based mutex + admin sentinel (5893ecb)
- workflows: wire a real, SSRF-guarded webhook action (was a silent no-op) (af7eea8)
Performance Improvements
Documentation
- branch model + migration-to-org guide + PR template (166ef47)
- branch model + migration-to-org guide + PR-template target hint (d606fcd)
- prominent migration banner at the top of README (14bd3e1)
- prominent migration banner at the top of README (#669) (5839bba)
- readme: add CRM + accounting to features, tax disclaimer, update contributor (116743b)
- readme: add Pixieset to comparison + customer-accounts/CRM/accounting rows (721f440)
- readme: clarify comparison footnotes — $0 cost caveat + Pixieset video cap (b043963)
- readme: credit @the-luap as creator/lead maintainer (3528f6b)
- readme: credit @the-luap as creator/lead maintainer (748238e)
- require screenshots for UI changes in PRs (f5b4aa7)
- require screenshots for UI changes in PRs (8ca7477)
- slideshow: add Live Slideshow guide + README entries (16013d1)