feat: add pools for resolving groups of names by key - #9
Merged
Conversation
A pool is a named list of names sharing one field (service), defined in a separate pools.yml. Given a pool and an asked service, the service resolves every member through the existing QueryService. - Domain: Pool (getField/getNames), PoolQueryRepository (findByName), and PoolService (QueryService injected). `whatAreTheNamesOf` returns one answer per member, index-aligned and string|array|null, mirroring QueryService::whatAreTheNamesOf so callers get 207 semantics. `whoseNamesAreThere` flattens those answers into a distinct list (arrays spread in, nulls and duplicates dropped). When the asked service is the pool's own field, its names are returned verbatim. - Infrastructure: PoolYamlFileRepository replicates YamlFileRepository's mtime-based caching, indexing pools by name. - API: GET /whose-name/pool (per-member, 200/207/404) and GET /whose-name/pool/names (flattened distinct, 200/404). Both GET and lenient like the single query endpoint. - Wiring: WHOSENAME_POOLS_YAML config + PoolQueryRepository binding. - Docs: README Pools section and an ADL for the endpoint status/shape. Tests cover the domain (per-member shape, null kept vs dropped, dedup, same-field shortcut), the repository (find, cache, missing file), an end-to-end integration, and both endpoints. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Introduces pools — a named list of names sharing one field (service), resolvable as a group.
A pool is defined in a separate
pools.yml:Given a pool and an asked service,
PoolServiceresolves every member through the existingQueryService.Domain (
domain/WhoseName/)Pool— value object:getField(): string,getNames(): array.PoolQueryRepository— interface:findByName(string): Pool(emptyPoolon a miss, likeIdentityQueryRepository).PoolService— takesPoolQueryRepository+QueryService:whatAreTheNamesOf($pool, $service)— one answer per member, index-aligned, eachstring|array|null, mirroringQueryService::whatAreTheNamesOfsonulls are kept and callers get 207 semantics.whoseNamesAreThere($pool, $service)— those answers flattened into a distinct list (arrays spread in,nulls and duplicates dropped).Infrastructure
PoolYamlFileRepository— replicatesYamlFileRepository's mtime-based cache, indexing pools by name.API
GET /api/whose-name/pool?p=&q=— per-member:[{"username": ...}, …], 200/207/404 (parallels the batch query endpoint).GET /api/whose-name/pool/names?p=&q=— flattened distinct:{"names": [...]}, 200/404.Both are
GETand lenient (emptyp/q→404, not422), matching the single query endpoint. Route closures stay thin HTTP↔domain maps; all logic lives inPoolService.Wiring & docs
WHOSENAME_POOLS_YAMLconfig (defaulttests/pools.yml) +PoolQueryRepository => PoolYamlFileRepositorybinding.docs/adl/2026-07-08-pool-endpoints-status-and-shape.mdrecords the per-member-vs-flattened split, the lenient404-on-empty choice, and rejected alternatives.Testing
Full suite passes via
./vendor/bin/sail test— 51 passed, 2 skipped (pre-existing filesystem-atime skips). New coverage:nullkept vs dropped, dedup, same-field shortcut, empty pool.PoolService+ real repos test.Note
Builds on the merged multi-name feature, so it carries the
string|array|nullreturn type. The PHP 8.0-FPM / Laravel-upgrade decision (Laravel 9 doesn't run on PHP 8.5) still applies at deploy time.🤖 Generated with Claude Code