feat(cohort): generic reusable external target catalog and picker#371
Open
jorisjonkers-dev-agents[bot] wants to merge 3 commits into
Open
feat(cohort): generic reusable external target catalog and picker#371jorisjonkers-dev-agents[bot] wants to merge 3 commits into
jorisjonkers-dev-agents[bot] wants to merge 3 commits into
Conversation
added 3 commits
June 30, 2026 11:01
…stems Introduce a system-agnostic CohortTarget core: one TargetStrategy port (with a TargetDescriptor carrying kind, labels and capabilities), a TargetStrategies facade, and a generic TargetCatalog + controller. Brevo becomes one strategy; adding Discord/Google is one strategy class plus a TargetSystem value, not a new table/service/picker. The kindFor(system) switches in targeting and provisioning are removed — kind comes from the strategy descriptor.
Replace the Brevo-specific picker with one component driven by each system's target descriptor: the CATALOG capability renders a searchable combobox (fetched once, filtered client-side), otherwise a manual id field, with create/folder fields shown per capability. One picker serves Brevo lists, and future Discord roles / Google groups, with no per-system branches.
8e20a0e to
b05d3a1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
External cohort targets — Brevo lists today, Discord roles and Google Workspace groups next — are now one generic, reusable abstraction with a single picker, instead of Brevo-specific tables, services, and UI.
TargetStrategyport: each external system implementscatalog/resolve/members/add/remove/create/deleteand exposes aTargetDescriptor(kind, labels, capabilities). A smallTargetStrategiesfacade resolves the strategy for a system.TargetSystemstays a plain enum; the descriptor lives on the strategy so the shared kernel keeps no dependency on cohort types.TargetCatalogservice +CohortTargetController(GET /management/cohort-targets/{system}and/systems) returns named, human-readable options annotated with whether each is already linked. Provider calls run outside DB transactions.BrevoTargetStrategyis the one live provider (folder/list paging, members via the existing contact-list adapter). Adding Discord or Google is one strategy class plus aTargetSystemvalue — no new table, sync job, query service, or picker branch.kindFor(system)switches are gone; target kind comes from the descriptor.linkExisting/switchTargetvalidate against the strategy but allow record-only binding when an id is not in the fetched catalog, so a paste-in id still works.CATALOGcapability renders a searchable combobox (fetched once, filtered client-side), otherwise a manual id field, with create/folder fields shown per capability.No shadow tables: target options are fetched live and filtered client-side. A generic cache can be added later if a provider's volume requires it.
Verification
./gradlew :services:api:test --tests '*Target*' --tests '*cohort*'— 123 passed (the full suite's OIDC/Vault security tests cannot run in the local sandbox; they pass in CI).git diff --exit-codeclean.