Skip to content

fix(featureflag): make create idempotent to stop duplicate-key crash - #354

Merged
resamsel merged 3 commits into
mainfrom
fix-duplicate-feature-flag-create
Sep 18, 2026
Merged

resamsel merged 3 commits into
mainfrom
fix-duplicate-feature-flag-create

Conversation

@resamsel

Copy link
Copy Markdown
Owner

Summary

  • FeatureFlagService.create() now checks for an existing (user_id, feature) flag via UserFeatureFlagRepository.findByUserAndFeature() and updates it in place instead of blindly persisting, which previously threw a duplicate key constraint violation on ix_user_feature_flag_user_id_name when the flag already existed (e.g. toggling theme-switcher twice).
  • Response status stays HTTP 200 in both the new-flag and updated-flag cases, matching the current openapi.yaml contract exactly — no codegen or contract changes needed.
  • A 201 (new) / 200 (updated) status split was considered but dropped: the generated UserFeatureFlagsApi interface returns a plain FeatureFlagDto because build.gradle.kts sets the jaxrs-spec generator's returnResponse option to false project-wide. Enabling a dynamic per-call status code would require flipping that globally, changing every generated resource interface's method signature across the app. Tracked separately as #353.
  • Added OpenSpec change fix-duplicate-feature-flag-create (proposal/specs/design/tasks), now archived, and synced a new user-feature-flags main spec documenting the idempotent-create and update-by-ID requirements.

Test plan

  • Unit tests in FeatureFlagServiceTest: new-pair create persists a new flag; existing-pair create updates in place instead of persisting.
  • Integration tests in FeatureFlagResourceTest (real @QuarkusTest + Postgres): create-new, create-existing (200 + same ID), repeated identical POSTs, and a dedicated theme-switcher regression test recreating the exact flag from the original bug report.
  • ./gradlew test — full suite green, no regressions.
  • openspec validate --specs — 7/7 pass.

🤖 Generated with Claude Code

renepanzar and others added 3 commits September 18, 2026 21:13
Fixes duplicate key constraint violation when creating a feature flag
that already exists for a user (e.g. theme-switcher). Adds openspec
change proposal/specs/design/tasks deciding on idempotent create
(update-on-duplicate, 201 for new / 200 for existing) and TDD-red
tests exercising the new contract ahead of implementation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
FeatureFlagService.create() now checks for an existing (user_id, feature)
flag via the repository's findByUserAndFeature() and updates it in place
instead of blindly persisting, which previously threw a duplicate key
constraint violation on ix_user_feature_flag_user_id_name when recreating
an existing flag (e.g. toggling theme-switcher twice).

Dropped the originally planned 201/200 status-code split: the generated
UserFeatureFlagsApi interface returns a plain FeatureFlagDto because
returnResponse=false in build.gradle.kts, and enabling a dynamic status
would require flipping that project-wide, touching every resource
interface. Tracked separately as #353.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Moves the completed change to archive/2026-09-18-fix-duplicate-feature-flag-create
and syncs its delta spec into a new main spec at
openspec/specs/user-feature-flags/spec.md, documenting the idempotent
create requirement and the existing update-by-ID requirement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@resamsel
resamsel merged commit 3ecb0b0 into main Sep 18, 2026
6 checks passed
@resamsel
resamsel deleted the fix-duplicate-feature-flag-create branch September 18, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants