User Story
As a developer using PostgreSQL with Pulse, I want an IIdempotencyStore backed by PostgreSQL ADO.NET, so that I can enforce idempotency in applications that use NetEvolve.Pulse.PostgreSql without adopting EF Core.
Background
Mirrors the SQL Server implementation (#227) but uses Npgsql and PostgreSQL-specific DDL (TIMESTAMP WITH TIME ZONE, ON CONFLICT DO NOTHING).
Requirements
- Add
src/NetEvolve.Pulse.PostgreSql/Scripts/IdempotencyKey.sql:
- Table
"{schema}"."IdempotencyKey" with idempotency_key VARCHAR(500) NOT NULL PRIMARY KEY and created_at TIMESTAMP WITH TIME ZONE NOT NULL.
- PostgreSQL functions:
fn_exists_idempotency_key, fn_insert_idempotency_key, fn_delete_expired_idempotency_keys.
- Create
PostgreSqlIdempotencyKeyOptions: Schema, TableName, TimeToLive?.
- Implement
PostgreSqlIdempotencyStore : IIdempotencyStore via Npgsql ADO.NET:
ExistsAsync: calls fn_exists_idempotency_key.
StoreAsync: calls fn_insert_idempotency_key; ignores PostgreSQL error 23505 (unique violation).
- Expose
AddPostgreSqlIdempotencyStore extension overloads in PostgreSqlIdempotencyMediatorBuilderExtensions.
Acceptance Criteria
Dependencies
User Story
As a developer using PostgreSQL with Pulse, I want an
IIdempotencyStorebacked by PostgreSQL ADO.NET, so that I can enforce idempotency in applications that useNetEvolve.Pulse.PostgreSqlwithout adopting EF Core.Background
Mirrors the SQL Server implementation (#227) but uses Npgsql and PostgreSQL-specific DDL (
TIMESTAMP WITH TIME ZONE,ON CONFLICT DO NOTHING).Requirements
src/NetEvolve.Pulse.PostgreSql/Scripts/IdempotencyKey.sql:"{schema}"."IdempotencyKey"withidempotency_key VARCHAR(500) NOT NULL PRIMARY KEYandcreated_at TIMESTAMP WITH TIME ZONE NOT NULL.fn_exists_idempotency_key,fn_insert_idempotency_key,fn_delete_expired_idempotency_keys.PostgreSqlIdempotencyKeyOptions:Schema,TableName,TimeToLive?.PostgreSqlIdempotencyStore : IIdempotencyStorevia Npgsql ADO.NET:ExistsAsync: callsfn_exists_idempotency_key.StoreAsync: callsfn_insert_idempotency_key; ignores PostgreSQL error23505(unique violation).AddPostgreSqlIdempotencyStoreextension overloads inPostgreSqlIdempotencyMediatorBuilderExtensions.Acceptance Criteria
ExistsAsyncreturnstruefor an existing key,falsefor a new one, and ignores expired keys whenTimeToLiveis set.StoreAsyncdoes not throw on error23505.AddPostgreSqlIdempotencyStoreoverloads registerIIdempotencyStoreasScoped.Dependencies
IdempotencyKeySchemaconstants).