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=default(System.Threading.CancellationToken));

Parameters

invoice Invoice

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

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

merchant Merchant

Merchant entity to persist.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

invoiceIdentifier System.Guid

Invoice identity.

userIdentifier System.Nullable<System.Guid>

Partition (owner) identity.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

userIdentifier System.Guid

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

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

merchantIdentifier System.Guid

Merchant identity.

parentCompanyId System.Nullable<System.Guid>

The parent company identifier.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

invoiceIdentifier System.Guid

Invoice aggregate identity (GUID).

userIdentifier System.Nullable<System.Guid>

Optional partition key for efficient point read.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

userIdentifier System.Guid

Partition key / owner identity.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

merchantIdentifier System.Guid

Merchant identity.

parentCompanyId System.Nullable<System.Guid>

The parent company identifier.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

parentCompanyId System.Guid

Partition key representing the parent company identifier.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

currentInvoice Invoice

Current persisted invoice snapshot (not validated here).

updatedInvoice Invoice

Updated invoice aggregate snapshot.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

invoiceIdentifier System.Guid

Target invoice identity.

updatedInvoice Invoice

Updated invoice aggregate snapshot.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

currentMerchant Merchant

Current persisted merchant (not modified).

updatedMerchant Merchant

Updated merchant snapshot to persist.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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=default(System.Threading.CancellationToken));

Parameters

merchantIdentifier System.Guid

Merchant identity.

updatedMerchant Merchant

Updated merchant snapshot.

cancellationToken System.Threading.CancellationToken

Optional cancellation token to abort the operation.

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?