Commit Graph

104 Commits

Author SHA1 Message Date
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
Matthew Meszaros 62da3c3e3d feat: add organization teams API 2026-06-07 07:03:49 +02:00
Matthew Meszaros f4c738de06 feat: add customizable CRM task types 2026-06-07 06:18:01 +02:00
Matthew Meszaros 625b10a5c8 feat: add contact email lookup endpoint 2026-06-07 06:17:24 +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 86d7d1f7d3 feat: expose unibox thread label api
Add read and replace endpoints for conversation labels, wire service methods, and route sender/category filtering through the thread-collapsed search path.
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 49f1b28bd1 feat: add campaign lead order api
Wire campaign lead ordering through handlers, service methods, and campaign routes.
2026-06-05 15:44:26 +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 d6f055da19 feat: add lead sync backend 2026-06-04 11:49:55 +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 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 24422ed427 feat: add campaign template scoring
Add an advisory content score endpoint that reuses warmup linting heuristics for campaign templates.

Surface the score in the sequence editor so users can check subject and body deliverability before sending.
2026-06-03 06:27:07 +02:00
Matthew Meszaros e81f6d54cf feat: add mailbox deliverability checks
Add an email auth-check endpoint and dashboard panel for SPF, DKIM, and DMARC validation.

Expose warmup content segment editing on mailboxes so segment-aware warmup content can be selected intentionally.
2026-06-03 06:26:23 +02:00
Matthew Meszaros 15ef9d4994 feat: add warmup content controls
Add warmup content generation and admin review surfaces, plus mailbox warmup appeal/status APIs.

Track warmup engagement and tampering signals so unsafe mailboxes can be handled by the warmup flow.
2026-06-03 05:05:53 +02:00
Matthew Meszaros eac99628bb feat: enforce worker pool assignment safety
Reserve dedicated worker allocation for the control plane, auto-promote spare capacity when needed, and keep risky or quarantined mailboxes off clean shared workers.
2026-06-02 16:38:49 +02:00
Matthew Meszaros bc435747ea feat: expand admin management queries
Add richer backend models, handlers, services, and repository queries for admin campaigns, discounts, outreach, organizations, limit requests, and provisioning surfaces.
2026-06-02 15:54:29 +02:00
Matthew Meszaros 2430095197 feat: move infrastructure state off dynamodb
Remove DynamoDB-backed storage paths, add Postgres/HTTP repositories for mailbox state maps, wire the internal message-map API, and add provisioning runner/migration plumbing.
2026-06-02 15:54:12 +02:00
Matthew Meszaros 3837cd3898 feat: bound auth login network waits
Add request and mail-delivery timeouts around auth flows so login requests cannot hang indefinitely when notification delivery stalls.

Allow the local admin dev origin through default CORS and update context-aware lint fixes so the repository lint gate passes.
2026-06-01 16:56:24 +02:00
Matthew Meszaros 559d05a458 feat: use dot-separated event-bus topic names for Kafka compatibility 2026-06-01 12:49:24 +02:00
Matthew Meszaros a35ca01a6c feat: fix warmup lifecycle audit logging
Use the organization-scoped audit helper after merging the updated audit service signature from main.
2026-06-01 11:41:22 +02:00
Matthew Meszaros 83eae84d49 feat: merge main into warmup branch
Resolve the main-branch conflict in realtime event publishing by keeping both warmup account-health and audit-created events. Renumber the warmup migrations after the current main migration tail.
2026-06-01 11:36:04 +02:00
Matthew Meszaros a04d7450bc feat: guard warmup reconciliation by access
Make the warmup task reconciler re-check account state and org warmup access before scheduling replacement tasks. Remove pool membership for accounts whose org can no longer use warmup to avoid repeated no-access task churn.
2026-06-01 11:19:44 +02:00
Matthew Meszaros fc18b8e470 Merge pull request #23 from warmbly/feature/passkey-login-experience-2 2026-06-01 09:15:21 +02:00
Matthew Meszaros 218af13dd9 feat: add session management
Add authenticated session listing and revocation APIs, track the auth provider on sessions, and expose active session controls in account security settings.
2026-06-01 05:53:49 +02:00
Matthew Meszaros e237986f46 feat: merge main into integrations oauth 2026-06-01 04:49:50 +02:00
Matthew Meszaros 4500aeba0f feat: add integration oauth connections
Adds OAuth-backed integration connection management across the API, repository, event dispatch, migrations, docs, and dashboard UI.

Includes realtime invalidation and small dashboard type compatibility fixes needed for the web typecheck gate.
2026-06-01 04:25:14 +02:00
Matthew Meszaros e0ced97ba1 feat: add organization audit trail
Move audit logs into org-scoped Postgres storage, wire audit events across backend handlers, and surface actor details in the dashboard activity log.

Add realtime audit invalidation and retention pruning so the trail stays current and bounded.
2026-06-01 04:23:00 +02:00
Matthew Meszaros 87f9bf58b0 feat: add Safari-ready passkey login
Add passkey enrollment and login wiring, including a Safari-safe explicit login path that prefetches the WebAuthn challenge before the click and calls the credential ceremony immediately from the user gesture.
2026-06-01 03:09:17 +02:00
Matthew Meszaros 545dcea940 feat: show scheduled replies in threads
Add a thread_id filter for scheduled Unibox sends and expose a per-thread hook for the dashboard.

