Skip to main content

arolariu.Backend.Domain.Invoices.Brokers.DatabaseBroker

arolariu.Backend.Domain.Invoices​

arolariu.Backend.Domain.Invoices.Brokers.DatabaseBroker Namespace​

Interfaces​

IInvoiceNoSqlBroker Interface​

Low-level (broker) persistence contract for invoice and merchant aggregates backed by Azure Cosmos DB (NoSQL).

public interface IInvoiceNoSqlBroker

Derived
↳ InvoiceNoSqlBroker

Remarks​

Role (The Standard): A broker is a thin abstraction over an external dependency (Cosmos DB). It exposes primitive CRUD / query operations with minimal translation. It MUST NOT implement domain validation, cross-aggregate orchestration, authorization, business workflow branching, or exception classification beyond direct dependency errors.

Responsibilities:

  • Persist (create / upsert) invoice and merchant aggregates.
  • Retrieve single or multiple aggregates (optionally partition-scoped for RU efficiency).
  • Apply soft delete semantics for invoices (and future merchants) by flagging rather than removing.

Exclusions: No invariant checking, no ownership / tenancy authorization, no retry / circuit breaker policy (to be added via delegating handlers or higher resilience layer), no pagination abstraction, no projection shaping (callers handle filtering / shaping).

Partitioning: Invoices partitioned by UserIdentifier; merchants by ParentCompanyId. Overloads lacking an explicit partition key perform cross-partition (fan-out) operations and SHOULD be reserved for administrative / analytical scenarios due to higher RU cost.

Soft Delete (Invoices): Implemented via IsSoftDeleted flags on invoice and contained products. Broker read methods return only non-soft-deleted documents. Bulk hard-deletion is intentionally avoided for audit and recovery concerns (future backlog: retention policy enforcement).

Idempotency:

  • Create operations are NOT idempotent (duplicate IDs depend on upstream id assignment strategy).
  • Soft-delete operations are idempotent (repeated calls yield same terminal state).
  • Read operations are naturally idempotent.

Concurrency: No optimistic concurrency (ETag) handling is implemented yet (backlog: introduce access conditions to prevent lost updates).

Performance Notes: Prefer partition-aware overloads. Cross-partition queries should be monitored (add RU telemetry in higher layers). Upsert patterns may incur additional RU vs targeted replace (evaluate once concurrency tokens introduced).

Thread Safety: Implementations (e.g., EF Core DbContext wrapper) are typically NOT thread-safe; consumers should scope instances per unit-of-work.

Cancellation: All async methods accept an optional CancellationToken to support request abort and timeouts.

Backlog: Pagination / continuation tokens, optimistic concurrency, projection queries (selective field retrieval), bulk operations (transactional batch for co-partitioned items), telemetry hooks, and soft-delete for merchants.

Methods​

IInvoiceNoSqlBroker.CreateInvoiceAsync(Invoice, CancellationToken) Method​

Persists a new invoice document.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice> CreateInvoiceAsync(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice invoice, System.Threading.CancellationToken cancellationToken);

Parameters​

invoice Invoice

Fully populated invoice aggregate (identity may be reassigned by upstream factory prior to call).

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Invoice>
The persisted invoice including any storage-generated metadata.

Exceptions​

System.ArgumentNullException
Thrown if invoice is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Asynchronous I/O-bound single write operation. Assumes the invoice aggregate has been fully validated upstream.

IInvoiceNoSqlBroker.CreateMerchantAsync(Merchant, CancellationToken) Method​

Persists a new merchant entity.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant> CreateMerchantAsync(arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant merchant, System.Threading.CancellationToken cancellationToken);

Parameters​

merchant Merchant

Merchant entity to persist.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Merchant>
The persisted merchant.

Exceptions​

System.ArgumentNullException
Thrown if merchant is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Performs a single write operation. Caller must ensure uniqueness and upstream validation of fields.

IInvoiceNoSqlBroker.DeleteInvoiceAsync(Guid, Nullable<Guid>, CancellationToken) Method​

Soft-deletes an invoice by identifier within a known partition.

System.Threading.Tasks.ValueTask DeleteInvoiceAsync(System.Guid invoiceIdentifier, System.Nullable<System.Guid> userIdentifier, System.Threading.CancellationToken cancellationToken);

Parameters​

invoiceIdentifier System.Guid

Invoice identity.

userIdentifier System.Nullable<System.Guid>

Partition (owner) identity.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

More efficient than cross-partition delete variant. Marks invoice and contained products as soft-deleted.

IInvoiceNoSqlBroker.DeleteInvoicesAsync(Guid, CancellationToken) Method​

Soft-deletes all invoices for a given user partition.

System.Threading.Tasks.ValueTask DeleteInvoicesAsync(System.Guid userIdentifier, System.Threading.CancellationToken cancellationToken);

Parameters​

userIdentifier System.Guid

Partition (owner) identity whose invoices will be soft-deleted.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Iterates all partition documents; may incur significant RU charges for large partitions.

IInvoiceNoSqlBroker.DeleteMerchantAsync(Guid, Nullable<Guid>, CancellationToken) Method​

Soft-deletes (or physically replaces) a merchant by identifier via cross-partition search.

System.Threading.Tasks.ValueTask DeleteMerchantAsync(System.Guid merchantIdentifier, System.Nullable<System.Guid> parentCompanyId, System.Threading.CancellationToken cancellationToken);

Parameters​

merchantIdentifier System.Guid

Merchant identity.

parentCompanyId System.Nullable<System.Guid>

The parent company identifier.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Current implementation performs a greedy query. If soft-delete is later introduced for merchants, implementation should mark a flag rather than remove.

