Matthew Meszaros
|
23d7bfa166
|
Merge pull request #289 from warmbly/feature/marketing-hero-visual-backdrop
feat: index page visuals 1/1 with the dashboard, hero pricing line, Discord links (#268)
|
2026-09-02 06:15:05 -07:00 |
|
Matthew Meszaros
|
454c1391c6
|
feat: pause the feature carousel's reduced-motion timer while the frame is hovered or off screen and resume it with the remaining hold time, so a slide never advances right after release the way the paused fill animation never does
|
2026-09-02 06:11:45 -07:00 |
|
Matthew Meszaros
|
37d48baf0b
|
feat: address the CodeRabbit review on the index visuals: the app shells and feature screens are aria-hidden pictures whose buttons, inputs and links leave the tab order and the shell's fake Search control is a span, the CRM board counts and sums open deals per stage and hides the open row at zero like the app's pg_crm summary so the Won column no longer reads 42,000 open, the dashboard stat strip totals agree with the at-risk, failing and paused rows beneath it, the story carousel advances on a timer under reduced motion where no fill animation ends, the forms sparkline gradients are keyed by row index instead of name length so two 17-character names no longer share an id, the unibox reply controls reveal on hover at md and up, the hosted form mock uses paragraphs instead of h1/h2 so it stays out of the page outline, and four stylelint findings in global.css are cleared
|
2026-09-02 06:04:11 -07:00 |
|
Matthew Meszaros
|
1d626496af
|
feat: rebuild the index page product visuals 1/1 with the dashboard for issue #268: every feature section renders the real app shell (AppShellMock with the live sidebar counts) inside a browser window hung from a corner, a shared demo cursor engine (lib/cursor.ts + DemoCursor) walks element anchors instead of guessed coordinates, the campaign builder opens its step editor as the 320px spring side sheet and portals the ⌘J caret assistant over the whole window, analytics, integrations, developers and CRM use a new wide FeatureSection mode that fits the full 1280px window by width so centred dialogs read as centred, forms, form builder and hosted form mocks replace the AI assistant mock, the hero gets a grain backdrop (@paper-design/shaders) and a three-point free to self-host / 10 mailboxes / no card line instead of the long pricing paragraph, the How we differ section is removed, and a Discord glyph linking to dc.warmbly.com is added to the header, mobile menu and footer
|
2026-09-02 05:53:04 -07:00 |
|
Matthew Meszaros
|
f200c8cf0a
|
Merge pull request #287 from warmbly/feature/public-forms
feat: forms v2 with themes, layouts, pages, personalized links, funnel analytics, campaign integration and a custom forms domain
|
2026-09-01 09:55:24 -07:00 |
|
Matthew Meszaros
|
53b932292b
|
fix: address review findings on forms v2: the list aggregates query passed a Go int into a text concatenation so pgx could not encode it and starts, identified and the trend sparkline were always empty behind a silent degrade; the forms tables sat above campaigns in the org transfer order despite carrying a campaign_id foreign key, which would fail a full import; an imported forms domain inherited the destination workspace's stale verified flag; a form whose creator was offboarded stopped creating contacts because created_by is ON DELETE SET NULL, now falling back to the workspace owner; the forms mirror check never ran when only the web-side copy changed; and the bare metal guide asked for five DNS names while certbot requested a sixth
|
2026-09-01 09:49:06 -07:00 |
|
Matthew Meszaros
|
290f1f00aa
|
Merge remote-tracking branch 'origin/main' into feature/public-forms
# Conflicts:
# cmd/backend/main.go
# docs/content/docs/guides/workspace-export-import.mdx
|
2026-09-01 09:29:53 -07:00 |
|
Matthew Meszaros
|
6fb5c3ca08
|
feat: connect forms to campaigns end to end: a toolbar button and {{ menu that insert a per-recipient {{form_link:id}} chip resolved at send time, a Forms panel on the campaign overview reporting links sent, opened, started, submitted and the resulting rate per form, GET /campaigns/:id/forms behind the campaign read gates, and campaign attribution carried through every form submission, funnel event and analytics breakdown
|
2026-09-01 09:27:33 -07:00 |
|
Matthew Meszaros
|
05d74dbe9f
|
feat: forms v2, a full redesign of the hosted form and its builder: eight one-click themes, card/wide/split layouts with a brand cover panel, classic paged and Typeform-style focus modes split on a new page_break block, logo/cover/background uploads with size, fit and veil controls, an optional header bar that can span the page or sit with the form, a real HSV colour picker and font preview, per-contact personalized links that prefill and attribute without email verification, a render-token gate so the form JSON cannot be scraped without loading the page, funnel analytics with per-page drop-off and identified visitors, a leads-style forms list and responses table, and an organization custom forms domain verified by CNAME with hourly re-checks
|
2026-09-01 09:27:28 -07:00 |
|
Matthew Meszaros
|
84815381a9
|
fix: route the orphaned website tracking settings page, which the settings nav linked to but main.tsx never registered, and give every unmapped route a document title so forms, segments, categories, oauth apps and six settings pages stop rendering the literal Page not found in the browser tab
|
2026-09-01 09:26:40 -07:00 |
|
Matthew Meszaros
|
62e8f26d10
|
Merge pull request #284 from warmbly/fix/issue-277
feat: live segment-to-campaign linking, lead removal, and import targeting (issue #277)
|
2026-09-01 08:19:43 -07:00 |
|
Matthew Meszaros
|
271b4b1625
|
feat: coalesce org segment syncs instead of dropping them, so an import's pinned contacts reach their linked campaigns in the same request: SyncOrgLinkedCampaigns now records a follow-up when a request lands while a pass is running (ImportCommit writes segment membership after its chunked Add already started one, so that pass read the old membership and left the contacts to the 2-minute sweep), the per-org state moves from a sync.Map to a mutex-guarded map so running, queued and released are one atomic transition, and two hermetic tests cover the mid-pass coalesce and the idle re-run
|
2026-09-01 04:19:59 -07:00 |
|
Matthew Meszaros
|
4385f6ec02
|
feat: merge main and renumber the segment migrations after PR #283 took 000114 and 000115: campaign_segments becomes 000116 and campaign_lead_removals becomes 000117, since unibox_folders and mailbox_security_mode are already recorded in deployments' schema_migrations and ours are not, restoring a clean 000001-000117 sequence that check-migrations and golang-migrate both accept
|
2026-09-01 04:06:13 -07:00 |
|
Matthew Meszaros
|
128e314103
|
Merge remote-tracking branch 'origin/main' into fix/issue-277
|
2026-09-01 04:03:37 -07:00 |
|
Matthew Meszaros
|
33011468fb
|
feat: rebuild the contacts bulk edit panel: a Will apply strip above the footer lists every queued change as a chip you can take back one at a time so a bulk write is never applied blind, the header names the segment or campaign the selection came from, add and remove pickers sit side by side under one heading behind small tinted glyphs instead of shouting green and red labels, the locally duplicated campaign picker is replaced by the shared CampaignMultiPicker so chips match the rest of the app, custom-field rows put key and value on one line with the type hint inline and mark a half-filled operation as skipped instead of sending it, and Escape now closes an open picker or the confirm before the drawer (with data-floating added to CategoryPicker)
|
2026-09-01 03:55:10 -07:00 |
|
Matthew Meszaros
|
d6ddf1f170
|
feat: fix implicit-TLS SMTP on 465 and IMAP STARTTLS on 143 behind a stored per-mailbox security mode that accepts any port, stop worker ID churn orphaning mailbox assignments via flock-claimed persistent worker ids, give the unibox a standard mail-folder sidebar (inbox/sent/drafts/archive/spam/trash) backed by a provider-derived folder column, and expose the AI tool registry over REST for non-MCP function-calling agents (#283)
|
2026-09-01 03:53:19 -07:00 |
|
Matthew Meszaros
|
c2b0f93583
|
feat: close the last silent-success window on the segment pin: the in-transaction segment_members insert now compares RowsAffected against the deduplicated segment list and rolls the create back with a 400 when a segment was deleted between the service's existence check and the write, plus a live repository test that a contact created with a segment is pinned as an include override while a sibling naming none stays out, and that a create naming a segment the organization does not have fails and leaves no contact behind
|
2026-09-01 03:15:08 -07:00 |
|
Matthew Meszaros
|
103145e970
|
feat: address the CodeRabbit review on the segment pin and campaign selection bar: the include override for a contact created inside a segment is now written inside the contact repository's own transaction (parsed and deduped alongside campaigns and categories, org-scoped, ON CONFLICT upsert) so a failed override write rolls the contact back instead of answering 200 with a membership that never happened, the service keeps only the pre-write existence check that turns an unknown segment into a 400, and the leads selection bar drops its bulk Delete inside a campaign so the destructive bulk action matches the row action and cannot delete workspace contacts from a Leads tab
|
2026-09-01 03:07:39 -07:00 |
|
Matthew Meszaros
|
55307b0ad9
|
feat: fix the segment dialog UI and make a contact created inside a segment join it (issue #285): the add-to-campaign picker now shows a humanised, colour-toned campaign status instead of the raw PAUSED_NO_ACCOUNTS enum, its footer wraps instead of clipping the hint mid-sentence and the Add leads button no longer breaks across two lines, campaign status labels move to a shared components/app/campaigns/status module, the Segments, Categories and Segment pages plus every unmapped settings and onboarding route get a document title so they stop reading Page not found, and POST /contacts takes a segments array that pins the new contacts in as include overrides (validated before the write, best-effort after it) which the New contact dialog sends when opened from a segment page
|
2026-09-01 02:57:30 -07:00 |
|
Matthew Meszaros
|
7b6830daa5
|
feat: say segments out loud in the API scope catalog: the READ_CONTACTS and WRITE_CONTACTS descriptions served to the API key dialog (and the docs permission table) now name segments, since segment CRUD, previews, member overrides and enrolment ride on the contact scopes and the picker never said so
|
2026-09-01 01:32:56 -07:00 |
|
Matthew Meszaros
|
5e87b1bbbf
|
Merge remote-tracking branch 'origin/main' into feature/public-forms
|
2026-09-01 01:17:54 -07:00 |
|
Matthew Meszaros
|
60c9e316d9
|
feat: hosted lead-capture forms end to end: drag-and-drop builder with field settings, design panel, embed/share and submissions tabs in the dashboard, a public TanStack form app (forms/) served by the new standalone forms service (cmd/forms + internal/formserver) on FORMS_DOMAIN with per-form frame-ancestors CSP, honeypot/fill-time/Turnstile/per-IP submit protection and a same-origin JSON API proxying the backend internal API, form submissions creating contacts with categories and campaign enrollment plus realtime, audit, webhook and org-transfer coverage, migration 000114, seed forms, CI jobs, Dockerfile, systemd/nginx/compose manifests and docs
|
2026-09-01 01:17:51 -07:00 |
|
Matthew Meszaros
|
8db032a656
|
feat: address review on segment-campaign linking: a campaign_lead_removals table (migration 000115, orgtransfer-registered) records hand-removed leads so the automatic segment sync never re-adds them while a manual add or the one-shot enrol clears the record, PUT /campaigns/:id/segments rejects an omitted segment_ids so {} cannot detach everything, rows.Err checks on the four new link queries so a truncated read cannot commit as success, write-path enrolment syncs detached from the request goroutine with a per-org in-flight dedupe, per-campaign 30s deadlines in the sweep instead of one shared budget, and an error-with-retry state in the linked-segments dialog
|
2026-09-01 00:33:42 -07:00 |
|
Matthew Meszaros
|
66a105fb9f
|
feat: make segments a live campaign audience and round out lead management (issue #277): a campaign_segments link table with GET/PUT /campaigns/:id/segments (max 20, replace semantics), immediate enrolment of linked-segment members as leads plus targeted re-syncs on contact writes, segment edits, pin-ins and imports and a 2-minute backend sweep for drift, waking active campaigns and restarting completed ones through the full launch checks; a Segments manager dialog and toolbar button on the campaign Leads tab; Remove from campaign as the row action and a selection-bar bulk action so leads can leave a campaign without deleting the contact; campaign and segment pickers in the CSV import wizard backed by a new segment_ids import option that pins imported rows as include overrides; a delete guard naming linked campaigns; orgtransfer registration, live repo tests and docs for all of it
|
2026-08-31 08:45:27 -07:00 |
|
Matthew Meszaros
|
ddb0e349ad
|
Merge pull request #281 from warmbly/fix/account-reverification-button-missing
Add the missing mailbox re-verification flow
|
2026-08-31 06:34:45 -07:00 |
|
Matthew Meszaros
|
773a3ecaf2
|
Merge remote-tracking branch 'origin/main' into fix/account-reverification-button-missing
|
2026-08-31 06:26:40 -07:00 |
|
Matthew Meszaros
|
c2f5cc4e9e
|
feat: address review on the reconnect flow: a reauth whose repeat consent omits the refresh token now refuses (typed error) when the stored one cannot be read instead of sealing an empty string over it, and credential errors resolve only after the reactivation Update succeeds so a failed reactivation keeps the banner and its reconnect button
|
2026-08-31 06:26:39 -07:00 |
|
Matthew Meszaros
|
acec534b6b
|
feat: give the mailbox drawer's ramp-hold, lifecycle and cold-ramp notice cards top padding (px-5 py-4 like every other Overview section) so they no longer touch the section divider above them
|
2026-08-31 06:16:15 -07:00 |
|
Matthew Meszaros
|
2d0db3ef63
|
Merge pull request #282 from warmbly/fix/issue-273
Fix missing line breaks in imported messages: read unibox bodies from the key the worker writes
|
2026-08-31 06:13:57 -07:00 |
|
Matthew Meszaros
|
70ca90a3e0
|
feat: fix the reconnect reactivation 500 found in live testing: reconnectAccount now loads the row via GetByID itself because the org-scoped Get selects no user_id and the owner-scoped Update was handed an empty uuid; UpdateSMTPIMAPCredentials switches to GetByID with an explicit tenancy check, and the test stub's Get now mimics the real partial row
|
2026-08-31 05:53:12 -07:00 |
|
Matthew Meszaros
|
6918ee06b0
|
Merge remote-tracking branch 'origin/main' into fix/issue-273
|
2026-08-31 05:49:38 -07:00 |
|
Matthew Meszaros
|
846d502284
|
Merge pull request #280 from warmbly/fix/cold-email-sending-defaults
feat: make the per-mailbox daily campaign cap configurable up to 5,000/day
|
2026-08-31 05:43:40 -07:00 |
|
Matthew Meszaros
|
6ea9ecbc82
|
Merge remote-tracking branch 'origin/main' into fix/issue-273
|
2026-08-31 05:40:29 -07:00 |
|
Matthew Meszaros
|
9d9c126b76
|
feat: hyphenate the 24-hour window compound in the mailboxes guide gap-throughput note
|
2026-08-31 05:39:53 -07:00 |
|
Matthew Meszaros
|
a657da3a1d
|
Merge remote-tracking branch 'origin/main' into fix/cold-email-sending-defaults
|
2026-08-31 05:39:46 -07:00 |
|
Matthew Meszaros
|
5abfb69882
|
feat: address Greptile review on #282: re-measure useFlipPlacement/useFlipAlignment on window resize so an open popover keeps a valid side when the toolbar reflows, and trim the unibox body-key and hook comments down to their one-line invariants
|
2026-08-31 05:36:24 -07:00 |
|
Matthew Meszaros
|
c28179e61f
|
feat: raise the campaigns ramp_start/ramp_ceiling DB CHECK constraints to 5000 (migration 000113) so raised API bounds cannot 500 on the constraint, validate the effective ramp pair against stored values on partial updates, and fix the campaign/mailbox guides on the effective cap and the 600s gap throughput bound
|
2026-08-31 05:31:13 -07:00 |
|
Matthew Meszaros
|
3a8015b12e
|
Merge pull request #278 from warmbly/feature/live-panel-redesign
Redesign the sidebar LivePanel: visuals over text
|
2026-08-31 05:29:51 -07:00 |
|
Matthew Meszaros
|
896fc60f4d
|
feat: add the missing mailbox re-verification flow (issue #274): POST /emails/onboarding/oauth/reauth/:id re-runs the provider consent for an existing Gmail/Outlook mailbox (login_hint preselect, same-address check, token rewrite keeping the stored refresh token) and PUT /emails/onboarding/smtp-imap/:id replaces SMTP/IMAP credentials after live validation; both resolve the credential-class error rows and reactivate the mailbox onto its worker, the drawer's Needs attention banner gains Re-authorize and Update credentials buttons, and the mailboxes guide documents reconnecting
|
2026-08-31 05:29:35 -07:00 |
|
Matthew Meszaros
|
dfca54959f
|
Merge branch 'main' into feature/live-panel-redesign
|
2026-08-31 05:27:56 -07:00 |
|
Matthew Meszaros
|
1a991a5d7a
|
Merge pull request #279 from warmbly/feature/segment-api-crud
feat: surface the segment ID in the dashboard and docs for segment API integrators
|
2026-08-31 05:20:20 -07:00 |
|
Matthew Meszaros
|
f35d7e5037
|
feat: address CodeRabbit review on the segment ID chip: narrow the API reference sentence to endpoints that operate on an existing segment, add an aria-label and a polite sr-only status to the copy button so the copied state reaches assistive technology
|
2026-08-31 04:19:20 -07:00 |
|
Matthew Meszaros
|
1194f819d0
|
Merge remote-tracking branch 'origin/main' into feature/segment-api-crud
|
2026-08-31 04:18:44 -07:00 |
|
Matthew Meszaros
|
760cb5651c
|
feat: fix issue 273: read unibox message bodies from the key the worker actually writes (users/<owner>/emails/<mailbox>/<message>.emsg via config.StorageEndpointEmailBody) instead of the never-written emails/<owner>/<id> key, so opened messages render the full stored plain+HTML body with its line breaks instead of degrading to the collapsed one-line snippet with the truncated-message notice; thread the mailbox account id through GetBody, GetByID and the body-text search backfill, drop the dead PutBody/GetEmailKey, and in the contact activity detail stop content escaping the drawer: measured left/right alignment for the date-range popover (new useFlipAlignment hook) and wrap-anywhere on expanded detail values so long URLs cannot widen the grid past the card
|
2026-08-31 03:54:59 -07:00 |
|
Matthew Meszaros
|
d936f04973
|
Merge branch 'main' into feature/live-panel-redesign
|
2026-08-31 03:53:06 -07:00 |
|
Matthew Meszaros
|
ec1ac7080a
|
feat: derive the LivePanel capacity denominator from the sum of each mailbox's configured campaign_limit (falling back to the 50/day default) instead of a flat mailbox count times 50, so tuned per-mailbox limits move the meter
|
2026-08-31 03:52:38 -07:00 |
|
Matthew Meszaros
|
d7a17a0149
|
feat: make the per-mailbox daily campaign cap configurable up to 5000 (issue #276): raise campaign_limit, campaign daily_limit and ramp start/ceiling validation to config.LimitMax, warn in the dashboard above 100/day, and update aitools, zapier and docs copy to match
|
2026-08-31 03:50:36 -07:00 |
|
Matthew Meszaros
|
55156a8964
|
feat: surface the segment ID for API integrators: a click-to-copy ID chip in the segment page header, a Copy segment ID entry in the segments list row menu, a Segments in the API section in the segments guide pointing at the CRUD, members and enrolment endpoints, and a note in the API reference on where the dashboard shows the ID
|
2026-08-31 03:47:12 -07:00 |
|
Matthew Meszaros
|
3fc4fd0bb0
|
feat: redesign the sidebar LivePanel around visuals instead of text rows: a hero sent-today number that scrubs day-by-day when hovering the new smooth 14-day area sparkline (replacing the bar strip), a sky capacity meter for today vs the derived daily cap, icon glance chips for mailboxes, active senders and unread inbox, a zero-filled continuous trend axis so quiet days are not squeezed out, and no LIVE status row since realtime updates already read as live
|
2026-08-31 03:41:27 -07:00 |
|
Matthew Meszaros
|
f11115b642
|
Add greptile config.json to stop automatic pr reviews
|
2026-08-31 12:12:14 +02:00 |
|