Render queued sends inline in ThreadView with cancellation, refreshing the thread, scheduled list, and overview caches after cancel.
2026-05-31 05:19:39 +00:00
Matthew Meszaros 7b5a87d1d1 feat: add unibox scheduled send backend
Add Unibox overview, snooze, and scheduled-send endpoints with task repository support, queue caps, execution-time guards, and snooze persistence.
2026-05-31 04:26:26 +00:00
Matthew Meszaros 4663333d2c feat: update billing and email settings 2026-05-30 15:45:10 +00:00
Matthew Meszaros a227938778 feat: seed unibox trial fixtures 2026-05-30 14:06:36 +00:00
Matthew Meszaros d08c984c42 feat: snapshot current dashboard changes 2026-05-30 13:56:27 +00:00
Matthew Meszaros 44c837d8ac Merge branch 'main' into feature/dashboard-plans
# Conflicts:
#	AGENTS.md
2026-05-30 09:49:12 +00:00
Matthew Meszaros b168f4d466 feat: simplify worker installer route 2026-05-30 09:37:26 +00:00
Matthew Meszaros d8a546eca5 feat: add worker enrollment install 2026-05-30 05:10:27 +00:00
Matthew Meszaros cb0c2b4fac feat: harden webhook endpoints 2026-05-30 04:33:43 +00:00
Matthew Meszaros 878e8d921e feat: enforce api key email scopes 2026-05-30 04:28:25 +00:00
Matthew Meszaros 67bbd72777 feat: harden api permission gates 2026-05-30 04:24:41 +00:00
Matthew Meszaros ff763c4483 feat: add role and team-size onboarding questions and rework site SEO me 2026-05-29 14:47:16 +00:00
Matthew Meszaros 6766031cc5 feat: add discount code support for checkout and plan changes 2026-05-29 05:49:19 +00:00
Matthew Meszaros e7ef328b2d Merge pull request #18 from warmbly/feature/admin-management
feat: admin management surface with overrides, ban scope, and throttles
2026-05-29 05:01:00 +02:00
Matt 3ffa416e40 feat(admin): mailboxes admin (cross-org triage)
Adds GET /admin/mailboxes — paginated platform-wide mailbox list that
joins email_accounts → users → organizations so the table answers
"whose mailbox is this and where does it live" without N+1 fetches.

Search covers mailbox email / owner email / org name; status filter
defaults to active so the active surface shows first ("inactive" /
"all" both available). Provider filter speeds up "show me every Gmail
mailbox" investigations. Cursor pagination matches the rest of the
admin lists.

Frontend page surfaces warmup-on/off, send budget, and last-sync time
with red-when-never / amber-when-stale-over-24h tone so an
investigator can spot dead mailboxes fast. Mailbox email links into
the owning user's detail page; org name links into the workspace
admin so the pivot path stays one click in either direction.

Gated on AdminPermViewUsers since mailbox triage is tightly coupled to
user/org context today; a dedicated bit can be carved later if
mailbox-specific actions land.
2026-05-28 12:38:08 +02:00
Matt bd6a045751 feat(admin): outreach composer (platform mailer + reply-to + audit log)
Adds a dedicated admin path for sending platform email — distinct from
the campaign emailsend service (which sends through customer mailboxes)
so the two abuse surfaces never share code paths.

Schema (000047) adds admin_outreach_messages: every send is recorded
with sent_by, the resolved to_email, the optional reply_to, subject,
body, and a queued → sent/failed status. Failed sends keep their error
column populated for the audit log.

Extends notify.EmailNotificationService with SendOutreach so both
backends (SES + SMTP) support custom Reply-To: SES via the native
ReplyToAddresses field, SMTP via a forged Reply-To header. The
existing transactional Send() remains unchanged so no other caller is
affected.

Service (internal/app/adminoutreach) resolves recipients three ways:
to_email (raw address), to_user_id (sends to the user's account email),
or to_org_id (sends to the workspace owner). Persist-then-send-then-
mark ensures the audit row exists even if the mailer hangs, and
mark-failed captures the error string verbatim.

Routes:
  POST /admin/outreach            manage_organizations
  GET  /admin/outreach            view_organizations

Admin UI: composer with recipient mode picker (email / user_id / org_id),
configurable Reply-To (defaults to support@warmbly.com so customers can
actually reply), subject + HTML body editor, and an outreach log below
showing the last 50 sends with status badges and error details. Sidebar
entry under Accounts (Send icon).
2026-05-28 12:25:18 +02:00
Matt e6753f7c24 feat(limits): limit-increase request workflow (backend)
Wire the customer self-serve path for asking "please give me more
mailboxes / campaigns / contacts." Migration 000046 adds
limit_increase_requests with a partial unique index ensuring only one
pending request per (org, field) so the queue can't be spammed, plus
a CHECK requiring requested > current_effective so no-op rows never
reach an admin.

Service layer:
  - SubmitLimitIncreaseRequest validates membership, rejects unknown
    fields, snapshots the user's current effective limit at submission
    time so the queue row carries the context the admin needs.
  - CancelLimitRequest lets the original submitter walk back a pending
    request; approved/rejected rows are immutable as the audit record.
  - ApproveLimitRequest stamps the row and writes the corresponding
    column on organization_limit_overrides via SetLimitOverrides —
    same write path direct admin overrides use, so granted_by and
    notes carry through and the audit log treats both flows uniformly.
  - RejectLimitRequest stamps the row with required review notes.

Routes:
  POST   /v1/organization/:orgId/limit-requests
  GET    /v1/organization/:orgId/limit-requests
  DELETE /v1/limit-requests/:id                 (submitter only)
  GET    /admin/limit-requests?status=pending
  POST   /admin/limit-requests/:id/approve
  POST   /admin/limit-requests/:id/reject

Admin approval and rejection both fire admin audit log entries with
field + requested + notes so the decision history survives any future
reorg of the request table.

UI (admin queue page + dashboard request form) plus the ToS clause
giving Warmbly the right to refuse any increase land in the next commit.
2026-05-28 12:05:32 +02:00