c896c0c919
feat: use path-style S3 addressing when an AWS endpoint override is set - virtual-hosted bucket.host requests do not resolve as buckets on LocalStack/MinIO, so every email body upload failed with NoSuchBucket in dev; real AWS (no override) keeps the default addressing
Matthew Meszaros
2026-07-11 18:37:10 +02:00
b784f76e24
feat: select worker_id in the email repository GetByID - the column was missing from the query, so every caller saw a nil WorkerID: the email sender could never publish a send (every campaign task dead-lettered with "no worker assigned") and the worker reconciler re-ran assignment on every pass, endlessly reshuffling mailboxes between workers
Matthew Meszaros
2026-07-11 18:03:20 +02:00
41a95bbe0e
feat: stabilize the sandbox against two live-run failure modes - seed and repair fixture contacts as verified (the live verifier finds no MX for .test domains and the pre-send gate then skips every campaign send) and deactivate the seeded workers the native stack never runs, whose active-but-heartbeatless rows kept winning placement and ping-ponging mailbox assignments with the dead-worker sweep
Matthew Meszaros
2026-07-11 17:57:21 +02:00
e2ccd0d75a
feat: record the new operational contracts in the agent notes and env example - CODEC_PROVIDER=json wherever workers run, CREDENTIALS_ENCRYPTION_KEY for credential sealing, the two native workers, and the make sandbox entry point
Matthew Meszaros
2026-07-11 17:31:58 +02:00
9a3551c5ea
feat: document the sandbox at /development/sandbox/ (quick start, seeded data, architecture of the simulation, env vars, demo script, troubleshooting) and refresh /development/local-development/ with dovecot, the sandbox target, and the emulator host.docker.internal callback note
Matthew Meszaros
2026-07-11 17:31:58 +02:00
48ec53d781
feat: add the sandbox seeder and simulator (cmd/sandbox, internal/sandbox) - seeds the Sunrise Labs showcase org (paid plan, six live mailboxes with sealed mailpit/dovecot credentials, active tracked campaigns, pre-verified contacts, warmup pool membership) and repairs every fixture smtp_imap account and .test contact; the simulator plays the internet by polling mailpit, appending mail into dovecot inboxes for the real IMAP sync to pick up, hitting tracking pixels and click tickets, and replying as hash-stable contact personas with correct In-Reply-To threading
Matthew Meszaros
2026-07-11 17:31:42 +02:00
f8cf7e930e
feat: native dev targets for the sandbox - make sandbox / sandbox-seed, a second native worker (worker-premium, required because paid orgs place strictly onto premium-tier workers) joined into make run, CODEC_PROVIDER=json + CREDENTIALS_ENCRYPTION_KEY + MAIL_TLS_INSECURE in the dev env, dovecot in INFRA_SVCS, and SELF_HOST defaulting to host.docker.internal so the dockerized cloud-tasks emulator can reach the host-run backend
Matthew Meszaros
2026-07-11 17:31:42 +02:00
1634d195d3
feat: fix the DEK cache path in the cipher service - a redis cache miss (every first use of an org key) returned redis.Nil as a fatal error before the KMS fallback could run, and a cache hit was fetched then discarded; now a hit returns immediately and any cache miss or error falls through to KMS
Matthew Meszaros
2026-07-11 17:31:23 +02:00
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
Matthew Meszaros
2026-07-11 17:31:23 +02:00
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
Matthew Meszaros
2026-07-11 17:31:23 +02:00
6bc2073379
feat: honor CODEC_PROVIDER=json across backend and consumer (previously worker-only) and round-trip untyped event bodies into their typed payloads in both dispatchers - the worker command/result envelopes carry any-typed bodies that Avro cannot serialize, so worker messaging only works on the JSON codec; also wires the credentials encrypter into both mains
Matthew Meszaros
2026-07-11 17:31:02 +02:00
99c1c4afa9
feat: seal SMTP/IMAP credentials at rest with a CREDENTIALS_ENCRYPTION_KEY-backed encrypter - the email repository Encrypt field was never wired anywhere, so smtp_imap accounts could never load onto workers (plaintext rows failed decode; hex-looking rows would nil-panic); adds encrypt.FromEnv and nil-guards that fail with a captured error instead
Matthew Meszaros
2026-07-11 17:30:49 +02:00
50aa0a3b3d
feat: contain panics in the per-mailbox sync loop - the worker is multi-tenant, so one mailbox hitting a bad server response must not take down every other account on the process
Matthew Meszaros
2026-07-11 17:30:20 +02:00
ee35138e37
feat: fix the generic IMAP client so it can actually connect and sync - assign the client before auth (was nil and would panic), check CONDSTORE after login where servers advertise it, request LIST-STATUS fields (folders were silently empty), and fetch 1:* instead of an empty SeqSet that panics inside go-imap
Matthew Meszaros
2026-07-11 17:30:20 +02:00
932b0bc856
feat: add the MAIL_TLS_INSECURE dev knob (netbind) so worker mail clients can skip TLS verification and, for SMTP, tolerate a server with no STARTTLS - local mailpit/dovecot only; production behavior is unchanged when the env var is unset
Matthew Meszaros
2026-07-11 17:30:20 +02:00
c8ed667aeb
feat: add a dovecot IMAP service to the infra stack and accept any-credential SMTP auth on mailpit so local mailboxes can really send and sync (sandbox mail hosting), plus CODEC_PROVIDER/CREDENTIALS_ENCRYPTION_KEY env for backend, consumer, and workers and a host-gateway alias so the cloud-tasks emulator can call a natively run backend
Matthew Meszaros
2026-07-11 17:30:03 +02:00
c3b99e598b
Merge pull request #64 from warmbly/feature/ios-dashboard-app
Matthew Meszaros
2026-07-11 10:59:59 +02:00
b379be9732
feat: qualify self.task in the openSocket admission check - with the type-checker crash worked around, Xcode 26.6 surfaces the real diagnostic: the locked closure's bare 'task' resolves to the local declared later in the function and is rejected as captured before declaration
Matthew Meszaros
2026-07-11 10:44:57 +02:00
04cf24c98d
feat: hoist the socket url resolution out of the guard condition entirely - across three CI crashes the Xcode 26.6 type checker dies whenever the async urlProvider closure property is bound or awaited inside a guard condition under StrictConcurrency, so the read, the await and the unwrap are now three plain statements
Matthew Meszaros
2026-07-11 10:41:26 +02:00
da1a6efbf8
feat: make the websocket urlProvider a non-optional closure with a nil-returning default because the Xcode 26.6 type checker also crashes on referencing an optional async closure property, not just on optional-chained calls; behavior is unchanged (nil result still schedules a reconnect)
Matthew Meszaros
2026-07-11 10:37:33 +02:00
e5f5623dc4
feat: unblock iOS CI - unwrap the websocket urlProvider in two steps because 'await urlProvider?()' crashes the Xcode 26.6 Swift type checker (works on 27), and build only the arm64 simulator slice in CI since the generic destination was doubling the compile for no extra signal
Matthew Meszaros
2026-07-11 10:34:07 +02:00
2d00ff2f69
feat: rename the Icon Composer icon to AppIcon.icon so Xcode 26's asset catalog linker finds the AppIcon.appiconset fallback (the Warmbly name built on Xcode 27 but failed LinkAssetCatalog on the macos-26 runner), and stop truncating the iOS CI build output so failures are diagnosable
Matthew Meszaros
2026-07-11 10:28:36 +02:00
1c76787f24
feat: CI gains an iOS job - a paths-gated macos-26 build of ios/Warmbly.xcodeproj against the generic iOS Simulator destination with signing disabled, selecting the newest installed Xcode (the app needs the iOS 26 SDK and the Icon Composer .icon), wired into the ci-status rollup
Matthew Meszaros
2026-07-11 10:21:46 +02:00
b4c100b7ff
feat: bump excelize to v2.11.0 so the Trivy security scan passes - v2.10.1 carries CVE-2026-54063 (unbounded row index allocation in the worksheet parser, HIGH, used by the contact import/export paths); go.sum picks up the transitive golang.org/x refreshes
Matthew Meszaros
2026-07-11 10:21:46 +02:00
956edabca3
feat: kafka no longer fails its first boot after an unclean stop - the container now waits for the stale ephemeral /brokers/ids/1 registration to expire in zookeeper before starting (with a 6s session timeout) instead of crashing on NodeExists and relying on the restart policy
Matthew Meszaros
2026-07-11 10:13:44 +02:00
56c3a2e988
feat: app icon becomes a native Icon Composer document matching the Figma branding 1:1 - Warmbly.icon layers the exact 1024px Logo frame render (sky gradient, clouds) under the plane glyph as a separate Liquid Glass vector layer positioned identically to Figma, replacing the flat AppIcon asset via ASSETCATALOG_COMPILER_APPICON_NAME
Matthew Meszaros
2026-07-11 10:13:44 +02:00
76e6ad2466
feat: iOS analytics becomes an air-hero drawer browser cover - the sky hero stays (circular hamburger and close, translucent 7d/30d/90d period chips, glass stat chips) while the web-style tab strip and card grids give way to a section drawer (overview/deliverability/warmup/accounts with issue-tinted counts) over flat native lists; Home now opens analytics and mailboxes as covers instead of pushes
Matthew Meszaros
2026-07-11 10:13:44 +02:00
de85abc47c
feat: iOS mailboxes rebuilt end to end - the list is a full-screen drawer browser cover (warmup status scopes with live counts, search pill, multi-select bulk warmup/remove, circular close) since pushing it fought the system back swipe; connecting is an air onboarding flow with real Google/Outlook brand logos, a web-style authorize step with scope bullets, working in-app OAuth via ASWebAuthenticationSession against the new warmbly:// callback, an SMTP/IMAP wizard, and a start-warmup offer on success; the detail screen becomes editable (warmup ramp steppers, sending window and weekday bitmask chips matching the Go scheduler's Sunday-first layout, sender profile, sending limits, disconnect) with debounced optimistic PATCHes
Matthew Meszaros
2026-07-11 10:13:10 +02:00
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
Matthew Meszaros
2026-07-11 10:13:10 +02:00
c12a621d06
feat: iOS workspace creation is the air onboarding flow - two sky-chrome steps (name, optional invites) creating the org at the end so it works both as the zero-workspaces gate (Sign out is the only exit, like the web) and as a cover with a circular close wired through explicit onClose bindings; the org picker becomes a sky screen with workspace rows and a New workspace path
Matthew Meszaros
2026-07-11 10:12:41 +02:00
928e1924b2
feat: iOS session handling survives network blips and explains sign-outs - token refresh only drops the session on definitive rejections (network errors rethrow and keep tokens), a missing token now kicks cleanly to sign-in instead of hanging, and the auth welcome step shows an amber session-expired notice when the app signed the user out
Matthew Meszaros
2026-07-11 10:12:41 +02:00
e6b0bd2918
feat: iOS More tab and CRM rebuilt in the flat browser language - the hub is one full-bleed list with a workspace header and cover rows, Deals/Tasks/Meetings become full drawer browsers (scope sidebars with sliding tone capsules, search pills, end markers), and billing/notifications/profile/security/team pages drop grouped cards for eyebrow-captioned hairline rows
Matthew Meszaros
2026-07-11 10:12:41 +02:00
ac87d80604
feat: iOS campaign leads becomes a full drawer browser matching contacts - status scopes (all/processing/replied/bounced/queued/unsubscribed) with live counts in a sky-hero sidebar, advanced contact filters, multi-select bulk edit/remove with optimistic count bumps, an add-leads picker that locks rows already in the campaign, live detail re-derived from the store with presence claims, plus shared contact browser pieces (filters sheet, CSV import, bulk actions, sidebar) and keyboard-safe create-flow sheets
Matthew Meszaros
2026-07-11 10:12:09 +02:00
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
Matthew Meszaros
2026-07-11 10:11:36 +02:00
343fc33b1d
feat: campaign schedule board supports multiple timeframes per day - the + button now drops each new window into a free gap kept an hour clear of its neighbours (so a second tap adds a distinct morning-and-afternoon window instead of merging into one), and tapping any bar opens a precise start/end editor sheet with 30-minute wheel pickers plus remove, which is how narrow windows are tuned exactly on mobile where a ~25pt bar can't be dragged pixel-accurately; bars still drag to move and merge when overlapped
Matthew Meszaros
2026-07-08 07:06:22 +02:00
3c8abbb713
feat: rebuild the iOS campaign schedule as an interactive board reimagined for mobile - each day is its own full-width horizontal 24h track (not a cramped 7-column grid) with draggable window bars: tap + to add, drag a bar sideways to move, drag its white left/right handle to resize, tap × to remove, long-press a day to copy it to all or clear it, snapping to 30 minutes, with presets, a timezone menu and today highlighted; writes the authoritative schedule_windows and supports multiple independent windows per day
Matthew Meszaros
2026-07-07 19:00:43 +02:00
80a0ece647
feat: make the iOS campaign Settings page fully editable instead of a read-only wall - sender strategy, rotation mode and ESP matching are inline menu pickers, ramp-up is an enable toggle with start/ceiling/step steppers, and lead flow has a new-leads-per-day stepper (0=off) plus a prioritize-new-leads toggle, all PATCHing optimistically; only CC/BCC lists and tracking-domain DNS stay read-only under an 'On the web' handoff
Matthew Meszaros
2026-07-07 17:33:31 +02:00
430a31148a
fix: campaign GetByID now selects and scans organization_id so the org gate in start/stop, the sender pool, advanced settings and tracking-domain verification stops 404ing every campaign (the field was always nil, failing campaignForOrg's non-nil org check)
Matthew Meszaros
2026-07-07 17:33:31 +02:00
326a07d567
feat: rebuild the iOS campaign detail as a flat hub-and-spoke instead of a card-stacked overview - the sheet is now one full-bleed native surface (eyebrow captions, bare stat columns for open/reply/bounce rates plus a live 30-day chart, hairline rows) matching the inbox and campaigns list, with Manage rows pushing to Leads (searchable, count in title), a read-only Sequence with per-step HTML reader, and Senders, all carrying a web-handoff banner for editing that needs a big screen; Sending settings (daily-limit two-disc stepper clamped 1-100, stop-on-reply, open/link tracking) edit inline via optimistic PATCH, and new Schedule (day chips, daily window, timezone picker writing schedule_windows; custom per-day schedules stay read-only) and Settings (name/description, delivery toggles, read-only advanced, creator-only delete) pages
Matthew Meszaros
2026-07-07 17:14:44 +02:00
836f72129f
feat: detail screens get a flat full-width underline tab bar replacing the chunky scrollable pills (every tab always visible, sliding accent underline, shared by campaign, mailbox, contact, and analytics details), the white sheet is now clipped so scrolling content can never bleed over its rounded corners, and the campaign create flow presents instantly by mounting the 40fps flight-scene canvas and raising the keyboard only after the cover's slide-up finishes
Matthew Meszaros
2026-07-07 10:28:46 +02:00
7143533bf5
feat: make folder-heavy accounts feel first-class - the create flow's folder page switches to a two-up chip grid with a search box once there are more than eight folders (with a no-matches state), and both the campaigns and unibox drawer cascades cap their per-row stagger so long folder, mailbox, or label lists never animate for seconds
Matthew Meszaros
2026-07-07 10:21:23 +02:00
ac74b94c8d
feat: campaign creation becomes a stepped sky onboarding flow like sign-in - full-screen cover with the flight-scene backdrop, step badge and progress segments, and three sheet pages: name plus description with live character count, sending pace presets (10/25/50 per day with conservative fresh-mailbox guidance) alongside stop-on-reply and open/link tracking toggles, and an optional skippable folder-filing page that only appears when the member has folders; the create body now carries daily_limit, rule toggles, and folder_ids
Matthew Meszaros
2026-07-07 10:02:20 +02:00
60e70515c0
feat: turn the campaigns tab into a unibox-style browser - hamburger in the search pill slides in a sky-hero drawer with status scopes and campaign folders (counts from campaigns-overview, sliding selection capsule, cascade-in rows, edge swipe to open), scopes and folders now filter server-side so every view has an exact found count and working infinite scroll, replacing the client-side underline tabs
Matthew Meszaros
2026-07-07 09:40:27 +02:00
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
Matthew Meszaros
2026-07-07 09:40:27 +02:00
500ef3419e
feat: flatten the campaign detail overview tab from insetGrouped boxes to the flat full-width list - plain style on the system background with inline eyebrow section labels for performance, last 30 days, and per step instead of sticky gray header bands
Matthew Meszaros
2026-07-07 07:43:11 +02:00
a5d18f5b3e
feat: rebuild the campaigns tab in the flat Gmail language - search pill header with inline presence and a round create button replaces the nav title, underline scope tabs with live counts replace capsule chips, and the list becomes dense full-width hairline rows with a status-toned avatar disc, teammate presence dot, stats line, pulsing status, start/pause and delete swipe actions plus a context menu, and quick start/pause from the row via the new store toggle
Matthew Meszaros
2026-07-07 07:43:11 +02:00
9e77738c5f
feat: keep users signed in through backend outages - bootstrap distinguishes a real 401 (clear token, show sign-in) from an unreachable or erroring server, which now lands on a sky unreachable screen that keeps the session and retries automatically every few seconds
Matthew Meszaros
2026-07-07 07:27:16 +02:00
9cfef4937c
feat: eliminate white message bodies - plain-equivalent emails now render as native SwiftUI text instead of a webview, and rich-HTML messages get a hardened webview that reloads after web content process termination, retries failed or never-painted loads with a capped budget, and starts from a realistic frame
Matthew Meszaros
2026-07-07 07:27:15 +02:00
2e13eb4d3d
Merge pull request #63 from warmbly/feature/coming-soon-banner
Matthew Meszaros
2026-07-07 07:16:55 +02:00
fb5e22030e
feat: wire per-post cover frontmatter into the nine remaining blog posts so each renders its own grid thumbnail and og/twitter card
Matthew Meszaros
2026-07-07 07:15:06 +02:00
d2afbf9319
feat: rewrite the quarantine-early blog post with the four-band health table, sample-size floors, engagement-signal rule, and earned re-entry
Matthew Meszaros
2026-07-07 07:15:06 +02:00
bba7a8fcb3
feat: rewrite the bulk sender rules blog post to full cluster length, converting it to mdx and covering the current Google and Microsoft 5000-a-day SPF DKIM DMARC alignment enforcement bar
Matthew Meszaros
2026-07-07 07:15:06 +02:00
339e3495b2
feat: add eleven 1200x600 webp blog cover images (29-59KB each) under public/blog for post grid thumbnails and social share cards
Matthew Meszaros
2026-07-07 07:15:06 +02:00
d1ec6206e7
feat: full schedule-send control - the schedule sheet gains Gmail-style one-tap presets (later today, tomorrow morning/afternoon, Monday morning) with their concrete times shown, a month calendar, a dedicated hour-and-minute time row that was previously clipped at the medium detent, and a will-send summary line, all clamped to the server's scheduling bounds
Matthew Meszaros
2026-07-07 06:48:40 +02:00
2370c6e637
feat: selection-aware AI in the composer - highlighting text in the draft switches the AI dropdown to a Selected text section (rephrase, shorten, expand, more formal, fix grammar) that rewrites only that range via the editor selection binding, guarded against concurrent draft edits and covered by the same one-tap undo
Matthew Meszaros
2026-07-07 06:42:21 +02:00
1633c6274f
feat: fix the blank-message-until-tap bug - the email webview now starts from a realistic frame instead of .zero, retries a first load that never committed (dropped mid navigation transition) on any SwiftUI update, and re-measures content height after layout settles
Matthew Meszaros
2026-07-07 06:42:21 +02:00
d2613a01fe
feat: composer power features - Bcc joins Cc behind a Gmail-style chevron on the To row and rides the reply request, the full-screen AI sheet is replaced by an inline prompt bar above the keyboard plus a rewrite dropdown (improve/shorten/formal/casual/grammar) with one-tap undo, and templates become an instant-insert dropdown with a searchable server-side browser for large libraries
Matthew Meszaros
2026-07-07 06:17:16 +02:00
cc01ce900f
feat: rebuild the reply composer Gmail-style - borderless full-width From/To/Cc/Subject rows separated only by hairlines, the draft editor fills the whole sheet, send moves to a toolbar paperplane with a when-to-send menu (now/smart/schedule with a graphical date sheet and an inline schedule banner), and AI/templates sit in a quiet helper bar above the keyboard
Matthew Meszaros
2026-07-07 06:07:58 +02:00
2961b4e120
feat: fix thread view bugs - message expansion and measured body heights move into the thread store so LazyVStack row recycling can no longer collapse an open message or blank its body, and the connector rail is drawn as segments that stop at the avatar edges instead of running through the translucent avatar fill
Matthew Meszaros
2026-07-07 06:07:58 +02:00
fb7397e26a
feat: iOS developer docs - README with project layout and DEVELOPMENT.md covering simulator setup, local backend wiring, and build/run workflow
Matthew Meszaros
2026-07-07 05:57:59 +02:00
b4fde65a7d
feat: iOS environment wiring - AppConfig backend/websocket endpoints, the observable AppEnvironment composing API/session/realtime/badges, and app entitlements for Sign in with Apple
Matthew Meszaros
2026-07-07 05:57:59 +02:00
29276fe056
feat: iOS analytics and settings - account analytics with charts and audit log, plus the more tab (profile, team, notifications, billing, security) in the air language
Matthew Meszaros
2026-07-07 05:57:44 +02:00
eefa88adff
feat: iOS mailboxes - account list with health/warmup state, connect sheet, and mailbox detail with settings, limits and deliverability tabs
Matthew Meszaros
2026-07-07 05:57:43 +02:00
553a2844a5
feat: iOS contacts and CRM - contacts browser with category picker and bulk selection, contact detail with edit drawer, plus CRM deals, meetings, tasks and template views on the shared air scaffold
Matthew Meszaros
2026-07-07 05:57:43 +02:00
7afa5d997e
feat: iOS campaigns - list with status rows, create sheet, and campaign detail with air hero, sticky tabs, sequence/schedule/recipient views and live send stats
Matthew Meszaros
2026-07-07 05:57:43 +02:00
f3cb7b114b
feat: iOS unibox - Gmail-style browser with sidebar drawer (sky hero badges, sliding pill selection, red unread counts, labels + uncategorized), search pill with operator hints and result counts, multi-select with swipe actions and infinite scroll, flat thread view with connector rail, replying-to references, per-message reply/copy/read tools, and an air-styled reply composer with smart scheduling
Matthew Meszaros
2026-07-07 05:57:31 +02:00
07b319b2d6
feat: iOS home tab - workspace pulse with air hero, live health/send stats, and shortcuts into mailboxes and analytics
Matthew Meszaros
2026-07-07 05:57:31 +02:00
4dc32e6ccb
feat: iOS auth flow - welcome screen, multi-step email login/register with OTP code field, native Sign in with Apple and Google buttons against the new token endpoints, org picker, and the post-signup onboarding questionnaire
Matthew Meszaros
2026-07-07 05:57:31 +02:00
5041c285ca
feat: iOS navigation shell - session-gated root with a breathing-logo sky launch view and a permission-aware tab bar carrying the unibox unread badge
Matthew Meszaros
2026-07-07 05:57:11 +02:00
a434e0c070
feat: iOS design system - air theme (sky wash heroes, tone palettes, stat chips, eyebrow labels), shared components (avatars, skeleton shimmer rows, empty/error states, tap-scale style), and the Warmbly logo/wordmark shapes
Matthew Meszaros
2026-07-07 05:57:11 +02:00
4f55903165
feat: iOS realtime layer - Phoenix channels websocket client with heartbeats and rejoin backoff, org/user channel subscriptions, presence state sync, and per-feature event pulses driving live query invalidation
Matthew Meszaros
2026-07-07 05:57:11 +02:00
5710c86d9e
feat: iOS core layer - async APIClient with idempotency keys and typed errors, Codable models mirroring the backend wire contracts (including the Group title key), session store with permission checks, and a keychain-backed token store
Matthew Meszaros
2026-07-07 05:57:01 +02:00
734955b490
feat: scaffold the Warmbly iOS app - Xcode project with synchronized folder references, app entry point wiring the environment, Info.plist with a LaunchBackground sky launch screen, and the asset catalog (app icon, accent, clouds, launch color)
Matthew Meszaros
2026-07-07 05:57:01 +02:00
15088a6f64
feat: pin cowboy >= 2.16 in the realtime service so CR/LF response header values are rejected before the wire (EEF-CVE-2026-43966/43969 has no patched cowlib release)
Matthew Meszaros
2026-07-07 05:56:47 +02:00
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
Matthew Meszaros
2026-07-07 05:56:47 +02:00
08699b1c88
feat: include the referral_reward_percent column in plan row scans so plan lookups stop failing after the referral rewards migration
Matthew Meszaros
2026-07-07 05:56:47 +02:00
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
Matthew Meszaros
2026-07-07 05:56:35 +02:00
cef5e019e6
feat: ignore Xcode per-user state (xcuserdata) and .DS_Store so the iOS project tree stays free of machine-local files
Matthew Meszaros
2026-07-07 05:56:24 +02:00
6df48f626e
chore: update the README top banner to the new Figma branding export (1600x533 JPG, ~108KB, smaller than the previous banner)
Matthew Meszaros
2026-07-06 06:28:11 +02:00
f6a6a310ac
feat: enrich blog structured data with BreadcrumbList, wordCount, keywords, inLanguage, articleSection, and a per-post share image on BlogPosting
Matthew Meszaros
2026-07-06 06:28:11 +02:00
721aced30f
feat: replace the social OG card with the Figma export as an optimized 52KB mozjpeg JPG (1200x600) and switch every og:image reference from PNG to JPG
Matthew Meszaros
2026-07-06 06:28:11 +02:00
1f38604fcd
feat: cross-link the three existing blog posts into the new warmup, sending, and deliverability topic clusters with contextual internal links
Matthew Meszaros
2026-07-06 06:28:11 +02:00
074f484c43
feat: add eight SEO blog posts on cold email sending limits, warmup mechanics, delivery vs inbox placement, DMARC alignment, reputation recovery, and self-hosting
Matthew Meszaros
2026-07-06 06:28:11 +02:00
5809247980
style: replace an em dash with a colon in the terms usage-limits clause to match the no-em-dash copy rule
Matthew Meszaros
2026-07-06 06:28:11 +02:00
7aa1390f21
feat: add FAQPage JSON-LD to /faq, correct the per-user to per-organization DEK claim, and drop em dashes from two answers
Matthew Meszaros
2026-07-06 06:28:11 +02:00
534f6eb263
fix: correct the encryption claim from per-user to per-organization DEKs on the about, trust, and integrations pages to match the envelope-encryption model
Matthew Meszaros
2026-07-06 06:27:43 +02:00
dcf50cb99a
feat: change the trial to three mailboxes everywhere and add free-tier limitation copy (unfilled warmup pool, for evaluation not production) on the homepage and pricing page
Matthew Meszaros
2026-07-06 06:27:43 +02:00
a9384ca72c
feat: add reciprocal Deep dives blog link blocks to the warmup, sending, and deliverability pillar pages so clusters link both directions
Matthew Meszaros
2026-07-06 06:27:43 +02:00
71a4275e59
feat: surface the self-host warmup pool notice on the warmup page and sharpen the open-source section caveat that the pool needs the cloud
Matthew Meszaros
2026-07-06 06:27:43 +02:00
d9c8d3c9bd
feat: add a reusable PillarPosts component for a 'Deep dives' blog link block on pillar pages
Matthew Meszaros
2026-07-06 06:27:43 +02:00
e37a340bb4
feat: add a reusable WarmupPoolNotice component explaining the shared warmup pool is a cloud feature a single self-hosted instance cannot replicate
Matthew Meszaros
2026-07-06 06:27:43 +02:00
1d4357e4af
feat: add a site-wide coming-soon launch banner (LaunchBanner) announcing Warmbly Cloud and the shared warmup pool with a waitlist CTA, rendered above the header in Layout
Matthew Meszaros
2026-07-06 06:27:43 +02:00
99dfd261d4
Merge pull request #62 from warmbly/feature/gmail-imap-sync-fixes
Matthew Meszaros
2026-07-04 13:19:15 +02:00
27487a3279
Merge pull request #59 from warmbly/feature/human-send-behavior
Matthew Meszaros
2026-07-04 13:12:29 +02:00
f38a939f2e
Merge pull request #60 from warmbly/feature/inbound-bounce-and-behavior
Matthew Meszaros
2026-07-04 13:12:15 +02:00
87a877bd95
Merge pull request #61 from warmbly/fix/realtime-multiarch-publish
Matthew Meszaros
2026-07-04 12:09:32 +02:00
4c714c471f
Merge pull request #58 from warmbly/feature/gmail-imap-sync-fixes
Matthew Meszaros
2026-07-04 12:09:30 +02:00
b11cf3fa27
Merge pull request #57 from warmbly/feature/mailbox-graph-api
Matthew Meszaros
2026-07-04 12:02:05 +02:00
a2e35a1c02
fix: build the realtime image on native amd64 and arm64 runners and merge the digests into one manifest so the elixir release stops hanging for hours under qemu emulation
Matthew Meszaros
2026-07-04 11:59:35 +02:00
ad1d40fd2b
test: cover the gmail/graph message mapping (read-state inversion, spam/category labels, unpadded base64url bodies, warmup and classification header surfacing), the imap header-flag parser, the graph MIME builder, and the human-behavior timing (sub-minute randomisation, daily volume factor, night-deferred and heavy-tailed engagement)
Matthew Meszaros
2026-07-04 11:45:01 +02:00