Files
computer-playbook/docs/contributing/design
kevinveenbirkenbachandClaude Opus 4.7 f7eb65a682 fix(web-app-mig,web-app-sphinx)+test: container_port pointed at non-existent flat .port key, add wildcard-path validator
Both `roles/web-app-mig/vars/main.yml` and
`roles/web-app-sphinx/vars/main.yml` resolved `container_port` via
`lookup('config', application_id, 'services.' ~ entity_name ~ '.port')`,
but neither role's `meta/services.yml` declares a flat `port` key —
they declare `services.<entity>.ports.{inter, local.http}`. Deploy on
arch crashed at compose-template render time with
`The lookup plugin 'config' failed: Key 'port' not found in dict`
(GHA universal-deploy run 25028370090 jobs 73306260785 + 73306260788).
Match the convention used by web-app-listmonk / -gitea / -shopware
and read `services.<entity>.ports.inter` instead.

The existing `tests/integration/lookups/test_config_paths.py`
literal-path scanner only captures the first quoted segment of a
`lookup('config', ...)` call, so `~`-concatenated paths (where a
Jinja variable expands inside the dotted path) were validated only
as wildcard prefixes. That contract is too loose: any role with a
top-level `services` dict satisfied
`'services.' ~ entity_name ~ '.port'`, even when the resolved path
did not exist for the specific role.

Add a `test_wildcard_paths` method that:

- captures the entire path expression in any
  `lookup('config', <app>, <expr>)` whose `<expr>` contains `~`,
- parses the expression token by token, treating quoted strings as
  literals and any bareword between `~` markers as `*`,
- joins the parts and splits on `.` into a wildcard path
  (for example `'credentials.' ~ X ~ '_jwt_secret'` becomes
  `credentials.*_jwt_secret`),
- resolves the role from the file's `roles/<role>/...` path when
  the lookup's app argument is a Jinja variable,
- validates the wildcard path through the same fallback chain as
  the literal-path test (application defaults -> users defaults
  -> credentials in defaults / schema -> images presence), with
  per-segment fnmatch globbing so partial-segment wildcards like
  `*_jwt_secret` resolve correctly.

Verified: reverting the two role fixes makes the new test report
`'services.*.port' has no match in application defaults / schema for
role 'web-app-mig'` (and the same for sphinx) with file/line refs.
Restoring the fixes turns it green again.

Also drop one extra `..` segment from three relative links in
`docs/contributing/design/inventory.md` so the markdown lint check
passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:54:10 +02:00
..
…

Design 🎨

This directory contains contributor guidance for code design and implementation. Its scope is architecture, service wiring, coding principles, exceptions, and the boundaries that shape maintainable changes.