Matthew Meszaros
9d7e3aa61f
feat: make scheduled sending self-healing - dispatch Cloud Tasks callbacks by the task row type (all enqueues share one webhook URL, so campaign callbacks were run through the warmup handler), cancel pending tasks stranded past their slot so the reconcilers re-seed chains after a lost callback or emulator restart, and cast the status enum in the two UPDATE ... CASE queries that failed parameter type deduction on every callback
2026-07-11 17:31:23 +02:00
Matthew Meszaros
167cc370b3
feat: re-key dedicated_worker_assignments to organizations (migration 000055) - the assignment service has always keyed by org id but the column carried a users FK, so every runtime bind failed with an FK violation and dedicated-plan orgs could never get a worker; renames the column, remaps seed rows, and updates the repository, admin filter, and convert-to-dedicated endpoint to org semantics
2026-07-11 17:31:23 +02:00
Matthew Meszaros
07a6777536
feat: email OAuth callback page gains a native-app fallback - when there is no web opener to postMessage (an ASWebAuthenticationSession has no popup parent) it redirects to warmbly://email-oauth with provider/code/state/error so the iOS app can finish the connect; web popup behavior is unchanged and the docs describe both delivery paths
2026-07-11 10:13:10 +02:00
Matthew Meszaros
cc0871d1b8
feat: contacts search gains an additive lead_status filter plus per-status lead_counts on the first page when exactly one campaign_id is set - the SQL predicates reproduce the read-time status derivation exactly (unsubscribed > bounced > replied > active > pending via LATERAL bool_or rollups), invalid lead_status or multi-campaign combinations return 400, and the web types/table pick up the new lead_counts shape
2026-07-11 10:11:36 +02:00
Matthew Meszaros
3acb51df6c
feat: add server-side status-bucket filtering to GET /campaigns (draft/active/paused/completed, paused matches every paused_* variant, invalid values 400) and a new GET /campaigns-overview endpoint returning status and per-folder counts, with the campaigns API reference and endpoint scope map updated
2026-07-07 09:40:27 +02:00
Matthew Meszaros
13f193d91e
feat: unibox list filters - from now matches sender addresses by case-insensitive substring as documented, and a new uncategorized=true param returns only threads with no labels, documented in the unibox API reference
2026-07-07 05:56:47 +02:00
Matthew Meszaros
a20ba926cb
feat: add native Apple/Google sign-in to the backend - POST /auth/apple and /auth/google exchange provider-signed ID tokens for sessions, GET /auth/providers exposes configured providers for app discovery, with a JWKS-verifying idtoken package, auth config, stable error codes, and API/security docs
2026-07-07 05:56:35 +02:00
Matthew Meszaros
d4ead05456
feat: persist campaign sequence canvas coordinates with x/y columns (migration 000053) plus a bulk sequence-layout service/repo path that scopes by campaign owner and never bumps updated_at
2026-06-30 10:06:20 +02:00
Matthew Meszaros
73838cecf5
feat: add an unaudited automation node-layout endpoint handler/service/repo backed by an atomic jsonb x/y merge that leaves edges, config, and updated_at untouched
2026-06-30 10:06:19 +02:00
Matthew Meszaros
5e94b945ff
feat: add GetIdentity handler returning user, org, auth type, and granted scopes for GET /v1/me
2026-06-28 19:09:37 +02:00
Matthew Meszaros
9dd37b0d62
Merge pull request #52 from warmbly/referral-credits
...
feat: implement referral program with credit-based rewards
2026-06-28 09:12:57 +02:00
Matthew Meszaros
7e75394ab8
feat: decode the admin discount list and redemption cursors as opaque offset tokens, returning 400 on a malformed cursor instead of silently resetting to the first page
2026-06-28 05:58:25 +00:00
Matthew Meszaros
789da671d6
feat: send organization member invitations through GenerateInvitationHTML so they match the rest of the transactional mail
2026-06-28 05:27:18 +00:00
Matthew Meszaros
8bd3a1137e
feat: expose the JWT referral and applied-discounts endpoints with handlers and manage_billing-gated routes
2026-06-28 05:09:50 +00:00
Matthew Meszaros
03acdb87e3
fix: thread organization_id through contact, CRM, and unibox reads and writes so non-owner org members see and edit their workspace data, and backfill contacts.organization_id for single-membership users (migration 000049)
2026-06-15 08:11:53 +02:00
Matthew Meszaros
9d0c432be7
feat: let OAuth apps subscribe to webhooks by declaring a url/events/secret and materializing per-org endpoints gated by each grant's scopes, with secret rotation and delivery observability (migration 000050)
2026-06-15 08:11:20 +02:00
Matthew Meszaros
173736a004
feat: add a Stripe-grade webhook platform with a typed event catalog, HMAC-signed delivery, retries with backoff, endpoint ownership verification, per-endpoint throttling, an audit-spine event bridge, and firehose emit sites (migration 000048)
2026-06-15 08:11:20 +02:00
Matthew Meszaros
fcdb31cda7
feat: OAuth apps always issue a client secret (drop the public/PKCE-only client type, secret required for the token exchange), add an app-logo upload endpoint, and align the docs to OAuth2 with optional PKCE
2026-06-14 09:52:49 +02:00
Matthew Meszaros
8c175d4221
feat: add an OAuth 2.1 authorization server (migration 000047 apps/codes/grants, app registration CRUD, authorization-code-with-PKCE authorize+token+refresh-rotation+revoke endpoints, RFC 8414 discovery, bearer-token validation wired into the auth middleware reusing the API-permission gates, scopes mapped to API permission bits)
2026-06-13 13:56:39 +02:00
Matthew Meszaros
331745ecc5
feat: add a generic per-automation inbound webhook trigger (inbound.webhook event, token-gated POST /api/v1/integrations/inbound/automation/:token, migration 000046 inbound_token, background graph run with the JSON body as event payload)
2026-06-13 13:04:10 +02:00
Matthew Meszaros
aed4a06190
feat: unify pagination by making the offset-based CRM deals/tasks search and meetings endpoints expose the same opaque next_cursor and {total, next_cursor, has_more} envelope as every keyset list (offset hidden inside the token), updating web clients, the OpenAPI spec, and the reference docs
2026-06-13 10:47:17 +02:00
Matthew Meszaros
57e8705a82
feat: make public API list cursors opaque base64 tokens (internal/utils/paging) instead of raw record UUIDs, decoding on input with a 400 on a bad cursor; admin endpoints keep transparent UUID cursors
2026-06-13 07:18:23 +02:00
Matthew Meszaros
a7a43e0c4c
feat: rename the campaign sequences resource to steps across the API and URL (/campaigns/:id/steps), the JSON fields (target_step_id, step_id/step_name/step_index, analytics steps[], create body steps), the web client/models/route segment/labels, the audit step entity type, and the wire-contract docs; internal Go type names and the Kafka avro schema stay
2026-06-12 09:38:11 +02:00
Matthew Meszaros
0fd3d03f55
feat: add org-wide team presence privacy columns (presence_show_online, presence_show_activity) with update plumbing and a PRESENCE_POLICY_UPDATED realtime event so a settings change re-gates connected sockets live
2026-06-12 05:59:01 +02:00
Matthew Meszaros
8547fe97eb
feat: scope unibox MarkSeenBulk by organization so a non-owner member opening a thread clears the shared org-wide unread state instead of updating zero rows
2026-06-12 05:14:50 +02:00
Matthew Meszaros
4db027a342
feat: scope unibox GetByThread by organization instead of user_id so non-owner members see the full conversation they already see in the org-scoped inbox list, not an empty thread
2026-06-12 05:10:00 +02:00
Matthew Meszaros
6a3b8ac0eb
fix: scope the unibox unread-count endpoint by organization_id so the sidebar Inbox badge counts the workspace's unread mail instead of always showing 0 for non-owner members
2026-06-11 18:05:18 +02:00
Matthew Meszaros
594c696bf6
fix: scope the unibox inbox list and overview by organization_id (via the workspace's email accounts) instead of the logged-in user_id, so every member sees the org's incoming mail; per-user thread labels and snoozes stay personal
2026-06-11 17:57:52 +02:00
Matthew Meszaros
21032a8fce
fix: scope the contacts list by organization_id instead of user_id so all members see the workspace's contacts (and per-contact campaign badges); categories badge still user-scoped pending an organization_id column on categories
2026-06-11 17:52:36 +02:00
Matthew Meszaros
88e241d536
fix: scope the analytics dashboard (overall stats, recent activity, top campaigns, daily trend, account health) by organization_id instead of user_id, so every workspace member sees the org's analytics rather than an empty dashboard
2026-06-11 17:49:39 +02:00
Matthew Meszaros
a21dc57e07
fix: scope campaign list/detail/count queries by organization_id instead of user_id, so all workspace members see the org's campaigns rather than only the creator
2026-06-11 17:47:04 +02:00
Matthew Meszaros
6ae5e52c4e
fix: scope email-account list/detail queries by organization_id instead of the logged-in user_id, so every member of a workspace sees the org's mailboxes (not just the owner who connected them)
2026-06-11 17:43:56 +02:00
Matthew Meszaros
3c040649c0
fix: changing your password now revokes every other session (keeping the current device), matching the security promise in the sign-in alert and docs
2026-06-11 12:39:24 +02:00
Matthew Meszaros
5bcc2baaa8
feat: implement the coming-soon security features — logged-in change-password (verify current, policy-checked, POST /me/password) with a real dialog, and new-device sign-in alerts (security notification category fired from the token service on an unrecognized OS+browser, delivered in-app and by email), removing the comingSoon stub helper and updating docs
2026-06-11 12:30:44 +02:00
Matthew Meszaros
39a9752d63
feat: real tokenized invite-accept link — public /invite landing page with safe preview (org, inviter, roles), accept-by-token plus the previously-broken accept-by-invitation-id, public preview + admin copy-link endpoints, login next-param redirect, and a Copy button that yields a working /invite?token link
2026-06-11 11:57:45 +02:00
Matthew Meszaros
19f66507b4
feat: fix multi-role review findings — atomic member+roles insert on invite accept (no partial-failure stranding), gate role deletion on the actor holding the role's permissions (blocks team-managers de-privileging admins), and hydrate+chip pending-invitation role sets
2026-06-11 11:32:57 +02:00
Matthew Meszaros
3473d09bcc
feat: fix review findings in the roles redesign — GetMembers role_id column (members endpoint 500), TransferOwnership role_id hygiene, accept-time role re-resolution, race-free in-use delete guard covering invitations, assignment anti-escalation with self-role-change block, canManage-gated members UI, colored RolePills, fresh currentOrganization on refetch, dev JWT_SECRET wiring for make realtime, docs corrections
2026-06-11 10:45:21 +02:00
Matthew Meszaros
edd4524007
feat: custom organization roles backend (organization_roles table with write-through member propagation, CRUD endpoints with anti-escalation and in-use guards, custom-role invites and assignment via role_id, audited as role entity)
2026-06-11 09:39:52 +02:00
Matthew Meszaros
8732805934
feat: replace signed click redirects with server-side link tickets (tracked_links store, internal resolver API, opaque /c/<id> URLs, layered anti-probe caches with miss budget and circuit breaker) removing TRACKING_LINK_SECRET entirely
2026-06-11 09:30:21 +02:00
Matthew Meszaros
fe96eff7b4
feat: audit-log coverage for teams, automations (typed entity), lead-sync sources, and manual meetings so the org activity trail and its realtime spine see every mutation
2026-06-11 07:47:29 +02:00
Matthew Meszaros
a6acb97dea
feat: key the worker-facing internal DEK endpoint by organization
...
The /api/v1/internal/dek route parameter is now :orgID to match the
org-scoped encryptedkeys store. Workers fetch the organization DEK for
the account they are operating on instead of a user DEK.
2026-06-10 17:16:07 +02:00
Matthew Meszaros
5954ac53c2
feat: add automation execution safeguards
...
Support chained automation execution from native actions, guard automation recursion depth, carry idempotency context through campaign-launched automations, allow team task assignment in backend action execution, and reject deletes while campaign steps still reference an automation.
2026-06-09 10:56:56 +02:00
Matthew Meszaros
b2c5117eca
feat: preview campaign templates
...
Adds the shared template helper function map, send-path spintax expansion, server-side template preview validation, and the campaign template preview endpoint.
2026-06-08 15:04:53 +02:00
Matthew Meszaros
4013b33008
feat: expose security notification APIs
...
Wires notification and two-factor services into the backend and consumer, adds the authenticated notification feed/preferences endpoints, and exposes the public 2FA login verification endpoint.
2026-06-08 15:04:47 +02:00
Matthew Meszaros
5f7ac801ba
feat: execute automation graphs
2026-06-08 12:03:11 +02:00
Matthew Meszaros
b28fc9e957
feat: expose automation APIs
2026-06-08 06:55:11 +02:00
Matthew Meszaros
e6b2f233a1
feat: expand integration and meeting APIs
2026-06-08 06:25:40 +02:00
Matthew Meszaros
8773b7f7f3
feat: push contacts to integrations
2026-06-07 20:30:52 +02:00
Matthew Meszaros
051ae73fd2
feat: resolve named sender contacts
2026-06-07 07:54:02 +02:00
Matthew Meszaros
5f3940602f
feat: add CRM task search summaries
2026-06-07 07:04:16 +02:00