Skip to content

feat(export): export approved requests exactly once to the ERP mock #9

Description

@Fluory

Goal

Approved requests go through the ERP port to the mock (contracts/erp-export.openapi.yaml) with an idempotency key; a request can never be exported twice.

Acceptance criteria

  • The ERP mock stores idempotency keys; a repeated POST with the same key returns the same ERP reference
  • Export record with unique(request_id); transition APPROVED → EXPORTED under a row lock
  • With injected 5xx/timeouts and duplicate job delivery, the request ends EXPORTED exactly once
  • Outbound timeout configured; failures visible as ERROR (stage export)
  • The mock is active only with ERP_MOCK_ENABLED=true

Not part of this task

  • Real ERP mapping, file-based export

Affected areas

  • src/features/export/
  • src/features/erp-mock/
  • contracts/erp-export.openapi.yaml

Test plan

Criterion Check
exactly once integration test with injected failures and duplicate delivery
contract contract test against the OpenAPI schema

Security/Privacy affected?

Outbound data contains personal contact data – synthetic only; no payloads in logs.

Epic: #2 · Architecture: docs/decisions/ADR-0001-pilot-architecture.md

Activity

  1. added
    featureNew capability
    readyDefinition of Ready met – may be claimed
    on Sep 22, 2026
  2. self-assigned this
    on Sep 23, 2026
  3. Fluory commented on Sep 23, 2026

    @Fluory
    OwnerAuthor

    Claimed by @Fluory (Claude Code, overnight run) on branch claude/feat-erp-export-9 – stacked on #35 (claude/feat-review-ui-8). Draft PR follows.


    Generated by Claude Code

  4. Fluory commented on Sep 23, 2026

    @Fluory
    OwnerAuthor

    decision-needed – ERP mock: where it stores idempotency keys

    ADR-0001 D9 says the mock "stores idempotency keys" but not where. Options:

    1. In memory in the web process, behind a small MockStore interface (taken, most reversible). No schema and no entry in the exceptions register. Downside: a restart of the web process forgets the keys, and it works only with a single web instance, not on serverless or with several replicas. Our side still blocks double exports: the unique request_exports row plus EXPORTED under a row lock.
    2. A table (e.g. schema erp_mock). Survives restarts. It would be a table without tenant RLS, because the mock stands in for a foreign system, so it needs an entry in the exceptions register and a migration.

    Revisit when the showcase runs on Vercel (D11) or the demo needs keys that survive a restart.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

featureNew capabilityreadyDefinition of Ready met – may be claimed

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions