Repository navigation
feat(flag): Flag Description and Tags — Phase 2 - #64
Merged
Merged
Conversation
added 5 commits
May 12, 2026 19:56
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
Operators can attach a human-readable description and a set of lowercase
organizational tags to any feature flag. Both fields ride on the existing
per-environment
Flagrow (a deliberate pre-aggregate-split landing), arenormalized at the service boundary (trim + lowercase + dedupe for tags;
empty/whitespace description →
null), and flow throughIPromptSanitizerinto the AI flag-health analyzer payload. The change is purely additive on the
wire and in the database — existing clients and rows are unaffected.
Changes in this PR
feat(domain)—Flag.Description,Flag.Tags,Flag.UpdateMetadata(archived guard +
UpdatedAtbump)feat(app)— DTOs, validators (≤500 char description; ≤20 tags × ≤50 chars,char-class
^[a-z0-9\-_]+$on cleaned + lowercased), service-layernormalization, single
SaveChangesAsyncacrossReconfigure+UpdateMetadatafeat(infra)—TagListConverter,FlagConfigurationmapping withHasDefaultValueSql("'[]'"), zero-downtime additive migration, AI promptenrichment with
Description+Tagsdeclared inert in the system prompt,seed data on all six manifest entries, smoke-test.http demonstrating rich +
minimal create shapes and PUT clear/no-change semantics
test— 50 new unit/integration tests; 153 → 203 unit, 54 → 70 integrationdocs— spec + implementation notes; foundation docs refreshed; DDD backlogitems checked off
Spec
Docs/Decisions/flag-description-and-tags/spec.mdImplementation Notes
Docs/Decisions/flag-description-and-tags/implementation-notes.mdDefinition of Done
Domain
Flag.Description(string?) +Flag.Tags(IReadOnlyList<string>)description+tags; tags default to[]Flag.UpdateMetadatawith archived guard +UpdatedAtbumpApplication
CreateFlagRequest,UpdateFlagRequest,FlagResponsecarry the new fieldsFlagMappings.ToResponsepropagates description + tagsCreateFlagRequestValidatorenforces description/tag rulesUpdateFlagRequestValidatorenforces the same rules with null-tolerant guardsBanderasService.CreateFlagAsyncsanitizes description and normalizes tagsBanderasService.UpdateFlagAsynccallsReconfigurethen conditionallyUpdateMetadatawithin a singleSaveChangesAsyncBanderasService.AnalyzeFlagsAsyncprojection sanitizes description and tagsInfrastructure
TagListConverteratBanderas.Infrastructure/Persistence/FlagConfigurationmaps both columns with the documented constraintsAddFlagDescriptionAndTagsBanderasDbContextModelSnapshotregeneratedAiFlagAnalyzer.BuildPrompt+SystemPromptupdatedDatabaseSeeder.SeedManifestcarries realistic description + tagsTests
converter round-trip, AI prompt-projection sanitization
Build & CI
dotnet build -p:TreatWarningsAsErrors=truesucceedsdotnet csharpier check .passesdotnet test(unit + integration) all green locallyRequests/smoke-test.httpupdated for the new shapesTesting
Locally on a fresh devcontainer:
Then
docker compose up, point a.httprunner atRequests/smoke-test.http,and run the file top to bottom. Expected:
description+tagsechoed back.description: nullandtags: [].POST /api/flags/healthreturns 200 with assessments for every seed flag,and the analyzer payload contains sanitized description + tags.