Metadata API for agreements and envelopes. Part of the same platform as AgreementStream. Stores IDs, versions, and envelope links in PostgreSQL. Updates use optimistic locking so two writers do not stomp each other.
- .NET 8 ASP.NET Core Web API
- Entity Framework Core + PostgreSQL
- xUnit with
WebApplicationFactory(SQLite in-memory in tests) - Docker Compose for local runs
- Kubernetes manifest with liveness/readiness probes
DocIndex.sln
src/DocIndex.Api/ # API, services, EF Core
tests/DocIndex.Api.Tests/ # integration tests
kubernetes/deployment.yaml
docker-compose.yml
| Method | Route | Description |
|---|---|---|
| GET | /api/agreements?page=1&pageSize=20 |
Paginated agreement list |
| GET | /api/agreements/{id} |
Get agreement by id |
| POST | /api/agreements |
Create agreement |
| PUT | /api/agreements/{id} |
Update agreement (send version) |
| DELETE | /api/agreements/{id} |
Delete agreement |
| GET | /api/envelopes?page=1&pageSize=20 |
Paginated envelope list |
| GET | /api/envelopes/{id} |
Get envelope by id |
| POST | /api/envelopes |
Create envelope (needs agreementId) |
| PUT | /api/envelopes/{id} |
Update envelope (send version) |
| DELETE | /api/envelopes/{id} |
Delete envelope |
| GET | /health/live |
Liveness |
| GET | /health/ready |
Readiness (checks DB) |
Every entity has Id and Version (both Guid). On PUT, send the version you read. If someone else updated first, you get 409 Conflict.
ConcurrencyInterceptor bumps Version on insert/update. LoadForUpdateAsync checks the client version before applying changes.
- .NET 8 SDK
- Docker (optional, for compose)
docker compose up --buildAPI: http://localhost:5080
Swagger: http://localhost:5080/swagger
dotnet run --project src/DocIndex.ApiConnection string is in src/DocIndex.Api/appsettings.json.
dotnet testBuild and push the image, then apply kubernetes/deployment.yaml. Create a docindex-secrets secret with key connection-string for PostgreSQL.
- AgreementStream: event routing
- TerraVault: blob storage