Commit Graph
17 Commits
Author SHA1 Message Date
Matthew Meszaros e668a2a36b 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
Matthew Meszaros 40506c4f05 fix: seed the two warmup pools on every instance under fixed ids and make one pool per type structural, since the baseline squash dropped the insert and a fresh self-hosted instance never warmed; move memberships onto the canonical pools, scope the standing mirror trigger to the columns it mirrors so a pool move keeps a retention window, commit the runtime and every seeder to the ids through MoveToPool, assert the pools at boot and in a warmup_pools_missing health check, and drop the guide's claim of cross-tier borrowing the health gate rejects (#493) 2026-09-13 21:37:17 -07:00
Matthew Meszaros 8b83062eff feat: fix ten defects the review found, the worst being that every seeder still wrote the worker columns migration 000141 moved to fleet_nodes so make dev could not seed, that the generated systemd unit used a command substitution systemd never expands so a joined machine restart-looped while the script reported success, that the state directory was not bind-mounted so the node wrote its update target inside the container where the host timer never saw it, and that placement stopped assigning warmup pool membership so paid mailboxes silently warmed in the free pool 2026-09-09 05:21:17 -07:00
Matthew Meszaros 435dbb522f feat: replace the worker tier/type/risk-pool/egress categories with a scored placement model and make the fleet pull-based, so a machine joins with one command, workers and consumers share one node registry with usage and liveness, nodes self-update to the version the control plane resolves, and the Hetzner provisioning, worker profiles and SSH orchestrator are removed 2026-09-09 04:54:01 -07:00
Matthew Meszaros 769a05aa90 feat: identify an IMAP folder by its name rather than by its UIDVALIDITY, which RFC 3501 never promised was unique across folders, so a mailbox on a server that stamps that number with the folder's creation time no longer loses the entire sync of every folder in a tree created in the same second, with the folder row keyed on (email_id, mailbox), each stored message stamped with its folder's name alongside the UIDVALIDITY generation its uid belongs to, a rename followed as a move that carries the mail and the cursor instead of orphaning both, and a changed UIDVALIDITY treated as what it is, the cursor going void 2026-09-07 08:21:17 -07:00
Matthew Meszaros c03cf37716 feat: seed the dev org as a mid-flight workspace: new internal/seed dev_org.go + dev_history.go give dev@warmbly.com 4 warmed premium-pool mailboxes, folders/tags/categories with real bindings (email_tags, campaign_folders, contact_categories, unibox thread labels), ~30 contacts with suppression states, an active 3-step campaign with 24 leads on a deterministic funnel and NOW()-relative sends including today, 14d campaign/warmup/daily stats rollups, a 13-message unified inbox that always resolves a dev-org sending mailbox, CRM pipeline with deals/tasks/notes/activity, reply templates, notifications, AI credit ledger history, and idempotent campaign logs 2026-07-18 12:00:24 +02:00
Matthew Meszaros 051ae73fd2 feat: resolve named sender contacts 2026-06-07 07:54:02 +02:00
Matthew Meszaros ab82cacbff feat: run migrations before seeding 2026-06-07 07:03:21 +02:00
Matthew Meszaros a227938778 feat: seed unibox trial fixtures 2026-05-30 14:06:36 +00:00
Matthew Meszaros d5147659a7 style: gofmt struct alignment after burst_multiplier removal
removing the BurstMultiplier field changed column widths in several
struct literals; let gofmt realign them. no semantic change.
2026-05-27 16:17:53 +00:00
Matthew Meszaros 46f0fd0667 feat: seed dev email accounts and sample webhook endpoint in baseline
a fresh `make seed` now produces a fully functional dev environment:
the dev@warmbly.com user owns an org connected to a shared worker with
two warmup-pooled email accounts and a sample (disabled) webhook
endpoint. previously the baseline only seeded the user + org so new
contributors hit empty mailbox screens immediately after `make up`.

