Skip to main content

Partner Service

Service Type: Core REST Microservice Language: Kotlin / Micronaut Framework Database: PostgreSQL (owned) Status: Implemented (v0.1)


Overview

Partner Service is the authoritative owner of partner data and lifecycle management within DEUSS. It manages three partner roles (BROKER, PSP, GUARANTOR) and provides individualized platform fee schedules for brokers. The service operates entirely synchronously via REST without asynchronous messaging.


Business Responsibilities

  • Partner Lifecycle Management — Onboarding, status transitions (DRAFT → REVIEW_REQUESTED → ACTIVE), deletion (DRAFT only)
  • Role & Profile Management — BROKER, PSP, GUARANTOR roles with role-specific details (EBSI credentials, certificates)
  • Platform Fee Schedules — Versioned fee structures for brokers (DRAFT/ACTIVE/ARCHIVED states)
  • Fee Quote Calculation — Compute concrete fees based on fee type, issuance size, issuer track record
  • Audit Logging — Status change history with actor, timestamp, and reason

Owned Data

Entities:

  • partners — Core partner records (legal name, contact, country, identifiers, IBAN, status)
  • broker_details, psp_details, guarantor_details — Role-specific profiles
  • partner_certificates — Certificates with serial numbers
  • partner_status_history — Audit trail of status transitions
  • partner_platform_fee_schedules — Versioned fee schedules (DRAFT/ACTIVE/ARCHIVED)
  • partner_platform_fee_schedule_items — Individual fee rules with calculation logic
  • platform_fee_schedule_templates — Default templates for broker onboarding Constraints:
  • At most ONE ACTIVE and ONE DRAFT fee schedule per broker at any time
  • At most ONE ACTIVE default fee schedule template system-wide
  • Unique: legal_name, contact_email, business_id, legal_entity_id

Inbound Interfaces

REST API

Authentication: JWT Bearer token required; all operations require ADMIN role

Partners Management (/v1/partners)

EndpointMethodOperationPurpose
/v1/partnersPOSTcreatePartnerCreate new partner (starts in DRAFT)
/v1/partnersGETlistPartnersList with filters (name, email, business ID, country, role, status)
/v1/partners/{partner_id}GETgetPartnerFetch partner details
/v1/partners/{partner_id}PATCHupdatePartnerUpdate attributes (not status)
/v1/partners/{partner_id}DELETEdeletePartnerDelete (DRAFT only)
/v1/partners/{partner_id}/statusPATCHsetPartnerStatusChange status with reason & audit log

Platform Fee Schedules (/v1/partners/{partner_id}/platform-fee-schedules)

EndpointMethodOperationPurpose
/currentGETgetCurrentPlatformFeeScheduleGet active fee schedule
/{fee_schedule_id}GETgetPlatformFeeScheduleGet specific version
/POSTcreatePlatformFeeScheduleDraftCreate draft (copies current active)
/{fee_schedule_id}PATCHupdatePlatformFeeScheduleUpdate draft items
/{fee_schedule_id}/publishPOSTpublishPlatformFeeSchedulePublish draft as new active, archive old

Fee Quotes

EndpointMethodOperationPurpose
/v1/partners/{partner_id}/platform-fee-quotePOSTquotePlatformFeeCalculate concrete fee for broker

Outbound Interfaces

  • Database Only — PostgreSQL direct access via Hibernate/JPA
  • No External Service Calls — Partner Service operates independently
  • No Kafka/Async Messaging — Synchronous model only

Kafka Integration

Status: Not integrated

  • No Kafka producers
  • No Kafka consumers
  • No CDC/Debezium enabled

External Integrations

  • EBSI (Future)brokerDetails.ebsiVerifiableCredential stores EBSI credentials; not actively used
  • EOA Keys (Future)brokerDetails.eoaPublicKey for blockchain interactions; stored but not used

Key Business Rules

  1. Partners must have ≥1 role (BROKER | PSP | GUARANTOR)
  2. Brokers automatically receive ACTIVE fee schedule copied from default template at onboarding
  3. Deletion only allowed in DRAFT status
  4. Fee Schedules:
    • Brokers always have exactly 1 ACTIVE schedule + max 1 DRAFT
    • Versions increment on each publication
    • Items matched hierarchically: (feeType + issuanceSize + issuerTrackRecord) → (feeType + issuanceSize) → (feeType + issuerTrackRecord) → (feeType only)
  5. Fee Calculation: FIXED amounts or PERCENTAGE of base price, with optional min/max bounds
  6. Concurrency: Draft creation uses pessimistic lock on active schedule to prevent race conditions

Deployment

Runtime Stack:

  • Java 25 (OpenJDK JRE in Alpine container)
  • Micronaut on Netty
  • PostgreSQL database
  • Flyway for schema migrations Configuration:
  • Port: 8080
  • Health check: /health (standard Micronaut)
  • Environment variables: DATABASE_URL, DATABASE_USER, DATABASE_PASSWORD
  • Access logging: Enabled Container:
  • Non-root user (runtime) for security
  • Init process (tini) for signal handling
  • JVM container support enabled (-XX:+UseContainerSupport)

Observability

  • Structured Logging: Semantic logging with events and parameters via DeussLogger
  • Access Logs: Enabled on Netty
  • Health Endpoint: Micronaut standard /health
  • Metrics: Unknown (Micrometer integration status not verified)

Technical Notes

  • No Async Model — Only REST. Changes to partners don't propagate via events; dependent services must poll or call synchronously.
  • Pessimistic Concurrency Control — Draft creation locks the active schedule row to prevent concurrent draft race conditions.
  • Validation as Data — Errors returned as ValidationResult<Error, Success>, not exceptions; enables cleaner control flow.
  • Semantic Versioning — Fee schedule versions increment per publish; maintains full history.
  • Default Template Pattern — New brokers copy from the single ACTIVE system template to ensure consistency.

Relationships with Other Services

  • Registry Service — Likely queries Partner Service for broker/partner details during credential verification
  • Core Payment Service — May query fee schedules for pricing calculations (Unknown—not verified)
  • Indexer (GraphQL) — May expose partner data via GraphQL (Unknown—not verified)

Documentation Sources:

  • Source: core/partner-service/src/
  • Migrations: core/partner-service/src/main/resources/db/migration/
  • OpenAPI: api-specifications/src/main/resources/core/partner-service/public/
  • Config: core/partner-service/src/main/resources/application.yaml
  • Container: core/partner-service/Dockerfile