# Cosmos Db

## Description

Cosmos DB is used as a **Document DB provider** behind `IFlexDocumentStore`. Generated apps keep document reads/writes in the standard Query/Handler pattern while Cosmos-specific concerns (partition keys, throughput, retry/backoff) are handled in the provider wiring.

## Important Concepts

* **Container mapping is config-driven**: logical store/container names and partition keys live in configuration.
* **AppContext is mandatory**: always call `dto.GetAppContext()` in generated queries/handlers.
* **Provider-agnostic code**: your business logic depends on `IFlexDocumentStore`, not the Cosmos SDK.

## Configuration in DI (where to add)

Provider wiring is generated in your Infrastructure project (under a `...DataStoreProviders/Document/CosmosDb` folder). You typically do **not** register individual queries/handlers here — Flex generates and wires those.

If you are wiring Cosmos manually, add the **document-store provider** registration where you configure infrastructure services:

```csharp
// Infrastructure (example)
services.AddFlexCosmosDocumentStore<CustomerProfileDocument>(configuration);
```

## appsettings.json

```json
{
	"FlexBase": {
		"DataStores": {
			"Document": {
				"CosmosDb": {
					"Endpoint": "https://...documents.azure.com:443/",
					"AccountKey": "<from-secrets>",
					"DatabaseName": "{YourApplication}",
					"ContainerName": "CustomerProfiles",
					"PartitionKeyPath": "/id",
					"ThroughputRUs": 400
				}
			}
	}
  }
}
```

## Examples (from the generated templates)

Cosmos uses the same generated shapes as other Document DB providers.

### Handler example (Create)

```csharp
using Microsoft.Extensions.Logging;
using Sumeru.Flex;
using System.Threading.Tasks;

public interface ICreateCustomerProfileHandler : IAmFlexCommandHandler<CreateCustomerProfileCommand> { }

public partial class CreateCustomerProfileHandler : ICreateCustomerProfileHandler
{
	protected string EventCondition = "";

	protected readonly ILogger<CreateCustomerProfileHandler> _logger;
	protected readonly IFlexHost _flexHost;
	protected readonly IFlexDocumentStore _documentStore;
	protected readonly ICustomerProfileMapper _mapper;

	protected CustomerProfileDocument? _model;
	protected FlexAppContextBridge? _flexAppContext;

	public CreateCustomerProfileHandler(
		ILogger<CreateCustomerProfileHandler> logger,
		IFlexHost flexHost,
		IFlexDocumentStore documentStore,
		ICustomerProfileMapper mapper)
	{
		_logger = logger;
		_flexHost = flexHost;
		_documentStore = documentStore;
		_mapper = mapper;
	}

	public virtual async Task Execute(CreateCustomerProfileCommand cmd, IFlexServiceBusContext serviceBusContext)
	{
		_flexAppContext = cmd.Dto.GetAppContext(); // do not remove

		_model = _mapper.MapToDocument(cmd.Dto);
		await _documentStore.CreateAsync<CustomerProfileDocument>(_model);

		// TODO: set EventCondition (example: CONDITION_ONSUCCESS)
		await this.Fire(EventCondition, serviceBusContext);
	}
}
```

### Query example (Get-by-id)

```csharp
using Microsoft.Extensions.Logging;
using Sumeru.Flex;
using System;
using System.Threading.Tasks;

public class GetCustomerProfileById : FlexiQueryBridgeAsync<CustomerProfileDto>
{
	protected readonly ILogger<GetCustomerProfileById> _logger;
	protected readonly IFlexHost _flexHost;
	protected readonly IFlexDocumentStore _documentStore;
	protected GetCustomerProfileByIdParams _params;
	protected FlexAppContextBridge _flexAppContext;

	public GetCustomerProfileById(ILogger<GetCustomerProfileById> logger, IFlexHost flexHost, IFlexDocumentStore documentStore)
	{
		_logger = logger;
		_flexHost = flexHost;
		_documentStore = documentStore;
	}

	public virtual GetCustomerProfileById AssignParameters(GetCustomerProfileByIdParams @params)
	{
		_params = @params;
		return this;
	}

	public virtual async Task<CustomerProfileDto?> Fetch()
	{
		_flexAppContext = _params.GetAppContext();

		var doc = await _documentStore.GetByIdAsync<CustomerProfileDocument>(_params.Id);
		return doc == null ? null : new CustomerProfileDto { Id = doc.Id };
	}
}

public class GetCustomerProfileByIdParams : DtoBridge
{
	public Guid Id { get; set; }
}
```

## Provider-specific considerations

* **Partition keys**: model your access patterns around the partition key to avoid cross-partition scans.
* **Throughput**: keep RU/autoscale settings in config so environments can tune independently.
* **Retries/backoff**: rely on the provider’s retry policies for throttling (429) behavior.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flexbase.in/data-and-providers/data-stores/document-db/cosmos-db.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
