refactor: domain-first module restructuring with DIDKeySigner, error standardization, and HTTP layer extraction#1719
Draft
yshyn-iohk wants to merge 50 commits intomainfrom
Draft
refactor: domain-first module restructuring with DIDKeySigner, error standardization, and HTTP layer extraction#1719yshyn-iohk wants to merge 50 commits intomainfrom
yshyn-iohk wants to merge 50 commits intomainfrom
Conversation
7cf52e5 to
48fad88
Compare
Contributor
Contributor
Contributor
305677e to
12ec303
Compare
Rename all modules, packages, config sections, and infrastructure from internal codenames (mercury, pollux, castor, connect, agent.*) to domain-first names (didcomm, credentials, did, connections, etc.) following ADR 0001. Changes include: - Rename module directories from codenames to domain names - Rename SBT project IDs, artifact names, and dependency objects - Rename Scala packages throughout the codebase - Rename agent.* packages (walletapi, server, notification, vdr) - Move notification traits from core to API module - Align event.notification package to notifications - Rename config sections (pollux -> credentials, connect -> connections) - Rename env vars (POLLUX_DB_* -> CREDENTIALS_DB_*, etc.) - Rename SQL migration paths and Docker/Helm infrastructure - Remove unused re-export package.scala files - Remove stale codename build artifact directories - Remove duplicate and dead code files - Clean up import aliases and comments referencing old names - Update .github/labeler.yml and CI workflow for new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
12ec303 to
a6950f2
Compare
- Extract DIDKeySigner trait to did/api module with DIDKeySignerImpl in wallet-management, decoupling key resolution from VDR operations - Move PrismNodeVdrOperationSigner from api-server to vdr/prism-node, now depends on DIDKeySigner instead of ManagedDIDService - Standardize wallet-management errors to extend Failure with proper HTTP status codes, removing manual Conversion blocks - Create api-server-http-core module with shared HTTP infrastructure (ErrorResponse, EndpointOutputs, SecurityLogic, Authenticator, etc.) - Create notifications-http module as pilot for domain HTTP separation - Generalize EventServerEndpoints to use AuthenticatorWithAuthZ trait Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
Phase 16 of domain-first module restructuring: - Generalize DefaultAuthenticator to AuthenticatorWithAuthZ[BaseEntity] in all 13 ServerEndpoints companion objects - Extract 5 domain HTTP modules from api-server: credential-status-http, verification-http, vdr-http, connections-http, did-http (51 files moved) - Refactor ConnectionControllerImpl to take URL instead of AppConfig - Extract oid4vci-core module with IssuanceSession, Openid4VCIProofJwtOps, and IssuanceSessionStorage (3 files) - Decompose BackgroundJobsHelper (247 lines) into focused traits: DIDResolutionHelper, JwtIssuerHelper, DIDCommHelper Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
…coupling Extract system-http, didcomm-http, credential-schema-http, credential-definition-http, prex-http, oid4vci-http, api-server-controller-commons, issue-http, and presentproof-http from api-server/core (~90 files moved). Replace AppConfig dependencies with domain-specific config case classes (IssueControllerConfig, PresentProofControllerConfig, DIDCommControllerConfig, CredentialIssuerControllerConfig). Extract FeatureFlagConfig and PrismEnvelopeResponse to api-server-http-core. Reduces api-server/core from ~149 to 64 files. Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
Extract iam-core (authentication + authorization, 20 files), iam-entity-http (10 files), and iam-wallet-http (6 files) from api-server/core. Decouple config case classes (AdminConfig, ApiKeyConfig, KeycloakConfig) from AppConfig by removing their .layer companions and inlining derivation in Modules.scala. Move SchemaRegistryServerEndpoints to credential-schema-http and CredentialDefinitionRegistryServerEndpoints to credential-definition-http, replacing AppConfig with serviceName: String parameter. Move Oid4vciAuthenticator and CredentialIssuerServerEndpoints to oid4vci-http. Reduces api-server/core from 64 to 24 files. Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
…core - Create api-server-config module with AppConfig.scala, breaking the circular dependency between apiServer and apiServerJobs - Move VerificationConfig.toPresentationVerificationOptions() to PresentBackgroundJobs to remove VC-JWT/DID imports from config module - Extract 10 background job files to api-server-jobs module with proper domain module dependencies - Fix pre-existing test compilation failures (Phase 18 constructor changes, missing IssueControllerConfig layer, SystemControllerImpl version parameter) - api-server/core reduced from 24 to 13 source files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dpoints) to api-server-http-core Split CustomServerInterceptors: tapir interceptors moved to http-core, http4s error handler extracted to Http4sErrorHandler in api-server/core. Parameterized ZHttpEndpoints to remove BuildInfo/DocModels dependencies before moving to http-core. api-server/core now has 11 source files — the genuine assembly layer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove credentialsAnoncreds and didcommAgent from apiServer direct deps (both transitive via apiServerJobs/didcommHttp). Add 16 architecture constraints covering HTTP module isolation, infrastructure module boundaries, and persistence/HTTP separation. Generate Phase 20 dependency graph snapshot (286 edges). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dApi/didCore Move 22 model types, service traits, error types, and utilities from didCore to didApi, reversing the dependency so didCore depends on didApi. Only 3 service implementation files remain in didCore (PrismNodeDIDService, NeoPrismDIDService, NeoPrismClient). Seven modules switched from didCore to didApi, leaving only apiServer depending on didCore for wiring. This prevents didCore's heavy gRPC/HTTP implementations from leaking to infrastructure modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…odules Switch didcommHttp from connectionsCore+credentialsCore to connectionsApi+credentialsApi, and connectionsHttp from connectionsCore to connectionsApi. All needed types were already re-exported via API modules. Add Direct-scope architecture constraints to prevent regression. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace credentialsCore's fat dependency on didcommAgentDidcommx (which pulls in 13 protocol modules via didcommAgent) with direct dependencies on only the specific protocols actually used: protocolIssueCredential and protocolPresentProof. Move didcommAgentDidcommx to test-only scope and remove unused didcommVC dependency entirely. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Decompose the monolithic apiServerJobs (10 files, 11 deps) into 6 focused modules: apiServerJobsCore (shared helpers), apiServerJobsConnect, apiServerJobsIssue, apiServerJobsPresent, apiServerJobsStatusList, and apiServerJobsDidSync. Each domain owns its background job handlers with only the dependencies it actually needs. Add architecture constraints to prevent cross-job module coupling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ok module Move WebhookPublisher, WebhookPublisherError, and JsonEventEncoders from api-server/core into modules/notifications/webhook to reduce api-server/core scope and make webhook infrastructure dependencies explicit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace HTTP DTO imports with local webhook-specific DTOs in JsonEventEncoders, removing dependencies on connectionsHttp, didHttp, issueHttp, and presentProofHttp. Adds architecture constraints to prevent re-introducing these dependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…maHttp Switch CredentialDefinitionResponsePage to use its own local annotations instead of importing from CredentialSchemaResponsePage. This also fixes API docs showing schema-specific example URLs for credential definitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move lightweight types (Entity, Wallet, GenericSecretStorage, EntityService, EntityServiceError) into walletManagementApi and reverse the dependency so walletManagement depends on walletManagementApi. Delete unused type alias files (WalletManagementApi.scala, WalletManagementApiTestExports.scala). This gives apiServerHttpCore a lighter transitive closure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mAgentDidcommx Split PeerDID into data class (didcommModels) and factory/resolver logic (PeerDIDCreation in didcommResolver). walletManagement now depends on the much lighter didcommResolver instead of didcommAgentDidcommx, eliminating a massive transitive closure of 13 protocol modules and the full didcommx adapter from the wallet domain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move PresentationDefinition types and PresentationDefinitionValidator from credentialsPreX into credentialsCore (same package, no import changes). credentialsPreX now depends on credentialsCore instead of vice versa. First step toward making credentialsCore abstract over credential formats. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move CompactFormat and ModelsExtensionMethods (pure data types) from credentialsSDJWT to credentialsCore. Introduce SDJwtService trait in credentialsCore with Ed25519PrivateKey parameters, replacing direct SDJWT object calls and sdjwtwrapper-bound types (HolderPrivateKey, IssuerPrivateKey). SDJwtServiceLive in credentialsSDJWT wraps the existing SDJWT object and handles key conversions internally. credentialsSDJWT now depends on credentialsCore instead of vice versa. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- apiServerJobsCore: replace ES256KSigner/EdSigner with VcJwtService - credentialsPreX: add JwtDecoder param to decouple from JwtCredential/JwtPresentation - oid4vciCore: move JwtSignerImplicits to sharedCrypto - oid4vciHttp: add explicit credentialsVcJWT dep (was transitive via oid4vciCore) - Add arch constraints for apiServerJobsCore and oid4vciCore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…entialsCore Type-erase at the consumer boundary by introducing JsonEventConsumer in notificationsApi. WebhookPublisher now works with Seq[JsonEventConsumer] instead of typed consumers. JsonEventEncoders moved to apiServer where WebhookPublisherFactory wires typed consumers with domain-specific encoders. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Design for composable module architecture covering credential (format, data model, builder, signer, verifier) and protocol (transport, issuance, presentation, PEX) dimensions with contract-based decoupling and incremental migration strategy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TDD-driven, phase-by-phase implementation plan for migrating to composable plugin architecture. Phase 0 (foundation) and Phase 1 (leaf extraction) are fully detailed with exact file paths, test code, and implementation code. Phases 2-5 are outlined at task level. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… module graph - Add PersistenceProvider contract with PostgreSQL and SQLite modules - Add SQLite considerations (no advisory locks, migration variants) - Add DIDComm protocol versioning (v2/v3 as separate modules) - Add Phase 5 (SQLite) to implementation plan, renumber Phase 6 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 0 of plugin architecture migration: - Capability, Contract, Cardinality types for module dependency system - Module trait with lifecycle, capabilities, per-module config - ModuleRegistry with dependency validation and capability resolution - Credential contracts: CredentialSigner, DataModelCodec, CredentialBuilder, VerificationCheck, RevocationCheck, CredentialVerifier combinator - Protocol contracts: ProtocolTransport, IssuanceProtocol, PresentationProtocol, PresentationExchange - 13 tests passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add zio-json to shared module dependencies. Replace String with zio.json.ast.Json in all contract interfaces (BuildContext, BuildState, BuiltCredential, ProtocolMessage, IssuanceProtocol, PresentationProtocol, PresentationExchange, DataModelCodec). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract EdDSA and Secp256k1 CredentialSigner implementations from vc-jwt module into sharedCrypto, and add JwtExpiryCheck as the first VerificationCheck implementation in shared core. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Vcdm11DataModelCodec that encodes/decodes W3C VCDM 1.1 credential structure. Add JwtCredentialBuilder that composes DataModelCodec + CredentialSigner through a pipeline: encode claims → serialize → sign → assemble JWT string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Vcdm11DataModelCodec → credentialsCore (codec package) - JwtExpiryCheck → credentialsCore (verification package) - JwtCredentialBuilder → credentialsVcJWT shared/credentials now contains only pure contract traits and value types. All implementations live in their domain modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap existing components as Module implementations: - EdDsaSignerModule, Secp256k1SignerModule (sharedCrypto) - Vcdm11CodecModule (credentialsCore) - JwtBuilderModule (credentialsVcJWT) — requires signer + codec Integration test validates full dependency graph: registration, resolution by contract/variant, and missing dependency detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Crypto primitives (EdDSA, secp256k1) are always-on infrastructure, not pluggable modules. They remain as CredentialSigner implementations but no longer wrapped in Module declarations. JwtBuilderModule no longer requires CredentialSigner capability — signers are injected directly as constructor dependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…se 3)
Add DIDCommIssuanceModule declaring IssuanceProtocol("didcomm-v3")
capability. Add DIDCommIssuanceAdapter that bridges the IssuanceProtocol
contract to the existing CredentialService — dispatches createRequest
and issueCredential to format-specific methods based on record's
credential format. Enables incremental migration via strangler fig
pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…(Phase 3.4) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DIDCommV2 transport, OIDC transport, and PresentationExchange module declarations. Extend ModuleRegistry integration tests to cover issuance and presentation protocol resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ase 5) - PersistenceProvider trait and PersistenceType enum in shared - SqlitePersistenceProvider with Flyway migration support - PostgresPersistenceModule and SqlitePersistenceModule declarations - New persistence-sqlite sbt project with sqlite-jdbc dependency - 9 tests: contract (2), SQLite provider (3), module registry (4) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ModuleRegistry.fromAll with disable filtering and report generation - AllModules registry collecting all extracted modules - CloudAgentApp validates module dependency graph at startup - Integration tests expanded to 10 (covering all modules + filtering) - ModuleRegistry unit tests expanded to 8 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enforce that shared contains only contracts (no implementation deps) and persistence-sqlite stays isolated from domain modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bridges IssuanceProtocol contract to OID4VCI redirect-based flow. Most methods are unsupported (OID4VCI uses HTTP, not messages), but the adapter formalizes OID4VCI as a first-class protocol. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bridges PresentationProtocol contract to OID4VP redirect-based flow. Registered in AllModules for startup validation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract SdJwtCredentialBuilder that delegates to SDJwtService for credential issuance. Includes IssuerKeyResolver trait to bridge generic KeyRef to Ed25519PrivateKey. Registered as SdJwtBuilderModule in AllModules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract AnonCredsCredentialBuilder that delegates to AnoncredService for credential issuance. Uses CredentialContext.Resolver to bridge pre-negotiated state (cred def, offer, request) from the protocol layer. Add zio-test dependencies to credentialsAnoncreds project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move JWT and SD-JWT verification logic behind PresentationService, SDJwtService, and VcJwtService abstractions so that apiServerJobsIssue and apiServerJobsPresent no longer depend on credentialsVcJWT, credentialsSDJWT, or credentialsAnoncreds modules directly. BREAKING CHANGE: PresentationService, VcJwtService, and SDJwtService traits have new methods that implementations must provide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…yers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add abstract type member `Service` and abstract method `def layer: TaskLayer[Service]` to the Module trait so modules can contribute ZIO service layers to the runtime. Update all existing Module implementations with stub `type Service = Unit` and `def layer = ZLayer.succeed(())`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
- Add credentialsVcJWT, credentialsSDJWT, credentialsAnoncreds as direct deps of apiServer (composition root needs access to all modules) - Add arch constraints: shared must not depend on credentialsSDJWT or credentialsAnoncreds - Remove unused CredentialBuilderRegistry import from AllModules - Add implementation plan for wiring credential builders Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Yurii Shynbuiev <yurii.shynbuiev@iohk.io>
|
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
Domain-first module restructuring of the cloud-agent codebase, improving separation of concerns, dependency hygiene, and architectural consistency.
Phase 1-14: Module Restructuring
did/api,did/core,credentials/api,credentials/core,connections/api,connections/core,notifications/api,notifications/core,wallet-management/api,wallet-management/corevdr/api,vdr/core,vdr/service,vdr/prism-node,vdr/database,vdr/memory,vdr/blockfrost,vdr/proxycredentials/persistence-doobie,connections/persistence-doobie,wallet-management/persistence-doobie,wallet-management/secrets-vaultshared/predeffor cross-cutting Scala predef customizationscastor/pollux/connect/mercurytodid/credentials/connections/didcommPhase 15: DIDKeySigner, Error Standardization, HTTP Layer Extraction
DIDKeySigner extraction:
DIDKeySignertrait indid/apimodule — generic key resolution abstractionDIDKeySignerImplinwallet-management/coreusingManagedDIDServicePrismNodeVdrOperationSignerfromapi-servertovdr/prism-node, refactored to depend onDIDKeySignerError handling standardization:
CreateManagedDIDError,GetManagedDIDError,PublishManagedDIDError,UpdateManagedDIDError) to extendFailurewith proper HTTP status codesEventNotificationServiceErrorto extendFailuregiven Conversion[XxxError, ErrorResponse]blocks fromDIDRegistrarControllerHTTP module extraction:
api-server-http-coremodule with shared HTTP infrastructure (19 files: ErrorResponse, EndpointOutputs, SecurityLogic, Authenticator, credentials types, etc.)notifications-httpmodule as pilot for domain HTTP separation (5 files: EventController, EventEndpoints, EventServerEndpoints, webhook DTOs)EventServerEndpointsto useAuthenticatorWithAuthZ[BaseEntity]trait instead of concreteDefaultAuthenticatorTest plan
sbt compile— all modules compile cleanlysbt scalafmtAll— formatting appliedvdrPrismNode/testOnly PrismNodeVdrOperationSignerSpec— 3/3 passedwalletManagement/test— 178 passed, 0 failednotifications/test— 9/9 passedapiServer/testOnly SecurityLogicSpec— 6/6 passedGenerated with Claude Code