IInvoiceNoSqlBroker.ReadInvoiceAsync(Guid, Nullable<Guid>, CancellationToken) Method​

Retrieves a single invoice by identifier using either a single point read or a cross-partition (greedy) lookup.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice?> ReadInvoiceAsync(System.Guid invoiceIdentifier, System.Nullable<System.Guid> userIdentifier, System.Threading.CancellationToken cancellationToken);

Parameters​

invoiceIdentifier System.Guid

Invoice aggregate identity (GUID).

userIdentifier System.Nullable<System.Guid>

Partition key. Pass the owning user for a point read; pass null to search across partitions.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Invoice>
The matching invoice or null.

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Performs a non-partition-scoped query (higher RU cost). Use the partition-aware overload when the user / owner identifier is available.

Returns null when not found or soft-deleted.

IInvoiceNoSqlBroker.ReadInvoicesAsync(Guid, CancellationToken) Method​

Lists all non soft-deleted invoices for a specific user/partition.

System.Threading.Tasks.ValueTask<System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice>> ReadInvoicesAsync(System.Guid userIdentifier, System.Threading.CancellationToken cancellationToken);

Parameters​

userIdentifier System.Guid

Partition key / owner identity.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<System.Collections.Generic.IEnumerable<Invoice>>
An enumerable of invoices (may be empty).

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

IInvoiceNoSqlBroker.ReadMerchantAsync(Guid, Nullable<Guid>, CancellationToken) Method​

Retrieves a merchant by identifier via cross-partition (greedy) search.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant?> ReadMerchantAsync(System.Guid merchantIdentifier, System.Nullable<System.Guid> parentCompanyId, System.Threading.CancellationToken cancellationToken);

Parameters​

merchantIdentifier System.Guid

Merchant identity.

parentCompanyId System.Nullable<System.Guid>

The parent company identifier.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Merchant>
The merchant or null if not found or soft-deleted (if soft-delete introduced later).

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Use partition-aware read patterns (parent company id) where possible to reduce RU consumption.

IInvoiceNoSqlBroker.ReadMerchantsAsync(Guid, CancellationToken) Method​

Lists merchants filtered by parent company partition.

System.Threading.Tasks.ValueTask<System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant>> ReadMerchantsAsync(System.Guid parentCompanyId, System.Threading.CancellationToken cancellationToken);

Parameters​

parentCompanyId System.Guid

Partition key representing the parent company identifier.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<System.Collections.Generic.IEnumerable<Merchant>>
An enumerable of merchants (may be empty).

Exceptions​

System.OperationCanceledException
Thrown if the operation is cancelled.

IInvoiceNoSqlBroker.UpdateInvoiceAsync(Invoice, Invoice, CancellationToken) Method​

Replaces (upserts) an invoice using current and updated aggregate snapshots.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice> UpdateInvoiceAsync(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice currentInvoice, arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice updatedInvoice, System.Threading.CancellationToken cancellationToken);

Parameters​

currentInvoice Invoice

Current persisted invoice snapshot (not validated here).

updatedInvoice Invoice

Updated invoice aggregate snapshot.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Invoice>
The persisted invoice after update.

Exceptions​

System.ArgumentNullException
Thrown if currentInvoice or updatedInvoice is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

currentInvoice is not modified; only updatedInvoice is persisted. No optimistic concurrency token applied.

IInvoiceNoSqlBroker.UpdateInvoiceAsync(Guid, Invoice, CancellationToken) Method​

Replaces (upserts) an invoice by identifier (partition inferred from updatedInvoice).

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice> UpdateInvoiceAsync(System.Guid invoiceIdentifier, arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice updatedInvoice, System.Threading.CancellationToken cancellationToken);

Parameters​

invoiceIdentifier System.Guid

Target invoice identity.

updatedInvoice Invoice

Updated invoice aggregate snapshot.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Invoice>
The persisted invoice after update.

Exceptions​

System.ArgumentNullException
Thrown if updatedInvoice is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

Remarks​

Assumes updatedInvoice carries the correct UserIdentifier. Does not perform concurrency (ETag) checks.

IInvoiceNoSqlBroker.UpdateMerchantAsync(Merchant, Merchant, CancellationToken) Method​

Replaces (upserts) a merchant using its current and updated snapshots.

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant> UpdateMerchantAsync(arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant currentMerchant, arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant updatedMerchant, System.Threading.CancellationToken cancellationToken);

Parameters​

currentMerchant Merchant

Current persisted merchant (not modified).

updatedMerchant Merchant

Updated merchant snapshot to persist.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Merchant>
The persisted merchant.

Exceptions​

System.ArgumentNullException
Thrown if currentMerchant or updatedMerchant is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

IInvoiceNoSqlBroker.UpdateMerchantAsync(Guid, Merchant, CancellationToken) Method​

Replaces (upserts) a merchant by identifier (partition inferred via existing document lookup).

System.Threading.Tasks.ValueTask<arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant> UpdateMerchantAsync(System.Guid merchantIdentifier, arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant updatedMerchant, System.Threading.CancellationToken cancellationToken);

Parameters​

merchantIdentifier System.Guid

Merchant identity.

updatedMerchant Merchant

Updated merchant snapshot.

cancellationToken System.Threading.CancellationToken

Cancellation token to abort the operation (required).

Returns​

System.Threading.Tasks.ValueTask<Merchant>
The persisted merchant.

Exceptions​

System.ArgumentNullException
Thrown if updatedMerchant is null.

System.OperationCanceledException
Thrown if the operation is cancelled.

// was this page useful?