Skip to content

feat: support multiple names per field in an identity - #8

Merged
dragonee merged 1 commit into
mainfrom
feat/multiple-names-per-field
Jul 8, 2026
Merged

feat: support multiple names per field in an identity#8
dragonee merged 1 commit into
mainfrom
feat/multiple-names-per-field

Conversation

@dragonee

@dragonee dragonee commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Introduces multiple names per field in an identity. A service field may now hold a list of names instead of a single scalar:

-
  slack: U234567
  email:
    - other@example.org
    - new@example.org
  • Lookups match any listed name — querying by other@example.org or new@example.org on email resolves the same identity.
  • Answers return the whole list — asking for a multi-name field returns the array of names.

Changes

  • QueryService::whatIsTheNameOf() and Identity::username() now return string|array|null: a string for single-name fields, an array when the asked service holds several, null for a miss. whatAreTheNamesOf() (batch) returns an index-aligned list of those answers.
  • YamlFileRepository::transformIdentityListToIndex() indexes every name under a field (foreach ((array) $value as $name)), so a query by any one of them resolves the identity. A scalar is treated as a one-element list, so single-name data is unchanged.
  • The HTTP layer needed no code change: JSON encodes arrays natively and the status logic keys only on null, so both the single (200/404) and batch (200/207) endpoints keep their {"username": ...} envelope; the value simply widens to include a JSON array.
  • README updated (intro example, glossary, usage + batch sections) and a new ADL added: docs/adl/2026-07-08-multiple-names-per-field.md.

Compatibility

  • Backward compatible for single-name data — existing files, queries, and responses behave exactly as before; a response only becomes an array when the asked field is itself a list.
  • ⚠️ Contract widening: username is now string-or-array. String-only clients (e.g. whose-name-client) must be updated before they consume multi-name fields.

Testing

Full suite passes via ./vendor/bin/sail test32 passed, 1 skipped (pre-existing filesystem-atime skip). New tests cover the array response and search-by-any-entry across the domain, infrastructure, and application layers.

🤖 Generated with Claude Code

A service field may now hold a list of names, not just a scalar. Lookups
match any of the listed names, and answers return the whole list.

- `QueryService::whatIsTheNameOf` and `Identity::username` now return
  `string|array|null`: a string for single-name fields, an array when the
  asked service holds several, `null` for a miss.
- `YamlFileRepository` indexes every name under a field so a query by any
  one of them resolves the identity; a scalar is treated as a one-element
  list, keeping single-name data unchanged.
- The HTTP layer keeps its `{"username": ...}` envelope and 200/404 and
  200/207 status semantics; the value simply widens to include a JSON array.

Backward compatible for single-name data. Documented in the README and a
new ADL. Note: `username` is now string-or-array, a widening of the API
contract that string-only clients must handle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dragonee
dragonee merged commit 88b1687 into main Jul 8, 2026
1 check passed
@dragonee
dragonee deleted the feat/multiple-names-per-field branch July 8, 2026 19:06
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.

1 participant