github PicPeak/picpeak v2.7.0

2 hours ago
  • 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

  • slideshow: cache global settings to cut /state DB reads (PR #646 review) (a995131)

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)

Don't miss a new picpeak release

NewReleases is sending notifications on new releases.