Claude-skill-registry add-bc-contract
Add Contract for inter-BC communication using Provider pattern. Use when one Bounded Context needs to access data from another BC (e.g., Inventory needs Articles from Admin). Creates Contract interface, Provider implementation, and configuration.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/add-bc-contract" ~/.claude/skills/majiayu000-claude-skill-registry-add-bc-contract && rm -rf "$T"
manifest:
skills/data/add-bc-contract/SKILL.mdsource content
Add BC Contract
Create Contract for inter-BC communication using Provider pattern.
When to Use
- BC needs to read data from another BC
- Creating select options from another BC (TwigComponent)
- Exposing domain data to other contexts
Inputs/Outputs
| Input | Example | Output |
|---|---|---|
| provider_bc | Admin | |
| consumer_bc | Inventory | |
| contract_name | ArticleProvider | (updated) |
| methods | ['provide', 'provideAll'] | (updated) |
Process
| Step | File | Action |
|---|---|---|
| Contract | | Interface with methods (template: ) |
| Provider | | Implementation with Finder (template: ) |
| Config | | Autowire Contract → Provider |
| Deptrac | | Allow ProviderBC\Contracts |
| Validate | - | |
Structures
Contract (interface in
ProviderBC/Contracts/):
interface ContractName { public function provide(string $uuid): EntityData; // throws public function provideAll(?array $ids = null): iterable; }
Provider (
readonly, uses Finder):
final readonly class ProviderBCContractName implements ContractName { public function __construct(private EntityFinder $finder) {} // Finder, NOT Repository public function provide(string $uuid): EntityData { $entity = $this->finder->find($uuid) ?? throw EntityNotFound::fromUuid($uuid); return $this->toData($entity); } public function provideAll(?array $ids = null): iterable { $entities = $ids ? $this->finder->findByUuids($ids) : $this->finder->findAll(); foreach ($entities as $entity) { yield $this->toData($entity); } } private function toData(Entity $entity): EntityData { /* convert to DTO */ } }
Config (
ProviderBC/Frameworks/config/services.yaml):
ProviderBC\Contracts\ContractName: class: ProviderBC\Adapters\Contracts\ProviderBCContractName
Deptrac (
ConsumerBC/Frameworks/deptrac.yaml):
ConsumerBC\Adapters: - ProviderBC\Contracts # ONLY Contracts, NOT Entities/UseCases
See:
docs/GLOSSARY.md#contract, #provider, #data-dto
Rules
CRITICAL:
- Provider uses Finder (NOT Repository) - providers are read-only
- Consumer depends ONLY on Contract interface (never Provider implementation)
- Deptrac allows ONLY
namespace (not Entities/UseCases)Contracts
Locations:
- Contract:
ProviderBC/Contracts/ - Provider:
ProviderBC/Adapters/Contracts/ - Exception:
if neededProviderBC/Contracts/Exception/ - DTO:
if complex dataProviderBC/Contracts/DTO/
Naming:
- Contract:
(e.g., ArticleProvider){Entity}Provider - Provider:
(e.g., AdminArticleProvider){BC}{Contract}
Variants
Query Provider (data access):
public function provide(string $uuid): EntityData; public function provideAll(?array $ids = null): iterable;
TwigComponent Provider (form select):
/** @return array<string, string> [uuid => label] */ public function getAllForChoice(): array;
Templates
- Contract interfacecontract.php.tpl
- Provider implementationprovider.php.tpl
Location:
.claude/templates/
References
- Contract/Provider pattern:
,docs/GLOSSARY.md#contract#provider - Inter-BC architecture:
docs/architecture.md#inter-bc - Detailed guide:
docs/guides/bounded-contexts.md