Matthew Meszaros
|
32d2bdfb81
|
Merge pull request #324 from warmbly/feature/install-script-setup-wizard
feat: one-command self-host installer with an interactive data-control wizard
|
2026-09-04 07:12:38 -07:00 |
|
Matthew Meszaros
|
e5360713e7
|
Merge remote-tracking branch 'origin/main' into feature/install-script-setup-wizard
|
2026-09-04 06:43:12 -07:00 |
|
Matthew Meszaros
|
a7d2381120
|
Merge pull request #327 from warmbly/feat/step-composer-campaign-wide-attachments
Show the campaign's every-step attachments in the step composer
|
2026-09-04 06:42:48 -07:00 |
|
Matthew Meszaros
|
5c4f87c1aa
|
feat: list the campaign's unscoped attachments under a Sent with every step group in the step composer, so files the step really carries stop being invisible in the panel that claims to show them, and say in the confirm that removing one takes it off every step
|
2026-09-04 06:40:48 -07:00 |
|
Matthew Meszaros
|
6869676001
|
Merge pull request #323 from Skylinerffm97/fix/step-attachments-mount
Mount StepAttachments in the step composer (#307 item 3)
|
2026-09-04 06:39:51 -07:00 |
|
Matthew Meszaros
|
b0db8cc02b
|
feat: chain the backup bundle cleanup behind a successful docker compose cp so a failed copy cannot delete the only backup, and tell a pinned image install to set WARMBLY_TAG before pulling by hand
|
2026-09-04 06:35:04 -07:00 |
|
Matthew Meszaros
|
af9e852314
|
Merge branch 'main' into fix/step-attachments-mount
|
2026-09-04 06:34:53 -07:00 |
|
Matthew Meszaros
|
3156758c9f
|
Merge pull request #325 from warmbly/fix/step-scoped-attachments
Send only the attachments a step actually carries, and org-scope the attachment routes
|
2026-09-04 06:34:45 -07:00 |
|
Matthew Meszaros
|
9a2184fda7
|
Merge remote-tracking branch 'origin/main' into fix/step-scoped-attachments
|
2026-09-04 06:28:26 -07:00 |
|
Matthew Meszaros
|
04689a8bfc
|
feat: mark step_id required on the CampaignAttachment schema, since the attachment response always carries the key and serialises a campaign-wide file's as null, so a generated client that treats it as optional loses the difference between an unscoped file and one it forgot to read
|
2026-09-04 06:28:26 -07:00 |
|
Matthew Meszaros
|
77058a2cb4
|
feat: address the review on the installer branch by keeping the database password out of pg_dump's argv, excluding backup bundles from the blob root they are written into, tolerating blobs that change or vanish mid-archive, making the instance-settings bootstrap a single atomic insert, and validating the release tag before it is written into .env
|
2026-09-04 06:24:05 -07:00 |
|
Matthew Meszaros
|
2a820ed9f9
|
Merge pull request #322 from Skylinerffm97/fix/create-schedule-windows
Persist schedule_windows on POST /campaigns (#307 item 5)
|
2026-09-04 06:23:17 -07:00 |
|
Matthew Meszaros
|
fb868dfe40
|
feat: delete the storage objects of a step's attachments when the step is deleted, since the attachment rows cascade away with the sequence and left their bytes counted against the organization's storage quota with no row left to reach them
|
2026-09-04 06:20:26 -07:00 |
|
Matthew Meszaros
|
a54774c0a5
|
feat: install the attachment upload's body cap before the first form field is read, since reading step_id parses the whole multipart body and left the MaxBytesReader that followed it with nothing to limit
|
2026-09-04 06:19:29 -07:00 |
|
Matthew Meszaros
|
85f3dad215
|
feat: send the files a step actually carries by honouring campaign_attachments.sequence_id in the send, test-send and preview paths instead of attaching every campaign file to every step, count them per step in the preflight content score, and refuse an upload naming another campaign's step
|
2026-09-04 06:16:16 -07:00 |
|
Matthew Meszaros
|
05e19ffb69
|
feat: scope the campaign attachment routes to the caller's organization, so listing, uploading to or deleting from a campaign id belonging to another workspace is a 404 instead of leaking presigned download URLs, adding a file that workspace then sends, or deleting their stored objects
|
2026-09-04 06:16:16 -07:00 |
|
Matthew Meszaros
|
7314e85dfe
|
Merge branch 'main' into fix/create-schedule-windows
|
2026-09-04 06:08:05 -07:00 |
|
Matthew Meszaros
|
42c3000383
|
feat: verify the backup bundle's recorded dump digest before warmblyctl restore empties the target schema, so a truncated bundle is refused instead of leaving the instance with neither its own data nor the bundle's
|
2026-09-04 05:56:12 -07:00 |
|
Matthew Meszaros
|
f042e307e5
|
feat: rewrite the installer's three A && B || C constructs as guard clauses so shellcheck's SC2015 is satisfied on the CI runner's version, and print the shellcheck version in check-installer.sh
|
2026-09-04 05:53:16 -07:00 |
|
Matthew Meszaros
|
d68bbcd2ab
|
feat: add a one-command self-host installer at warmbly.com/install.sh with an interactive data-control wizard, give docker-compose.yml image keys and per-store volume variables, add an image-mode updater, move engagement/form/audit retention into instance settings, and add warmblyctl backup/restore
|
2026-09-04 05:49:54 -07:00 |
|
Matthew Meszaros
|
2f3693f5b2
|
Merge pull request #320 from warmbly/fix/issue-316-stale-list-when-socket-down
Stop the dashboard showing stale campaign counts and a permanent "Slow connection" (#316, #319)
|
2026-09-04 04:11:06 -07:00 |
|
Matthew Meszaros
|
7fe7b7c8e9
|
feat: scope the collaboration guide's offline claim to the data that is actually refetched, since live events are never replayed and presence and cursors resume from current state rather than backfilling what was missed
|
2026-09-04 04:07:44 -07:00 |
|
Matthew Meszaros
|
ebc6de1f81
|
feat: refetch the campaigns list on a slow cycle while the realtime socket is not connected, so send counts kept current by live invalidation cannot sit on their five-minute cache with no event coming to refresh them, and document what the header's connection dot means and what still refreshes while it is down
|
2026-09-04 04:03:01 -07:00 |
|
Matthew Meszaros
|
02c8d8ec27
|
feat: read the header's connection quality from the heartbeat roundtrip the socket provider already measures instead of an interval that compared itself against its own last tick and so reported a healthy socket as a slow one on almost every pass
|
2026-09-04 04:03:01 -07:00 |
|
Skylinerffm97
|
16d4a13810
|
feat: mount StepAttachments under the step composer in SequenceView for email steps so per-step attachments can be seen, uploaded and removed from the dashboard, and describe per-step attachments in the sequences guide (issue #307 item 3)
|
2026-09-04 12:59:19 +02:00 |
|
Skylinerffm97
|
1749d5c48e
|
feat: persist schedule_windows on POST /campaigns by adding the field to models.CreateCampaign, validating it with CampaignScheduleWindows before the transaction and writing it in the create INSERT, with a unit test for rejected windows, a live repository test for the round trip and the create field table in the campaigns API reference (issue #307 item 5)
|
2026-09-04 12:58:09 +02:00 |
|
Matthew Meszaros
|
c894d4e355
|
Merge pull request #315 from warmbly/fix/issue-307-test-send-preview-from-name
Verify a campaign before launch: working test sends, a preview that renders the real thing, live sender name and signature spacing (#307)
|
2026-09-04 03:42:21 -07:00 |
|
Matthew Meszaros
|
483d6c2fe7
|
Merge remote-tracking branch 'origin/main' into fix/issue-307-test-send-preview-from-name
|
2026-09-04 03:34:35 -07:00 |
|
Matthew Meszaros
|
ce85fd6188
|
feat: clear the rendered step preview alongside the contact and mailbox picks when the editor changes campaign, so the panel cannot keep showing the previous campaign's sender and attachments while the new render is in flight
|
2026-09-04 03:27:20 -07:00 |
|
Matthew Meszaros
|
43297882f1
|
feat: clear the step preview's contact and mailbox picks when the editor is pointed at another campaign or at none, and send the contact and account identifiers only alongside the campaign they belong to, so a preview can never carry a selection made for a different campaign
|
2026-09-04 03:19:54 -07:00 |
|
Matthew Meszaros
|
068b34751b
|
Merge pull request #312 from warmbly/fix/campaign-daily-budget-deferrals
Campaign scheduler: count only real sends against the daily budget and defer at cap instead of pausing (#306)
|
2026-09-04 03:13:50 -07:00 |
|
Matthew Meszaros
|
915390f42a
|
feat: match the closing body tag case-insensitively when placing the mailbox signature so a pasted document written with </BODY> still gets it inside the body, drop a step preview response whose request has been superseded so an out-of-order reply cannot repaint stale copy, and keep pulling mailbox pages in the preview sender picker while an enabled campaign sender is still unaccounted for
|
2026-09-04 03:11:53 -07:00 |
|
Matthew Meszaros
|
64e6e3a502
|
Merge remote-tracking branch 'origin/main' into fix/campaign-daily-budget-deferrals
|
2026-09-04 03:06:45 -07:00 |
|
Matthew Meszaros
|
14827e5123
|
Merge pull request #311 from warmbly/fix/contact-timeline-opaque-cursor
Contact timeline: opaque (at, source, id) cursor with a tie-break in every source
|
2026-09-04 03:05:49 -07:00 |
|
Matthew Meszaros
|
de33b03891
|
feat: give the HTML mailbox signature its own block with a top margin instead of a hard double line break that stacked against the body's trailing margin and rendered as two to three blank lines in Apple Mail and Outlook, insert it inside the document when the body carries a closing body tag as the tracking pixel and opt-out footer already do, and say so in the mailboxes guide
|
2026-09-04 03:01:19 -07:00 |
|
Matthew Meszaros
|
2a19bf0519
|
Merge remote-tracking branch 'origin/main' into fix/campaign-daily-budget-deferrals
|
2026-09-04 02:59:01 -07:00 |
|
Matthew Meszaros
|
5c9d365163
|
feat: pick a closed-hours mailbox that stays closed for the next ten minutes so the scheduling pass cannot run after it opens, and assert the mixed-pool deferral lands on the reopening from both sides instead of accepting any earlier time
|
2026-09-04 02:59:00 -07:00 |
|
Matthew Meszaros
|
997aa2c748
|
Merge remote-tracking branch 'origin/main' into fix/issue-307-test-send-preview-from-name
|
2026-09-04 02:58:40 -07:00 |
|
Matthew Meszaros
|
aa55b31422
|
feat: give the campaign step preview a contact and mailbox picker so it renders for a real lead with that sender's signature, the opt-out footer and the attachment list, add a Send test action that mails the saved step through the chosen mailbox, and document both in the sequences guide
|
2026-09-04 02:58:36 -07:00 |
|
Matthew Meszaros
|
8ce331a7ac
|
feat: fix the campaign test-email endpoint answering 404 for every caller by scoping its campaign lookup to the organization instead of the user, let it send from any mailbox of the organization and render a real contact through a new contact_id, attach the campaign's files, and extend the template preview with contact_id, campaign_id and account_id so it applies the signature, opt-out footer and plain-text rule the send path does
|
2026-09-04 02:58:36 -07:00 |
|
Matthew Meszaros
|
f844c14804
|
feat: carry the mailbox display name in the emsg body blob of every send so a renamed sender reaches the worker on its next message instead of waiting for an inactive-active toggle, read it into the From header of the Gmail, Graph and SMTP clients with the name cached at load time as the fallback, and say so in the mailboxes guide
|
2026-09-04 02:58:36 -07:00 |
|
Matthew Meszaros
|
eb85224cc8
|
Merge remote-tracking branch 'origin/main' into fix/contact-timeline-opaque-cursor
|
2026-09-04 02:57:59 -07:00 |
|
Matthew Meszaros
|
293226101a
|
Merge pull request #313 from warmbly/fix/campaign-linked-segment-display
Show linked segments on the campaign Leads tab, explain empty lists, add export to leads and segments
|
2026-09-03 20:54:15 -07:00 |
|
Matthew Meszaros
|
850ff2b6a2
|
feat: lock the campaign row for update while replacing its linked segments so two concurrent replacements cannot commit the union of their sets, and return the status read under that lock from ReplaceForCampaign so the wake or restart reaction no longer depends on a post-commit link lookup that a concurrent detach could empty
|
2026-09-03 20:46:27 -07:00 |
|
Matthew Meszaros
|
ab0c756aa2
|
feat: show a campaign's linked segments on the Leads tab as chips with live enrolled and held-out counts that filter the list, explain an empty list caused by an empty segment or hand-removed members and add them back in one click, add a scope-aware Export to campaign leads and segment members with a campaign-ready preset that carries lead status and engagement, write the links and the enrolment of PUT /campaigns/:id/segments in one transaction so a failed enrolment changes nothing instead of answering added 0, restart a completed campaign when a one-shot enrol adds leads, clear the manual-removal record when a contact is added by hand, count every link's members in one scan, audit sweep enrolments so open Leads tabs refresh, and document it in the campaigns and segments guides and the API reference
|
2026-09-03 20:38:27 -07:00 |
|
Matthew Meszaros
|
8aaf9e8c8c
|
feat: say in the contacts API reference and the OpenAPI 400 description that a before value on the contact timeline that is not an RFC 3339 timestamp is rejected with a 400 rather than accepted
|
2026-09-03 20:28:51 -07:00 |
|
Matthew Meszaros
|
4bc971eecb
|
feat: resume a campaign whose pool mixes capped and hours-closed mailboxes at the earlier of tomorrow and the closed mailbox's reopening, log the daily cap only when every usable mailbox is capped, and add the mixed-pool live regression
|
2026-09-03 20:26:21 -07:00 |
|
Matthew Meszaros
|
2f32b1b8c3
|
feat: bring the ContactTimelineEvent OpenAPI schema up to the real event shape with the lifecycle, form_submitted and page_hit types and the machine, link, origin, category, form and page_hit fields backed by new ContactLinkClick, EngagementOrigin and WebsitePageHit schemas, and list form_submitted and page_hit with their payloads in the contacts API reference
|
2026-09-03 20:21:42 -07:00 |
|
Matthew Meszaros
|
0981635c3a
|
feat: reject a contact timeline cursor whose source rank names no merged table with a 400 in the handler through ContactTimelineSource.Valid, since rank zero is reserved for the legacy before bound and a rank past the last source would re-admit the events at the cursor's instant
|
2026-09-03 20:21:42 -07:00 |
|
Matthew Meszaros
|
83b0a5ede3
|
feat: add the cursor query parameter to the contact timeline operation in the OpenAPI spec, mark before as deprecated, describe the invalid cursor and limit 400s, and reference the shared Pagination schema from ContactTimelineResult
|
2026-09-03 20:19:16 -07:00 |
|