Phase 12.5 - contact groups (v0.14.0) #62

Merged
vmanne-poc merged 5 commits from phase-12.5 into main 2026-10-19 12:02:12 -04:00
Owner

Summary

Phase 12.5: contact groups (v0.14.0).

  • Groups: hand-managed contact lists per project, with Groups and group pages, paged and searchable members, and add/remove by id or by contacts filter.
  • Contact profile shows the contact's groups (removable chips, add to existing or new group) and the segments they match now.
  • Contacts list: group filter (also on export), Groups column, row/page/all-matching selection, bulk add to and remove from group.
  • Import, export, and forms: CSV groups column on import and export, add everyone in a file to chosen groups, sign-up forms can add subscribers to groups.
  • Campaign audiences: include several groups and segments, exclude others, live count, each contact emailed once, audience recorded at send time and shown in the report. Groups and segments used by unsent campaigns can't be deleted.
  • Segment rule "Group is in / is not in"; builder containers renamed to blocks.
  • Phase 12 review fixes: test emails use sample data (Jane Doe) by default or a chosen contact; Duplicate keeps the web view setting and the audience.
  • Migrations: contact_groups (additive) and campaign_audience (moves segmentId into the audience, then drops the column). Back up the database before upgrading.
  • Release: CHANGELOG [0.14.0], README features, backend and frontend versions bumped to 0.14.0.

Tests

  • Backend unit: 145/145 (15 suites)
  • Backend e2e: 63/63 (known flaky "rate-limits sign-in" returned 401 instead of 429 once and passed on re-run)
  • Frontend: 121/121
  • Build and typecheck: OK

Live smoke

Passed 51 of 51 checks against the rebuilt stack through nginx with Mailpit, 0 JS errors on 7 rendered pages. Covered group CRUD and duplicate names, single and bulk membership, CSV import with groups, group segment rules, contact profile groups and matching segments, group-filtered list and export, multi-target audience with overlap and exclusion (exactly one email per expected recipient, none for excluded or untargeted contacts), delete protection, sample-data test sends, report audience snapshot, duplicate, and legacy segmentId compatibility.

Closes #55
Closes #56
Closes #57
Closes #58
Closes #59
Closes #60
Closes #61

## Summary Phase 12.5: contact groups (v0.14.0). - Groups: hand-managed contact lists per project, with Groups and group pages, paged and searchable members, and add/remove by id or by contacts filter. - Contact profile shows the contact's groups (removable chips, add to existing or new group) and the segments they match now. - Contacts list: group filter (also on export), Groups column, row/page/all-matching selection, bulk add to and remove from group. - Import, export, and forms: CSV `groups` column on import and export, add everyone in a file to chosen groups, sign-up forms can add subscribers to groups. - Campaign audiences: include several groups and segments, exclude others, live count, each contact emailed once, audience recorded at send time and shown in the report. Groups and segments used by unsent campaigns can't be deleted. - Segment rule "Group is in / is not in"; builder containers renamed to blocks. - Phase 12 review fixes: test emails use sample data (Jane Doe) by default or a chosen contact; Duplicate keeps the web view setting and the audience. - Migrations: `contact_groups` (additive) and `campaign_audience` (moves `segmentId` into the audience, then drops the column). Back up the database before upgrading. - Release: CHANGELOG [0.14.0], README features, backend and frontend versions bumped to 0.14.0. ## Tests - Backend unit: 145/145 (15 suites) - Backend e2e: 63/63 (known flaky "rate-limits sign-in" returned 401 instead of 429 once and passed on re-run) - Frontend: 121/121 - Build and typecheck: OK ## Live smoke Passed 51 of 51 checks against the rebuilt stack through nginx with Mailpit, 0 JS errors on 7 rendered pages. Covered group CRUD and duplicate names, single and bulk membership, CSV import with groups, group segment rules, contact profile groups and matching segments, group-filtered list and export, multi-target audience with overlap and exclusion (exactly one email per expected recipient, none for excluded or untargeted contacts), delete protection, sample-data test sends, report audience snapshot, duplicate, and legacy `segmentId` compatibility. Closes #55 Closes #56 Closes #57 Closes #58 Closes #59 Closes #60 Closes #61
Groups CRUD, members, bulk add/remove (ids or matching filter, BULK_RATE_LIMIT); contact list/detail/export group fields and filter; CSV import groups column and addToGroupIds; form group links; campaign include/exclude groups and segments with SQL counts, send-time snapshot, legacy segmentId compatibility; 409 on deleting groups/segments used by unsent campaigns; segment 'group' rule; test sends use sample data; Duplicate keeps publicLink and audience. Migrations 20261016100000_contact_groups and 20261016110000_campaign_audience.

Verified: docker compose run --rm --build -T backend-test (unit 138 passed, e2e 63 passed, no drift on legacy and fresh paths).

Refs #55 #56 #57 #58 #59 #60 #61
Groups and group pages; contact profile group chips and matching segments; contacts list group filter, column, selection, and bulk actions; import groups column and options; form group picker; campaign editor include/exclude lists with live count, spelled-out confirmations, and sample-data test sends; campaign list and report audience; segment builder Group field and 'block' wording; ApiError with status.

Verified: docker compose run --rm --build -T frontend-test (23 files, 121 tests passed; build and type-check pass).

Refs #55 #56 #57 #58 #59 #60 #61
Refs #55 #56 #57 #58 #59 #60 #61
vmanne-poc deleted branch phase-12.5 2026-10-19 12:02:12 -04:00
Sign in to join this conversation.
No reviewers
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
vmanne-poc/Postak!62
No description provided.