Repository navigation
fix(clients): search GetManyClients by SearchTerm not whole request - #88
Merged
Merged
Conversation
|
View your CI Pipeline Execution ↗ for commit 3cc6a03
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
brinehart
commented
Nov 2, 2026
brinehart
left a comment
Collaborator
Author
There was a problem hiding this comment.
Review — Must Fix #50 (client search filters on search term)
Reviewed against .kiro/specs/must-fix-50/spec.md, judging on the orchestrator-approved provider-agnostic predicate (not literal EF.Functions.ILike).
Correctness — all checks pass:
- ✅ Filter uses the search term, not the whole request.
$"%{request}%"(which stringified the protobuf debug message) is replaced byc.Name.ToLower().Contains(request.SearchTerm.ToLower()). Root-cause fix for #50. - ✅ Case-insensitive + match-all on null/empty. Guard changed to
!string.IsNullOrEmpty(request.SearchTerm); null and empty skip the predicate → all clients of the type. Faithful (and slightly safer) realization of the spec's stated behavior — also avoids.ToLower()on null. - ✅ Provider-agnostic translation.
ToLower()/Contains()translates toLOWER()/strposon Npgsql and evaluates under the EF Core InMemory provider — the point of the approved deviation. PostgreSQL behavior unchanged vsILike. - ✅ Test coverage. Five xUnit tests: matching term, case-insensitivity, non-matching term, empty term (all), null term (all). Matches the spec test plan and adds the empty-string case.
- ✅ Scope held to search. Production diff touches only the search-filter if-block; paging (
page/skip/NextUrl, #51) is untouched. - ✅ CI green. Both
dotnetandmainchecks pass.
Non-blocking notes (no action required for #50):
- The
TestServerCallContexthelper and theAliasOAuth2GrpcTypesMSBuild target (resolving the CS0433 ambiguity between the two assemblies that compileclient.proto) are reasonable, well-commented test-only scaffolding. - The
format:checkdebt on sibling spec markdown is pre-existing on the base branch and correctly left as an epic-wide cleanup.
The fix satisfies the spec intent and checks are green.
Collaborator
Author
|
ALL-CLEAR — #50 fully satisfies the spec intent (search by SearchTerm, case-insensitive, null/empty = match all, paging untouched), tests cover match/case-insensitive/non-match/empty/null, and CI is green (dotnet + main). |
The name filter in GetManyClients interpolated the entire ManyClientsRequest
message into the ILike pattern ($"%{request}%"), so every search compared
client names against the protobuf debug string and returned nothing. Filter on
request.SearchTerm instead.
Replace the Npgsql-only EF.Functions.ILike with a provider-agnostic,
case-insensitive predicate (c.Name.ToLower().Contains(term.ToLower())) so the
fix is covered by a unit test under the EF Core InMemory provider without
requiring PostgreSQL (AGENTS.md forbids it). Behavior is identical on Postgres:
Npgsql translates ToLower()/Contains() to SQL LOWER()/strpos. Null or empty
search term matches all clients of the type (guarded).
Adds InMemory tests: matching term returns the right clients, case-insensitive
match, non-matching term returns none, empty and null terms return all. The
test csproj aliases the transitive MicroZen.OAuth2 assembly to resolve the
duplicate MicroZen.Grpc.V1 types it compiles from the shared proto.
Scope: search filter only; paging is #51 on a separate branch.
Closes #50
brinehart
force-pushed
the
fix/must-fix-50
branch
from
November 2, 2026 03:50
ceed1bf to
3cc6a03
Compare
brinehart
added a commit
that referenced
this pull request
Nov 2, 2026
) The name filter in GetManyClients interpolated the entire ManyClientsRequest message into the ILike pattern ($"%{request}%"), so every search compared client names against the protobuf debug string and returned nothing. Filter on request.SearchTerm instead. Replace the Npgsql-only EF.Functions.ILike with a provider-agnostic, case-insensitive predicate (c.Name.ToLower().Contains(term.ToLower())) so the fix is covered by a unit test under the EF Core InMemory provider without requiring PostgreSQL (AGENTS.md forbids it). Behavior is identical on Postgres: Npgsql translates ToLower()/Contains() to SQL LOWER()/strpos. Null or empty search term matches all clients of the type (guarded). Adds InMemory tests: matching term returns the right clients, case-insensitive match, non-matching term returns none, empty and null terms return all. The test csproj aliases the transitive MicroZen.OAuth2 assembly to resolve the duplicate MicroZen.Grpc.V1 types it compiles from the shared proto. Scope: search filter only; paging is #51 on a separate branch. Closes #50 Co-authored-by: brinehart <ben.rinehart@avifoodsystems.comc>
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.
Closes #50
Summary
GetManyClientsinterpolated the entireManyClientsRequestmessage into theILikepattern ($"%{request}%"), so every search compared client names againstthe protobuf debug string of the request and returned nothing. The filter now uses
request.SearchTerm.Intentional deviation from the spec's one-liner
The spec (
.kiro/specs/must-fix-50/spec.md) prescribed a one-line change keepingEF.Functions.ILikeand testingGetManyClientsunder the EF Core InMemoryprovider. That test path is impossible:
EF.Functions.ILikeis the Npgsql-onlyNpgsqlDbFunctionsExtensions.ILike. I verified it throws under both the InMemoryprovider (
ILike ... is not supported, query switched to client-evaluation) and theSqlite provider (
Translation of NpgsqlDbFunctionsExtensions.ILike failed). Only areal PostgreSQL provider translates it, and
AGENTS.mdstates the test suite isself-contained and needs no PostgreSQL.
Per the orchestrator's decision (Option B, scoped), the production filter was changed
from the Npgsql-only
EF.Functions.ILiketo a provider-agnostic, case-insensitivepredicate:
This is the faithful, testable equivalent of
ILike: Npgsql translatesToLower()/Contains()to SQLLOWER()/strpos, so behavior on PostgreSQL isunchanged, while the InMemory provider the test suite uses can evaluate it in memory.
Reviewer: expect the predicate form to differ from the spec's one-liner — this is the
deliberate reason.
Empty / null search term
Guarded with
!string.IsNullOrEmpty(request.SearchTerm)soToLower()is never calledon null, and a null or empty term skips the filter entirely → all clients of the
requested type are returned. Matches the spec's stated behavior.
Tests (EF Core InMemory, per spec)
Added
ClientsGrpcServiceGetManyClientsTests:A small
TestServerCallContextprovides a no-opServerCallContext. The test csprojadds a build target aliasing the transitive
MicroZen.OAuth2assembly, because itcompiles the same
client.protoasMicroZen.Apiand would otherwise make theMicroZen.Grpc.V1.*types ambiguous (CS0433) in test code.Scope
Search-term filter only. Paging is untouched (that is #51 on a separate branch).
Conflicts at epic-merge time are expected; the orchestrator rebases.
CI gate (run locally from the worktree)
npx nx affected -t lint test build→ green (lint clean, 16/16 tests pass, build ok)dotnet test core/csharp/MicroZen.Core.sln→ 16/16 pass