feat: create consumer group bound to a topic#11
Merged
Conversation
added 10 commits
July 9, 2026 13:11
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Adds ErrGroupExists, CreateGroupRequest, and Registry.CreateGroup in admin_groups.go. CreateGroup prechecks via adm.ListGroups that the target group does not already exist, rejects the shift-by strategy (a new group has no prior commit to shift from), and otherwise delegates offset resolution/clamping/commit to the shared resolveAndCommit helper extracted from ResetOffsets. Also fixes a pre-existing bug in TestIntegration_ResetOffsets (integration_extended_test.go:161) that referenced the not-yet-declared `err` instead of the retry loop's `lastErr`, which kept the file from compiling under -tags=integration; fixing it was a prerequisite to compile-verify the new TestIntegration_CreateGroup added here. Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Wire kafka.Registry.CreateGroup (Task 2) into the HTTP layer: register
POST /clusters/{cluster}/groups, add the createGroup handler mapping
ErrUnknownCluster->404, ErrGroupExists->409, validation errors->400,
else->502, and document the operation in openapi.yaml. Also map the
new route in resolvePermission so RBAC-enabled deployments enforce a
group:edit check on create instead of silently bypassing it (same gap
would otherwise exist as the sibling groups routes).
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
The datetime-local input in create-group-modal previously rendered
with toISOString() (UTC) but parsed with new Date() (local), causing
the submitted timestamp_ms to drift by the local UTC offset in any
non-UTC timezone. Extract the local-time round-trip helpers
(msToLocalInput/localInputToMs) already used by reset-offsets-modal
into a shared frontend/src/lib/datetime.ts and reuse them here.
Also fix a latent display bug where an empty timestampMs string was
treated as epoch 0 (Number("") === 0 is finite) instead of blank,
which surfaced while adding a timestamp round-trip test.
Strengthen the "confirming create" test to assert the
topic-consumers query invalidation and that onClose fires after
onCreated, and add a timestamp-strategy round-trip test guarding the
timezone fix.
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
…estamp error - rbacMiddleware now derives the resource name from a resolvePermission- supplied body field (topics: "name", groups: "group_id"), so creating a consumer group authorizes against the specific group_id. A user with only group:billing-*:edit can no longer create group payments-prod; cluster-wide group:*:edit still authorizes any group_id. - CreateGroup pre-validates timestamp_ms so the error reads "create group: ..." instead of the shared "reset offsets: ..." prefix. Signed-off-by: FinkeFlo <florian.kube@gmail.com>
…fetch
- create-group-modal offsetValid now uses Number.isInteger so "1.5" disables
Preview/Create instead of sending a float that fails the Go int64 decode.
- consumers route drops onCreated={query.refetch()}; the modal's
invalidateQueries already refetches the active topic-consumers query, so the
list no longer double-fetches on create.
Signed-off-by: FinkeFlo <florian.kube@gmail.com>
Creating a consumer group is non-destructive (the backend returns 409 if the group already exists) and the modal already offers a dry-run Preview, so the nested ConfirmDialog only produced a confusing stacked-modal look (two centered same-size panels overlapping). Create now commits directly; Preview remains the review step. Button feedback is scoped per action via mutation.variables so only the clicked action shows its pending state. Signed-off-by: FinkeFlo <florian.kube@gmail.com>
FinkeFlo
force-pushed
the
feat/create-consumer-group
branch
from
July 9, 2026 16:00
e52d4b6 to
68d1f5d
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
Adds the ability to create a new consumer group bound to a single topic directly from kafkito. A group is created by committing initial offsets for all partitions of the chosen topic under a start strategy (default latest), so the group exists and is anchored at a known position before its consumer app is deployed.
In Kafka a group has no standalone "create" primitive — it exists once it has committed offsets — so this feature commits initial offsets for a not-yet-existing group name. Note that a group with no active consumer expires after
offsets.retention.minutes; the UI surfaces this.Changes
Backend (
pkg/kafka,internal/server)ResetOffsetsinto a sharedresolveAndCommit(behavior-preserving refactor).CreateGroup+ErrGroupExists: validates input, rejectsshift-by(no prior offset to shift from on a new group), prechecks the group does not already exist, then delegates toresolveAndCommit.POST /clusters/{cluster}/groups→ 200 / 409 if the group exists / 400 on validation / 404 unknown cluster.POST /groupsis authorized against thegroup_idfrom the request body (name-scoped, parity with delete/reset-offsets), via an explicitbodyFieldon the permission mapping.Frontend
createGroupAPI client.CreateGroupModalwith a dry-run preview of the resulting per-partition offsets, strategy selector (earliest/latest/timestamp/offset, default latest), and an expiry notice.msToLocalInput/localInputToMsdatetime helpers intofrontend/src/lib/datetime.ts(fixes a UTC-vs-local timestamp bug and is now shared with the reset-offsets modal).Testing
make test(Go unit) — green across all packages.vitest— 259 passing;build,typecheck, andcheck:strings/tokens/routesclean.TestIntegration_CreateGroup(create at latest / listing / re-create →ErrGroupExists/shift-byrejected / dry-run does not create) is compile-verified only — it needs Docker/testcontainers, so please let CI run the-tags=integrationsuite.err→lastErrbug inTestIntegration_ResetOffsetsthat broke compilation under-tags=integration.