Commit Graph
139 Commits
Author SHA1 Message Date
Matthew Meszaros 4762256c49 feat: add the warmbly.label_email native action type and the label_ids action config field across the campaign ActionConfig and the IntegrationAction enum + IsNativeAction 2026-06-12 16:44:07 +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 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 160dc0bc76 feat: implement the coming-soon notification delivery channels — Email (SES/SMTP to the account email) and Slack (posts to the org's connected workspace via a new integration NotifySlack), wired in both backend and consumer with per-channel gating, real toggles replacing the coming-soon labels, and updated docs 2026-06-11 12:21:48 +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 8540f7db15 feat: members can hold multiple roles — join tables for member/invitation role sets (migration 000044) with effective permissions as the bitwise OR recomputed on every assignment and role edit/delete, role_ids in invite/update APIs, multi-select checkbox role picker with colored chips in roster and invite flow, freely deletable roles 2026-06-11 11:24:19 +02:00
Matthew Meszaros 091b39f34e feat: roles become workspace data — seed editable Admin/Manager/Viewer rows per org (migration 000043 with member backfill), require role_id for invites and role changes, add role colors with a shared colored RoleSelect dropdown in the roster and invite flow, and rebuild Roles & access around real roles with an Owner reference column 2026-06-11 10:18:45 +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 014cbe79fa feat: label machine opens (Apple MPP prefetch, UA-less fetchers) with human-open upgrade semantics, exclude them from open-triggered automations, and surface the auto-open count in workspace and campaign analytics (migration 000040) 2026-06-11 08:33:09 +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 ae0c433084 feat: seal mailbox validation credentials with the organization DEK
SMTP/IMAP passwords on the validation round-trip are now encrypted and
decrypted under the organization DEK, carried as OrgID on
EventWorkerEmailValidation. Onboarding requires an organization before
a mailbox can be validated.

This fixes a latent key mismatch: the payload never set UserID, so the
worker decrypted with the zero-UUID platform key while the backend had
encrypted with the user key.
2026-06-10 17:16:56 +02:00
Matthew Meszaros ac3c11bf9a feat: seal outbound email content with the organization DEK
The send pipeline (publisher subject/body encryption, the S3 emsg blob,
and the worker-side decrypt) now keys off models.SendEmail.OrgID
instead of UserID. EmailMessage loses its UserID field entirely:
emailSender.Send derives the cipher identity from the email account's
OrganizationID and refuses to send for an account without one.

This also fixes two latent bugs. Emails sent through user_email_task
never set UserID, so they were silently encrypted under the zero-UUID
platform key. campaign_task's discarded Encrypt() pair is replaced with
an explicit DEK warm that fails fast when KMS is unavailable.
2026-06-10 17:16:42 +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 3eb96e33a1 feat: support automation expressions
Adds free-form expression conditions for automation graph branches and shares template helper functions with automation action rendering.
2026-06-08 15:04:59 +02:00
Matthew Meszaros c40a83c22d feat: add two factor auth core
Adds TOTP enrollment state, sealed secrets, recovery codes, pending login challenges, and the auth-service login gate for users with 2FA enabled.
2026-06-08 15:04:36 +02:00
Matthew Meszaros e67ee189a2 feat: add in-app notification core
Adds the persisted notification feed, user preferences, realtime notification events, and advanced-service notification hooks for replies and deliverability health events.
2026-06-08 15:04:29 +02:00
Matthew Meszaros ad7c87acca feat: expand deliverability metrics 2026-06-08 12:03:23 +02:00
Matthew Meszaros 5f7ac801ba feat: execute automation graphs 2026-06-08 12:03:11 +02:00
Matthew Meszaros 1199a17f7e feat: add automation persistence 2026-06-08 06:55:07 +02:00
Matthew Meszaros e6b2f233a1 feat: expand integration and meeting APIs 2026-06-08 06:25:40 +02:00
Matthew Meszaros c724ba59ec feat: expose integration action metadata 2026-06-07 20:30:41 +02:00
Matthew Meszaros fcef5008c4 feat: add CRM task team assignment 2026-06-07 19:32:37 +02:00
Matthew Meszaros 025fc65325 feat: match instant branch triggers 2026-06-07 17:24:08 +02:00
Matthew Meszaros f5abb8cbb6 feat: add CRM deal sequence actions 2026-06-07 11:48:03 +02:00
Matthew Meszaros f3625ca860 feat: add reply classification branch conditions 2026-06-07 11:47:57 +02:00
Matthew Meszaros 5f3940602f feat: add CRM task search summaries 2026-06-07 07:04:16 +02:00
Matthew Meszaros 62da3c3e3d feat: add organization teams API 2026-06-07 07:03:49 +02:00
Matthew Meszaros f9bc1dc40f feat: expose organization member display fields 2026-06-07 07:03:25 +02:00
Matthew Meszaros 9885e8b952 feat: create CRM tasks from campaign actions 2026-06-07 06:18:22 +02:00
Matthew Meszaros f4c738de06 feat: add customizable CRM task types 2026-06-07 06:18:01 +02:00
Matthew Meszaros 0ac0ba80ca Merge remote-tracking branch 'origin/main' into feature/crm-system 2026-06-06 19:42:26 +02:00
Matthew Meszaros 050d09c961 feat: add cross-pipeline deals search surface
Replace the client-side, 100-row-capped deals board as the default view
with a server-driven cross-pipeline table so totals stop lying at scale.

- POST /crm/deals/search: faceted filter body (query, status, pipeline,
  stage, owner, campaign, value range, close-date range), whitelisted
  sort, offset pagination, and Contact/Stage/campaign hydrated via JOIN.
- POST /crm/deals/summary: COUNT + SUM(value) per status and per stage
  over the same filter, with a mixed-currency guard, so header and board
  column totals are true server aggregates.
- DealsTable: cross-pipeline default view (infinite scroll, server
  filters/sort, honest summary stats) with a Table|Board toggle; the
  kanban stays as the single-pipeline working view.
- Deal attribution: campaign_id + source_mailbox_id columns + indexes
  (migration 000022) as groundwork for revenue lineage.
2026-06-06 19:42:20 +02:00
Matthew Meszaros a95a4e206e feat: add unibox thread label models
Add the conversation-label join table and expose thread label fields on the Unibox response models so inbox rows and overview data can carry category metadata.
2026-06-06 19:37:19 +02:00
Matthew Meszaros da82993846 feat: add campaign workflow backend support
Add sequence action-node storage and execution, template conditional rendering, lead progress state, profile updates, webhook fan-out throttling, and supporting repository fixes.
2026-06-06 07:49:52 +02:00
Matthew Meszaros c4c27fcc19 feat: add campaign lead ordering backend
Add campaign lead ordering repository methods for manual send order and tighten strict ESP matching so SMTP/IMAP is only a fallback outside strict mode.
2026-06-05 15:42:12 +02:00
Matthew Meszaros 0e26b9cd00 feat: refine campaign branch scheduling
Evaluate branch conditions relative to the previous send, defer while windows are still undecided, and let the routed pair finder handle deleted targets and loops at schedule time.
2026-06-05 09:10:57 +02:00
Matthew Meszaros e92ec7c661 feat: add ai writing credit backend
Add an organization credit ledger with idempotent consumption, plan credit grants, Anthropic/OpenAI writing providers, and a gated generation endpoint for campaign writing assistance.
2026-06-05 06:03:32 +02:00
Matthew Meszaros 3c440a9f0c feat: add campaign attachment endpoints
Persist campaign attachment metadata, enforce attachment storage quotas, and expose list, upload, and delete routes backed by object storage.
2026-06-05 06:03:13 +02:00
Matthew Meszaros 630e69037a feat: add per-step campaign ab variants
Scope campaign A/B variants to individual sequence steps and select step variants deterministically per contact and step. Keep campaign-level variants on the existing assignment flow.
2026-06-05 06:03:00 +02:00
Matthew Meszaros 2a2e248ad9 feat: add campaign sequence branching backend
Store per-step branching conditions, validate branch targets, and select campaign contact steps by following the flow graph. Preserve linear progression for steps without branch conditions.
2026-06-05 06:02:55 +02:00
Matthew Meszaros 5b9029d2a8 feat: add campaign schedule windows backend
Store per-day schedule windows on campaigns and validate updates before persistence. Use the schedule windows in campaign scheduling, including legacy day/time derivation for existing campaigns.
2026-06-04 18:56:43 +02:00
Matthew Meszaros d6f055da19 feat: add lead sync backend 2026-06-04 11:49:55 +02:00
Matthew Meszaros b2c885dda2 feat: hide sheets automation integration 2026-06-04 11:49:49 +02:00
Matthew Meszaros e1e02c5c18 feat: add campaign send controls backend 2026-06-04 08:53:23 +02:00
Matthew Meszaros 1afe453eb0 feat: add deliverability controls
Add seed inbox-placement testing with admin management, placement result polling, and seed mailbox persistence.

Add pre-send email verification, invalid-recipient skipping, warmup-health campaign gating, and RFC 8058 one-click unsubscribe headers/endpoints.
2026-06-03 16:47:53 +02:00
Matthew Meszaros b0b712a43f feat: refine warmup content admin
Treat warmup content as a shared library in settings and admin tables, and realign the conversation pick index with segment-based selection.

Add generation job details and fix warmup placement displays so backend percentages and provider counts render correctly.
2026-06-03 11:32:09 +02:00
Matthew Meszaros ff7ae430f1 feat: simplify warmup worker actions
Remove the worker-side dwell timer now that delayed warmup engagement is scheduled durably by the consumer.

Keep DelaySeconds only for wire compatibility and run received warmup action batches immediately on the worker.
2026-06-03 11:31:41 +02:00
Matthew Meszaros 2009780beb feat: add warmup batch generation
Add OpenAI Batch API support for warmup content generation, including job metadata, polling, cancellation, and completed-batch ingestion.

Share the generation prompt between sync and batch modes and humanize/lint generated threads before storing them in the warmup content library.
2026-06-03 11:14:33 +02:00
Matthew Meszaros 59d253ef1d feat: harden warmup action handling
Wire warmup health webhooks in the consumer and log skipped warmup actions when a recipient mailbox has no assigned worker.

Run foldering and spam rescue immediately while keeping only low-stakes engagement signals behind the dwell delay.
2026-06-03 06:40:35 +02:00