Skip to content

✨ feat(repository,cli): add namespace registry with DynamoDB records and CLI commands#382

Merged
sodre merged 3 commits into
mainfrom
feat/369-namespace-registry
Feb 14, 2026
Merged

✨ feat(repository,cli): add namespace registry with DynamoDB records and CLI commands#382
sodre merged 3 commits into
mainfrom
feat/369-namespace-registry

Conversation

@sodre

@sodre sodre commented Feb 14, 2026

Copy link
Copy Markdown
Member

Summary

  • Add seven namespace lifecycle methods to Repository: register_namespace, register_namespaces, list_namespaces, delete_namespace, recover_namespace, list_orphan_namespaces, and purge_namespace
  • Add full namespace CLI subcommand group with register, list, show, delete, recover, orphans, and purge commands
  • Implement bidirectional name-to-ID registry using forward (#NAMESPACE#) and reverse (#NSID#) DynamoDB records under the reserved _/SYSTEM# partition
  • Support soft-delete with optional purge: deletion is O(1) (removes forward record, marks reverse as deleted), purge queries GSI4 and batch-deletes orphaned data
  • Support concurrent bulk registration via register_namespaces() using asyncio.gather / _run_in_executor
  • Reserved namespace _ is rejected with ValueError across all operations
  • Comprehensive unit and integration test coverage for all repository methods and CLI commands

Test plan

  • Unit tests for all seven repository methods (tests/unit/test_namespace_registry.py)
  • Unit tests for all CLI namespace commands (tests/unit/test_cli.py)
  • Integration tests for namespace lifecycle (tests/integration/test_namespace_registry.py)
  • uv run pytest tests/unit/ passes
  • uv run mypy src/zae_limiter/ passes
  • Sync code generation is up-to-date (hatch run generate-sync)

Closes #369

🤖 Generated with Claude Code

sodre and others added 2 commits February 14, 2026 09:46
…tration (#369)

Add full namespace lifecycle management (register, list, delete, recover,
purge) with CLI commands. Extend sync code generator to handle
asyncio.gather(*iterable) pattern, enabling concurrent bulk registration
in both async and sync variants via _run_in_executor with default-arg
capture lambdas.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ommands

Add pagination tests for list_namespaces, list_orphan_namespaces, and
purge_namespace GSI4 queries. Cover reserved namespace edge case in
recover_namespace. Add 44 CLI tests for all namespace subcommands
including error branches and validation errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sodre sodre added this to the v0.10.0 milestone Feb 14, 2026
@sodre sodre added area/cli Command line interface area/limiter Core rate limiting logic labels Feb 14, 2026
@sodre sodre self-assigned this Feb 14, 2026
@codecov

codecov Bot commented Feb 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.82%. Comparing base (bbc8120) to head (d50be2b).
⚠️ Report is 11 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #382      +/-   ##
==========================================
+ Coverage   91.48%   91.82%   +0.33%     
==========================================
  Files          33       33              
  Lines        7118     7385     +267     
==========================================
+ Hits         6512     6781     +269     
+ Misses        606      604       -2     
Flag Coverage Δ
doctest 27.13% <4.46%> (-1.32%) ⬇️
e2e 40.46% <17.55%> (-1.62%) ⬇️
integration 48.53% <45.53%> (-0.69%) ⬇️
unit 91.56% <100.00%> (+0.31%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/repository_protocol.py Dismissed
Comment thread src/zae_limiter/sync_repository_protocol.py Dismissed
Comment thread src/zae_limiter/sync_repository_protocol.py Dismissed
Comment thread src/zae_limiter/sync_repository_protocol.py Fixed
@sodre

sodre commented Feb 14, 2026

Copy link
Copy Markdown
Member Author

Review: PR #382 — Namespace Registry + CLI (#369)

All 47 acceptance criteria verified against issue #369. CI green across all checks.

Acceptance Criteria Summary

Section Criteria Status
register_namespace 7 criteria All pass
register_namespaces 5 criteria All pass
list_namespaces 3 criteria All pass
delete_namespace 5 criteria All pass
recover_namespace 6 criteria All pass
list_orphan_namespaces 2 criteria All pass
purge_namespace 6 criteria All pass
Sync + CLI 13 criteria All pass

Code Quality Notes

  • Forward + reverse records now include GSI4PK, GSI4SK, and created_at on both records — fixes the missing attributes from _register_namespace()
  • generate_sync.py: Correctly handles starred args (asyncio.gather(*[expr for x in iter])self._run_in_executor(*[lambda x=x: expr for x in iter])) with default-arg capture to avoid late-binding closure bug
  • purge_namespace: GSI4 KEYS_ONLY projection is correct — only PK/SK needed for BatchWriteItem DeleteRequests
  • recover_namespace: Defensive ConditionExpression: attribute_not_exists(PK) on forward record re-creation handles name collision race

Test Coverage

  • Unit: 613 lines — all methods + pagination + edge cases
  • CLI: 686 lines — all 7 commands + help + error paths
  • Integration: 309 lines — full lifecycle with LocalStack
  • Pagination covered for all three paginated operations

One Observation (Non-Blocking)

namespace show CLI uses repo._get_client() directly instead of a public Repository method. Works correctly and tests cover it — a get_namespace() method could be added later if needed.

Closes #369. Ready to merge.

🤖 Generated with Claude Code

Replace direct _get_client() usage in `namespace show` CLI command
with a proper Repository.get_namespace() method.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread src/zae_limiter/repository_protocol.py Dismissed
@sodre sodre marked this pull request as ready for review February 14, 2026 17:45
@sodre sodre merged commit d808008 into main Feb 14, 2026
27 checks passed
@sodre sodre deleted the feat/369-namespace-registry branch February 14, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cli Command line interface area/limiter Core rate limiting logic

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Namespace registry with DynamoDB records and CLI management commands

1 participant