2026-09-21 04:28:20 -07:00
..
2026-09-16 21:44:42 -07:00
2026-09-21 02:24:36 -07:00
2026-09-21 02:11:38 -07:00
2026-09-21 02:11:38 -07:00
2026-09-14 07:44:34 -07:00
2026-09-10 05:23:56 -07:00
2026-09-04 06:16:16 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-08-28 11:50:48 -07:00
2026-09-04 12:58:09 +02:00
2026-09-04 12:58:09 +02:00
2026-09-16 03:31:01 -07:00
2026-09-14 21:54:05 -07:00
feat: add Delete and Duplicate campaign actions to the dashboard (issue #185): every campaign row and the detail header get a ⋯ menu (Edit, Duplicate, Start/Pause, Delete) plus a Delete card at the bottom of Settings, all permission-gated with a confirm that spells out what goes; DELETE /campaigns/:id is now organization-scoped instead of user_id-scoped so teammates can delete, runs in one transaction that also deletes the campaign's pending tasks and cancels a wakeup tick claimed at that moment (campaign_tasks only nulls its link, so those rows kept firing), removes attachment objects and publishes CAMPAIGN_DELETED so a teammate's open detail page is sent back to the list; new POST /campaigns/:id/duplicate copies the campaign row as a draft with steps and their branch graph rewired onto new step ids, tags, folders, senders with rotation reset, A/B variants, advanced settings and attachments (quota-checked, blobs undone if the copy fails) and none of the leads, progress, logs, counters, ramp level, guardrail trip or past dates, naming it (copy)/(copy N) inside the 50 byte cap without splitting runes; a claimed campaign tick whose campaign vanished now ends the chain instead of staying active forever; covered by TestLiveCampaignLifecycle* against real SQL, RemapBranchTargets and duplicateName unit tests and a react-query vitest for the list cache, with API reference, endpoint map and campaigns guide updated
2026-08-25 08:54:51 -07:00
feat: add Delete and Duplicate campaign actions to the dashboard (issue #185): every campaign row and the detail header get a ⋯ menu (Edit, Duplicate, Start/Pause, Delete) plus a Delete card at the bottom of Settings, all permission-gated with a confirm that spells out what goes; DELETE /campaigns/:id is now organization-scoped instead of user_id-scoped so teammates can delete, runs in one transaction that also deletes the campaign's pending tasks and cancels a wakeup tick claimed at that moment (campaign_tasks only nulls its link, so those rows kept firing), removes attachment objects and publishes CAMPAIGN_DELETED so a teammate's open detail page is sent back to the list; new POST /campaigns/:id/duplicate copies the campaign row as a draft with steps and their branch graph rewired onto new step ids, tags, folders, senders with rotation reset, A/B variants, advanced settings and attachments (quota-checked, blobs undone if the copy fails) and none of the leads, progress, logs, counters, ramp level, guardrail trip or past dates, naming it (copy)/(copy N) inside the 50 byte cap without splitting runes; a claimed campaign tick whose campaign vanished now ends the chain instead of staying active forever; covered by TestLiveCampaignLifecycle* against real SQL, RemapBranchTargets and duplicateName unit tests and a react-query vitest for the list cache, with API reference, endpoint map and campaigns guide updated
2026-08-25 08:54:51 -07:00
2026-08-28 10:29:39 -07:00
2026-09-17 06:03:56 -07:00
2026-09-18 08:26:18 +00:00
2026-09-12 03:13:38 -07:00
2026-09-12 03:13:38 -07:00
2026-04-09 15:59:27 +00:00
2026-09-16 03:31:01 -07:00
2026-09-13 20:51:41 -07:00
2026-09-14 23:05:16 -07:00
2026-09-19 09:24:17 -07:00
2026-09-14 23:05:16 -07:00
feat: add recipient-level engagement to the campaign Leads view by adding an engagement search filter (opened, not_opened, clicked, not_clicked, replied, not_replied, bounced) that composes with lead_status as AND and rejects unknown values with stable 400 codes, counting only human opens so machine opens never read as engagement, adding contacted/opened/clicked/replied_any totals to lead_counts, rendering Opened/Clicked/Replied columns and clickable server-backed status and engagement chips in the Leads table with matching Filters sheet sections, offering lead_status/lead_opened/lead_clicked/lead_replied export columns from a campaign, covering every filter value with a live Postgres test, and documenting the columns, filters, error codes and export fields (issue #250)
2026-08-29 03:12:02 -07:00
2026-09-08 06:53:57 -07:00
2026-09-10 04:53:50 -07:00
2026-09-08 20:26:34 -07:00
2026-09-19 09:24:17 -07:00
2026-09-16 08:30:35 -07:00
2026-08-26 06:03:20 -07:00
2026-09-08 21:05:37 -07:00
2026-08-28 12:12:28 -07:00
2026-09-14 12:20:47 -07:00
2026-09-09 08:59:40 -07:00
2026-09-18 12:54:45 +02:00
2026-09-09 09:46:39 -07:00
2026-09-08 21:00:09 -07:00
2026-06-02 15:54:12 +02:00
2026-09-07 08:49:23 -07:00
2026-09-12 03:37:31 -07:00
2026-09-12 03:37:31 -07:00
2026-08-29 10:07:36 -07:00
2026-06-02 15:54:12 +02:00
2026-09-15 00:00:20 -07:00
2026-09-19 09:45:03 -07:00
2026-09-08 04:59:31 -07:00
2026-08-28 12:08:17 -07:00
2026-09-14 07:55:01 -07:00
2026-09-07 05:08:35 -07:00
2026-08-28 22:41:44 -07:00
2026-08-28 22:47:24 -07:00
2026-09-17 04:15:05 -07:00
2026-09-17 04:15:05 -07:00
2026-09-13 08:09:01 -07:00
2026-09-21 02:11:38 -07:00
feat: backend half of the admin panel upgrade: delete the unrouted provisioning, releases, plan, discount and enterprise-inquiry admin handlers with their service and repository methods, retire the six admin permission bits nothing gated as reserved placeholders so live bit positions and existing masks are unchanged and IsSuperAdmin checks the live set, add forty admin endpoints for mailbox sync governor state with clear-throttle and restart-backfill, in-flight send reservations, cross-workspace dead letters with replay, task failures, webhook delivery health with reclaim, fleet capacity, the control loops decision log, dedicated bindings with release and the routed convert-to-dedicated, operator-driven workspace export and import, per-organization API keys and webhooks, warmup invalid-token abuse and action history, and signups by acquisition channel, and add a scheduled_job_runs table (migration 000135) with a jobrun package that every backend and consumer loop now records through and a run-now request the owning process picks up within fifteen seconds
2026-09-07 21:40:38 -07:00
2026-09-07 21:56:23 -07:00
2026-09-21 02:24:36 -07:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-09-14 07:44:34 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-07-19 13:22:56 +02:00
feat: inbox agent that drafts a suggested unibox reply on inbound human replies for human approve/edit/discard - paid + per-org opt-in (organizations.inbox_agent_enabled) feature where the consumer's reply hook, on a non-automated reply, detaches a goroutine (panic-contained, never blocks ingest) that checks entitlement, dedupes via ai_thread_drafts partial unique indexes (one pending per thread, unique source_message_id), pre-checks balance, grounds a reply in the thread history + org voice + skills via generation.Provider.Complete, reserves a draft row then charges 5 credits (idempotency inbox_agent:<draft.ID>, row unwound on a fresh context if the charge fails so no unpaid draft lingers), and emits an org-scoped AI_DRAFT_READY event gated on access_unibox; the agent never sends - only a human POST to /unibox/agent-drafts/:id/approve sends through the normal reply path, claiming pending->approved before send with an approved->pending revert on send failure, alongside list + discard endpoints; plus the unibox awaiting_agent_draft badge + agent_drafts search scope, an AgentDraftCard in the thread view with inline-editable approve-and-send/discard, the workspace settings opt-in toggle, CanUseInboxAgent paid gate, migration 000065, and docs (inbox-agent guide, endpoints, realtime)
2026-07-14 06:13:27 +02:00
2026-07-19 13:22:56 +02:00
2026-09-20 10:15:33 -07:00
2026-09-10 05:23:56 -07:00
2026-09-08 21:00:09 -07:00
2026-07-30 17:15:09 +02:00
2026-09-16 15:03:21 +02:00
2026-09-21 03:23:14 -07:00
2026-09-13 06:47:42 -07:00
feat: give every campaign email a working opt-out: a reply-to-opt-out line by default or an unsubscribe link (workspace setting under Settings > Sending with a per-campaign override and a {{.UnsubscribeLink}} variable), signed per-recipient unsubscribe links served on the API origin so the List-Unsubscribe header no longer points at a dead warmbly.com page, a confirm page on GET with RFC 8058 one-click on POST and a resubscribe button, reply opt-out detection through the whole-word compliance lexicon with quoted history stripped, a first-class suppression list (Contacts tab, GET/POST/DELETE /suppressions with address and domain entries, audited removal, contact drawer action), the contact Subscribed flag enforced in campaign routing, migration 000122 with a shared recipient_suppressed() predicate, and docs for all of it
2026-09-03 01:52:40 -07:00
2026-09-13 20:51:41 -07:00
2026-08-28 10:29:39 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-09-19 08:28:41 +02:00
2026-09-04 21:03:58 -07:00
2026-09-12 06:58:25 -07:00
2026-07-19 08:52:56 +02:00
feat: add first-touch contact source attribution (migration 000106: contacts.source with a CHECK, source_detail, first_seen_at, existing rows stamped unknown) stamped at every creation site (dashboard manual/campaign, file import, Google Sheets sync, API key, AI assistant), write contact_created / campaign_added / campaign_removed / category_added / category_removed lifecycle events into contact_activities inside the same transactions as the links and merge them into the contact timeline, refactor FindNextRoutedPair's routing into a campaignRouter shared with a per-contact RouteContact and split CalculateNextCampaignTime into campaignSenders + placeCampaignSend so a read-only PreviewContactSend derives a contact's next step through the scheduler's own constraints, expose it as GET /contacts/:id/campaigns behind the contact service, render a per-campaign state panel, Campaigns/Lifecycle filter chips and expandable event rows in the Activity tab plus a Source section on Overview, cover it with TestLive* for the timeline events and the next-action preview (step wait, sending window, paused), and document it in the contacts, campaigns and API reference docs (issue #255)
2026-08-29 03:28:16 -07:00
2026-09-14 09:26:06 -07:00
2026-09-19 09:24:17 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-08-28 12:12:28 -07:00
2026-09-17 15:25:35 +02:00
2026-07-19 13:22:56 +02:00
2026-09-19 08:28:41 +02:00
2026-09-09 09:07:26 -07:00
2026-09-18 12:54:45 +02:00
2026-05-27 15:54:56 +00:00
2026-07-13 16:11:15 +02:00
2026-09-21 02:11:38 -07:00
2026-09-07 03:51:06 -07:00
2026-09-15 13:46:37 +02:00
2026-09-08 21:00:09 -07:00
2026-06-02 15:54:12 +02:00
2026-09-10 03:38:50 -07:00
2026-09-18 11:42:49 +02:00
2026-09-21 00:52:02 -07:00
2026-09-17 04:15:05 -07:00
2026-09-09 04:54:01 -07:00
2026-09-01 09:49:06 -07:00
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
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-07-04 08:07:49 +02:00
2026-09-12 03:37:31 -07:00
feat: give each mailbox a human sending persona (randomized daily and hourly caps, send spacing, work start/end, lunch break and working weekdays, rolled once per local day in the mailbox's own timezone and applied across the campaign, warmup and smart-send schedulers), add campaign auto-pause guardrails that stop a campaign when its bounce, complaint or reply rate leaves the configured band, make mailbox rotation actually rotate for tag-resolved and all-mailbox campaigns, stop every scheduler from ever returning a slot in the past, and correct the mailbox min-gap field that stored seconds while labelling them minutes
2026-08-13 16:51:29 +02:00
2026-06-02 15:54:12 +02:00
2026-09-21 03:57:29 -07:00
2026-09-17 04:57:24 -07:00
2026-09-17 04:57:52 -07:00
feat: shared TypeSafe client under internal/pkg/typesafe with inbox tagging phases 2 and 3 (hold, stop, task, suppress behind workspace switches, reversible ones on by default), labels seeded at workspace creation and by the follow-up sweep, premade inbox views (hot leads, needs a reply, follow up, declined, automated), typed reply classification and a reply_intent branch condition, an inbox agent draft gate, Advisor copy judgment with a cached editor re-check, warmup content lint, bounce cause classification that keeps a blocked address sendable, and per-form submission triage
2026-09-19 23:33:37 -07:00
2026-09-08 21:05:37 -07:00
feat: backend half of the admin panel upgrade: delete the unrouted provisioning, releases, plan, discount and enterprise-inquiry admin handlers with their service and repository methods, retire the six admin permission bits nothing gated as reserved placeholders so live bit positions and existing masks are unchanged and IsSuperAdmin checks the live set, add forty admin endpoints for mailbox sync governor state with clear-throttle and restart-backfill, in-flight send reservations, cross-workspace dead letters with replay, task failures, webhook delivery health with reclaim, fleet capacity, the control loops decision log, dedicated bindings with release and the routed convert-to-dedicated, operator-driven workspace export and import, per-organization API keys and webhooks, warmup invalid-token abuse and action history, and signups by acquisition channel, and add a scheduled_job_runs table (migration 000135) with a jobrun package that every backend and consumer loop now records through and a run-now request the owning process picks up within fifteen seconds
2026-09-07 21:40:38 -07:00
2026-09-08 04:59:18 -07:00
2026-09-10 03:38:50 -07:00
2026-08-28 12:08:17 -07:00
2026-09-14 07:55:01 -07:00
2026-09-18 11:42:49 +02:00
2026-07-13 20:05:24 +02:00
2026-06-11 11:32:57 +02:00
2026-07-20 08:01:22 +02:00
2026-07-16 08:57:19 +02:00
2026-08-28 22:51:23 -07:00
2026-08-28 22:47:24 -07:00
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
2026-06-11 11:24:19 +02:00
2026-09-21 02:11:38 -07:00
2026-08-18 07:53:39 -07:00
2026-06-03 16:47:53 +02:00
2026-09-13 21:22:12 -07:00
2026-09-12 06:58:25 -07:00
2026-05-27 12:06:18 +00:00
2026-01-29 05:59:04 +01:00
2026-08-27 01:04:50 -07:00
2026-09-12 03:37:31 -07:00
feat: AI contact research agent that gathers cited web findings per contact with sync and background-batch runs - contact_research_runs table plus a strict save_research schema (every signal and public_artifact must carry a url, confidence high/medium/low, signals<=5 hooks<=3, reject-and-reprompt once then fail), a text/template runtime prompt injecting org voice, contact record, objective, and 5-search/6-fetch budgets, a research service that drives search_web/fetch_url through the provider loop and charges 2 credits on save (billable even for nothing_found, refund-free since charged only on save, balance and abuse-cap pre-checked so a capped org never does free work), POST/GET /contacts/:id/research plus a 500-cap /contacts/research/batch draining through a bounded pool of 4 workers over FOR-UPDATE-SKIP-LOCKED claims (no new Kafka), an org-scoped AI_RESEARCH_PROGRESS realtime event gated to view_contacts, APIPermAIResearch bit 23, a ContactEdit Research tab and a ContactsTable bulk Research action, and docs; also org-scopes every credit and research idempotency key so a client-supplied Idempotency-Key can never replay across tenants
2026-07-13 19:34:11 +02:00
feat: give every campaign email a working opt-out: a reply-to-opt-out line by default or an unsubscribe link (workspace setting under Settings > Sending with a per-campaign override and a {{.UnsubscribeLink}} variable), signed per-recipient unsubscribe links served on the API origin so the List-Unsubscribe header no longer points at a dead warmbly.com page, a confirm page on GET with RFC 8058 one-click on POST and a resubscribe button, reply opt-out detection through the whole-word compliance lexicon with quoted history stripped, a first-class suppression list (Contacts tab, GET/POST/DELETE /suppressions with address and domain entries, audited removal, contact drawer action), the contact Subscribed flag enforced in campaign routing, migration 000122 with a shared recipient_suppressed() predicate, and docs for all of it
2026-09-03 01:52:40 -07:00
2026-09-14 22:12:15 -07:00
2026-08-28 23:30:15 -07:00
2026-09-16 03:31:01 -07:00
feat: org AI skills (playbooks) that every AI feature loads and follows - ai_skills table (org-scoped, unique name per org, 32KB content cap) with a skills service exposing CRUD plus an enabled-skills preamble injected into the dashboard agent, contact research, and reply-draft prompts and a load_skill read-tool that returns a playbook's full content by name, /ai/skills CRUD gated on manage_settings (JWT) or the AI_AGENT scope (API) with an ai_skill audit entity and spine entry, an AI skills settings page (list rows opening a right-side drawer with name, one-line description, enable toggle, and a markdown body), and docs with two example playbooks
2026-07-13 19:46:25 +02:00
2026-05-27 14:43:36 +00:00
2026-09-12 09:45:31 -07:00
2026-09-19 09:58:52 -07:00
2026-06-07 07:03:49 +02:00
2026-08-27 01:04:50 -07:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-09-19 08:15:31 -07:00
2026-09-03 01:05:34 -07:00
2026-08-16 07:46:19 +02:00
2026-09-18 14:44:41 +02:00
2026-09-20 07:16:35 -07:00
2026-09-15 00:42:45 -07:00
feat: validate every person, workspace and company name through internal/pkg/displayname on each write path (profile, onboarding, setup, IdP sign-in, org create and rename, org import, enterprise inquiry, admin testers, warmblyctl) with a 400 invalid_name code, render stored names in platform email through the same rules, mirror them in the web forms, check the org slug format, and document the rules in error-codes, security and AGENTS.md
2026-09-21 03:34:03 -07:00
2026-09-14 23:05:16 -07:00
2026-09-19 09:38:59 -07:00
2026-09-05 21:24:11 -07:00
2026-06-03 11:14:02 +02:00
2026-05-25 15:42:50 +00:00
2026-09-21 00:52:02 -07:00
2026-06-01 03:09:17 +02:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-08-29 04:16:28 -07:00
2026-09-17 04:15:05 -07:00
2026-09-17 07:45:23 -07:00
2026-09-09 04:54:01 -07:00
2026-05-20 14:15:52 +00:00
2026-09-17 07:45:23 -07:00
2026-09-15 13:46:37 +02:00
2026-09-21 02:11:38 -07:00
2026-09-18 14:12:33 +02:00
feat: make the admin panel's broken queries run: seven statements referenced schema that does not exist and failed 100% of the time, so a force-stop wrote status = 'stopped' and stopped_at to a campaign_status enum and a campaigns table that have neither, the plan writes named a duration column that became duration_id long ago, the user rate-limit read and write named a daily_email_limit column that user_rate_limits has never had, and the user preview compared email_accounts.user_id (uuid) against a text parameter and then swallowed the error so every operator saw an empty mailbox list; the same uuid = text defect in GetUserEmails, which the prepare sweep cannot see because that WHERE clause is assembled at runtime, was a live 500 on GET /admin/users/:id/emails; a stop now parks the campaign at 'paused' like the owner-facing stop and records the reason the UI has always sent and the backend has always dropped into both the audit log and the owner's campaign feed, the plan writes resolve durations.title to duration_id and answer 400 rather than a constraint violation on an unknown period, the rate-limit editor now covers the seven real limit columns instead of one that never existed and patches insert-then-update in a transaction because every column is NOT NULL, AdminWorkerEmail.LastSyncedAt is a pointer so a never-synced mailbox stops being silently dropped from every admin list, and TestLiveEveryQueryPrepares now fails on undefined columns, tables, operators and enum values instead of only reporting them
2026-08-27 03:09:40 -07:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-09-14 22:12:15 -07:00
2026-09-14 22:12:15 -07:00
2026-08-29 23:45:05 -07:00
2026-08-28 21:54:29 -07:00
2026-08-28 11:26:44 -07:00
2026-09-08 00:31:45 +00:00
2026-09-12 03:37:31 -07:00
2026-09-20 07:16:35 -07:00
2026-09-17 04:18:08 -07:00
2026-09-16 21:44:42 -07:00
2026-09-14 23:05:16 -07:00
2026-09-19 09:38:59 -07:00
2026-09-20 09:42:53 -07:00
2026-09-17 21:15:28 -07:00
2026-09-21 00:52:02 -07:00
2026-09-20 10:15:33 -07:00
2026-09-13 21:37:17 -07:00
2026-08-28 10:40:25 -07:00
feat: complete the ADA CASA v2.1.1 AL1 control set across authentication, sessions, access control, cryptography, input validation and configuration, adding a breached-password denylist and per-account login throttling, enforced multi-factor authentication on the admin panel, step-up confirmation before an action that mints a lasting credential, purpose-scoped session tokens, single-use TOTP steps, tenant verification on every cross-referenced identifier, security headers on every surface, encrypted webhook signing secrets, per-organization idempotency, PKCE and a minimal two-scope Gmail consent on the mailbox OAuth flow, bounded spreadsheet and archive decoding, a patched Go toolchain with govulncheck in CI, and the evidence pack under compliance/casa
2026-09-19 08:18:35 +02:00
2026-09-07 04:35:56 -07:00
2026-09-17 04:15:05 -07:00