15 KiB
Merchant Analytics API Task List
- Status: Draft for review — implementation not authorized
- Plan:
tasks/plan.md - Contract:
docs/API-SPEC.mdanddocs/openapi.yamlversion1.0.0
Every task must satisfy its acceptance criteria and the standing Definition of Done. File lists are expected blast radii, not permission to modify unrelated files.
Task 1: Establish the OpenAPI toolchain and conformance harness
Description: Select, approve, and pin the Go OpenAPI generation/validation tooling; make contract validation and generated-artifact drift checks reproducible from a clean checkout.
Acceptance criteria:
- One approved pinned toolchain validates OpenAPI 3.1 and produces only the intended server/types artifacts.
- Generated artifacts contain no hand-edited business logic and regenerate with a clean Git diff.
- Stable
operationIdvalues, schemas, media types, and security requirements are covered by a contract test harness.
Verification:
- Run the documented OpenAPI validate/generate/check commands from a clean checkout.
- Run focused generator/conformance tests and confirm a deliberate contract mismatch fails.
- Review generated and lockfile/checksum diffs; approve any new dependency before installation.
Dependencies: Approved implementation authorization and separately approved Go scaffold.
Files likely touched:
go.modgo.suminternal/api/contract/internal/api/contract_test.go- approved command/tool configuration
Estimated scope: Medium (3–5 files/artifact groups)
Task 2: Build the shared HTTP boundary and protected-request middleware
Description: Create the API server boundary for /api/v1, central Problem Details mapping, request ids, 16 KiB body/8 KiB target limits, no-store/security headers, session resolution, and CSRF/origin enforcement.
Acceptance criteria:
- All protected handlers receive merchant/user context only from a verified server-side session.
- Boundary failures use the approved RFC 9457 schema/code/status mapping without internal details.
- Request limits, unknown fields/parameters, CSRF/origin checks, and no-store/security headers behave as specified.
Verification:
- Focused middleware tests cover missing/expired/revoked sessions, malformed input, size limits, request ids, CSRF, and origin/fetch metadata.
- Cross-tenant client inputs cannot create or replace merchant context.
go test ./...andgo vet ./...pass.
Dependencies: Task 1 and approved Identity session-verification interface.
Files likely touched:
internal/api/http/server.gointernal/api/http/problem.gointernal/api/http/middleware.gointernal/api/http/middleware_test.go
Estimated scope: Medium (4 files)
Checkpoint 1: Boundary readiness
- Tasks 1–2 acceptance criteria pass.
- OpenAPI generation is reproducible with a clean diff.
- Human review confirms the tenant and error boundaries before feature handlers begin.
Task 3: Implement authentication session endpoints
Description: Implement login, current-session, and logout as one vertical slice through the approved Identity provider, including secure cookie and generic-failure behavior.
Acceptance criteria:
- Login creates a revocable session and sets only the approved
__Host-zpa_sessioncookie attributes. - Current-session JSON matches OpenAPI and exposes a session-bound CSRF token but no authentication token.
- Logout revokes server state before clearing the cookie; expected credential failures remain indistinguishable and throttled.
Verification:
- Integration tests cover success, enumeration resistance, cookie flags, rotation, expiry, revocation, throttling, CSRF, and dependency failure.
- OpenAPI conformance tests cover all auth statuses and headers.
go test -race ./...passes for affected packages.
Dependencies: Task 2 and approved Identity provider implementation.
Files likely touched:
internal/api/http/auth_handler.gointernal/api/http/auth_handler_test.gointernal/api/identity.gocmd/api/main.go
Estimated scope: Medium (4 files)
Task 4: Implement approved reporting-period discovery
Description: Return only allowlisted day/week/Jalali-month/Persian-season periods with exact UTC/Tehran boundaries, ready Persian labels, and the approved default.
Acceptance criteria:
- Period responses match OpenAPI and use backend-calculated half-open boundaries.
- Iranian weeks start Saturday; default selection is the latest complete Jalali month containing source data.
- Unknown parameters/types are rejected and arbitrary date ranges are impossible.
Verification:
- Table tests cover all period types, month/year boundaries, Saturday–Friday weeks, empty source ranges, and timezone independence.
- Integration tests reconcile returned ids/boundaries with
calendar_dates. - OpenAPI examples and
go test ./...pass.
Dependencies: Task 2 and approved calendar/period provider implementation.
Files likely touched:
internal/api/http/period_handler.gointernal/api/http/period_handler_test.gointernal/api/periods.go
Estimated scope: Medium (3 files)
Task 5: Implement analytics-run start and snapshot retrieval
Description: Implement idempotent run creation/current-run resolution and tenant-scoped snapshot retrieval for all four sections.
Acceptance criteria:
- Same intent/key replays safely, key/body conflicts fail, and equivalent concurrent starts resolve one current run.
- Run snapshots serialize every section state/result exactly as OpenAPI defines.
- Missing and cross-tenant run ids return the same
404 RESOURCE_NOT_FOUNDresponse.
Verification:
- Concurrency tests cover atomic idempotency claim, in-flight duplicates, current revisions, and no duplicate jobs.
- Contract tests cover
200,202,401,403,404,422,429, and dependency failures. - Integration tests assert that rejected/limited requests enqueue no work.
Dependencies: Tasks 1–2 and approved Analytics run provider implementation.
Files likely touched:
internal/api/http/run_handler.gointernal/api/http/run_handler_test.gointernal/api/analytics.gointernal/api/idempotency.go
Estimated scope: Medium (4 files)
Checkpoint 2: Core API flow
- Tasks 3–5 acceptance criteria pass.
- Authenticated merchant flow works through the actual HTTP server and test dependencies.
- Cross-tenant and idempotency adversarial tests pass.
- Human review approves the core flow before streaming/detail work.
Task 6: Implement authenticated SSE delivery and recovery
Description: Stream typed run/section events with 15-second heartbeats, one-hour authorized replay, snapshot reset, and session-aware disconnect/reconnect behavior.
Acceptance criteria:
- Event framing, ids, names, and JSON data match the approved SSE schemas and UTF-8 media type.
- Retained ids replay only later authorized events; unavailable ids reset with
run.snapshotand never disclose another tenant. - Session expiry/revocation, connection limits, and completed-run closure behave as specified.
Verification:
- Integration tests cover ordered partial readiness, failure isolation, suppression, heartbeat timing, replay, reset, disconnect, revocation, and user/merchant connection limits.
- Proxy-style tests assert no buffering/compression and required stream headers.
- Race tests cover concurrent publish/replay/disconnect paths.
Dependencies: Task 5 and approved Analytics event provider implementation.
Files likely touched:
internal/api/http/sse_handler.gointernal/api/http/sse_handler_test.gointernal/api/events.gointernal/api/events_test.go
Estimated scope: Medium (4 files)
Task 7: Implement exhausted-section manual retry
Description: Add the idempotent retry-attempt subresource for one exhausted failed section without disturbing ready siblings.
Acceptance criteria:
- Only an exhausted, retryable failed section for the current run/revisions is accepted.
- Retry idempotency and independent user/merchant throttles prevent duplicate work.
- Ready siblings remain unchanged and stale/cross-tenant requests fail safely.
Verification:
- Tests cover retryable/non-retryable states, duplicate keys, stale revisions, throttling, cross-tenant ids, and no sibling restart.
- Rejected retries enqueue no work.
- OpenAPI conformance and
go test -race ./...pass.
Dependencies: Tasks 5–6.
Files likely touched:
internal/api/http/retry_handler.gointernal/api/http/retry_handler_test.gointernal/api/retry.go
Estimated scope: Medium (3 files)
Checkpoint 3: Asynchronous behavior
- Tasks 6–7 acceptance criteria pass.
- SSE and retry runtime checks pass through the actual queue/cache test boundary.
- Human review confirms recovery and rate-limit behavior.
Task 8: Implement cursor-paginated session detail views
Description: Implement the three approved detail views with deterministic ordering, opaque bound cursors, default 25/maximum 100 rows, and a strict field allowlist.
Acceptance criteria:
UNVERIFIED_PAID,FAILED, andRETRIEDfilters match catalogue definitions and reconcile to aggregates.- Cursors bind tenant, canonical filters, ordering, expiry, and last row; invalid reuse returns generic
INVALID_CURSOR. - Detail rows expose only approved fields and the tenant-scoped opaque terminal reference.
Verification:
- Tests cover page boundaries, duplicate timestamps, cursor tampering/expiry/filter change/cross-tenant reuse, limits, and empty results.
- Integration queries reconcile representative merchants and approved periods.
- Sensitive-field absence and measured query-plan checks pass.
Dependencies: Tasks 2 and 4 plus approved Analytics detail provider implementation.
Files likely touched:
internal/api/http/detail_handler.gointernal/api/http/detail_handler_test.gointernal/api/details.gointernal/api/cursor.gointernal/api/cursor_test.go
Estimated scope: Medium (5 files)
Task 9: Implement safeguarded Persian CSV export
Description: Stream the same authorized detail predicate/projection as Persian CSV with BOM, Persian spaced headers/statuses, machine-safe numeric/ISO values, formula neutralization, and approved caps.
Acceptance criteria:
- CSV and JSON share one canonical tenant/filter/projection policy; CSV adds no unavailable field.
- Output matches the approved encoding, headers, labels, quoting, disposition, no-store, and
nosniffcontract. - Preflight rejects over 100,000 rows/50 MiB, generation ends within 60 seconds, throttling applies, and interrupted streams are audited as incomplete.
Verification:
- Golden tests cover Persian output, BOM, CRLF, quotes/newlines, all status mappings, and stable headers with spaces.
- Security tests cover
=,+,-,@, tab, CR, LF formula prefixes and forbidden-field absence. - Integration tests cover filter parity, snapshot consistency, caps, deadline, disconnect, throttle, and content headers.
Dependencies: Task 8.
Files likely touched:
internal/api/http/export_handler.gointernal/api/http/export_handler_test.gointernal/api/export.gointernal/api/export_test.go
Estimated scope: Medium (4 files)
Checkpoint 4: Reconciliation and data boundary
- Tasks 8–9 acceptance criteria pass.
- Detail/CSV reconciliation and sensitive-data negative tests pass.
- Export resource limits hold under representative merchant volume.
- Human review approves the merchant evidence boundary.
Task 10: Publish the stable API problem-type catalogue
Description: Document every stable application error code and make each approved https://zarinpal.amiirkhl.ir/docs/errors/{error-slug} URI resolve to safe human-readable guidance.
Acceptance criteria:
- Every OpenAPI problem code maps to one stable slug, title, status, meaning, safe resolution guidance, and retry rule.
- Published pages expose no internal topology, SQL, stack, secret, tenant existence, or security-control detail useful for abuse.
- Contract tests fail when a returned problem type/code lacks catalogue documentation.
Verification:
- Link checks confirm every production type URI resolves successfully.
- OpenAPI and catalogue mapping tests pass with no duplicate slug/code.
- Security review approves public wording.
Dependencies: Tasks 2–9 for the final error-code set; hosting mechanism approval.
Files likely touched:
docs/ERROR-CATALOGUE.md- error-page source/template location approved by the hosting plan
internal/api/http/problem_catalogue_test.go
Estimated scope: Medium (2–3 files/artifact groups)
Task 11: Add API audit and observability instrumentation
Description: Instrument the approved audit events, metrics, logs, and traces with bounded-cardinality safe metadata and 90-day analytics/export-audit retention.
Acceptance criteria:
- Required auth/run/SSE/detail/export audit outcomes and operational metrics are emitted with correlation ids.
- Only authorized backend operators can access analytics/export audit records; automatic deletion occurs after 90 days.
- Telemetry excludes credentials, tokens, raw cursors/filters, payment rows, payer tokens, peer data, and high-cardinality sensitive labels.
Verification:
- Tests assert required event/metric emission for success, rejection, failure, timeout, and interrupted export.
- Negative leak tests inspect structured logs, traces, and audit records.
- Retention/access-control tests pass using an accelerated test clock.
Dependencies: Tasks 3–10 and the approved audit/observability adapters.
Files likely touched:
internal/api/observability.gointernal/api/audit.gointernal/api/observability_test.gointernal/api/audit_test.go
Estimated scope: Medium (4 files)
Task 12: Complete contract, security, race, and performance verification
Description: Run and close the full implementation Definition of Done across all API operations and critical failure/abuse paths.
Acceptance criteria:
- Every OpenAPI operation/status/media type/header/security requirement has automated contract coverage.
- Tenant isolation, session/CSRF, idempotency, SSE, cursor, export, audit, and sensitive-field abuse suites pass.
- Representative detail/export query plans and resource bounds meet approved behavior with no unreviewed exception.
Verification:
- Run
go test ./...,go test -race ./...,go vet ./...,golangci-lint run, andgovulncheck ./.... - Run reproducible OpenAPI validation/generation and confirm a clean Git diff.
- Exercise critical merchant flows end to end through the deployed-style proxy/test environment.
Dependencies: Tasks 1–11.
Files likely touched:
- API contract/integration test packages
- approved test fixtures containing no sensitive source data
- API runbook/documentation corrections if verification finds drift
Estimated scope: Medium (3–5 files/artifact groups)
Checkpoint 5: Complete
- Tasks 1–12 and every checkpoint pass.
- Full project Definition of Done is satisfied.
- No unrelated frontend, deployment, physical-schema, ERD, or raw-data changes are included.
- Human review approves completion before merge or deployment.