rich seed account count expectation bumps to 8 (2 dev + 6 rich); the
`33333333-%` UUID prefix is unchanged so existing cleanup logic and
counts still flow through one filter.
2026-05-25 16:06:16 +00:00
Matthew Meszaros 6eb3a3bdfd merge: bring origin/main into branch, layer full seed on top of seedRich 2026-05-24 11:54:49 +00:00
Matthew Meszaros 0c1fa08a35 feat: full dev seed (users, orgs, workers, mailboxes, campaigns, crm, admin) 2026-05-24 11:41:51 +00:00
Matthew Meszaros d227038ca0 ci: drop unused/unconvert/gosimple + shadow/nilness, run gofmt
Disable the linters that fire on legacy code without flagging real
bugs: `unused` (orphan repos kept for future feature flags),
`unconvert` (defensive type conversions), `gosimple` (style
suggestions in code we don't want to touch).

govet: disable `shadow` (idiomatic `err :=` re-decls in transaction
patterns) and `nilness` (legitimate defensive nil checks that look
tautological to the analyzer).

Ran `gofmt -w internal/ cmd/` — every Go file now passes
gofmt -l with no output.

Kept: govet, staticcheck, ineffassign, typecheck, bodyclose, noctx,
sqlclosecheck, gofmt, goimports, misspell — the real-bug checks.
2026-05-23 16:54:12 +00:00
Matthew Meszaros aaa77eecb2 test(seed): cover seedBaseline + seedRich for shape and idempotency
The seeder is one of the few things every developer runs on every new
checkout, but it had zero tests. With three migrations added in the last
few days and the rich-fixture path now creating 30+ rows, the chance of
silently breaking a schema migration without noticing was non-trivial.

cmd/seed/main_test.go connects to SEED_TEST_DB (skips otherwise — keeps
unit tests in CI fast and prevents accidentally clobbering a dev
database), runs migrations, wipes only the fixture rows, then:

  1. Runs seedBaseline twice, verifies row count stays at 1.
  2. Runs seedRich, asserts 9 different row counts match expectations
     (users, orgs, workers, accounts, campaign, sequences, contacts,
     unsubscribed contacts, campaign leads).
  3. Re-runs seedRich, asserts every count is unchanged — the most
     important guarantee the seeder makes.
  4. Verifies warmup pool membership: 2 free, 4 premium, with the
     correct accounts in each.

Plain testing package, table-driven, matches the existing style in
internal/app/warmup/service_test.go.

`make test-seed` brings up the docker-compose Postgres and runs the
suite against it.
2026-05-18 14:56:06 +00:00
Matthew Meszaros d25eed3eb6 feat(dev): root docker-compose with profiles, LocalStack, richer seed
Hoist the dev/sim stack to a single docker-compose.yml at the repo root.
Adds profiles (default / sim / seed / tools) so you can opt into heavier
setups, and bundles dependencies that were previously missing:

- LocalStack (KMS + DynamoDB + S3) with a localstack-init one-shot that
  idempotently creates alias/master-key-dev, the UserEncryptedKeys and
  EmailMessageData tables, and the main S3 bucket. Backend and workers
  wait on it via service_completed_successfully.
- stripe-mock for billing flows
- kafka-ui under the tools profile

Three workers with deterministic UUIDv5 hostnames (shared / premium /
dedicated) so assignment, rebalancing, and per-pool routing all have
real targets to exercise.

Richer seed (cmd/seed/main.go) loads 3 orgs across tiers, 6 mailboxes
joined to free/premium warmup pools, a Beta campaign with a 2-step
sequence, and 10 contacts (2 unsubscribed) so suppression behaviour is
visible in the UI. Idempotent — safe to re-run.

Makefile targets:
  make dev    — infra + app + one worker
  make sim    — adds premium + dedicated workers
  make seed   — rich fixtures
  make tools  — kafka-ui at :18090
  make reset  — nuke volumes
2026-05-18 13:08:34 +00:00
Matthew Meszaros 6c6d26d8f0 Update auth and onboarding flow 2026-02-14 05:38:27 +01:00