Files
zarinpal-analytics-backend/tasks/todo.md

363 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Merchant Analytics API Task List
- Status: Approved task breakdown — implementation not authorized
- Plan: `tasks/plan.md`
- Contract: `docs/API-SPEC.md` and `docs/openapi.yaml` version `1.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 `operationId` values, 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.mod`
- `go.sum`
- `internal/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 ./...` and `go vet ./...` pass.
**Dependencies:** Task 1 and approved Identity session-verification interface.
**Files likely touched:**
- `internal/api/http/server.go`
- `internal/api/http/problem.go`
- `internal/api/http/middleware.go`
- `internal/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_session` cookie 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.go`
- `internal/api/http/auth_handler_test.go`
- `internal/api/identity.go`
- `cmd/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.go`
- `internal/api/http/period_handler_test.go`
- `internal/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_FOUND` response.
**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.go`
- `internal/api/http/run_handler_test.go`
- `internal/api/analytics.go`
- `internal/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.snapshot` and 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.go`
- `internal/api/http/sse_handler_test.go`
- `internal/api/events.go`
- `internal/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.go`
- `internal/api/http/retry_handler_test.go`
- `internal/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`, and `RETRIED` filters 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.go`
- `internal/api/http/detail_handler_test.go`
- `internal/api/details.go`
- `internal/api/cursor.go`
- `internal/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 `nosniff` contract.
- [ ] 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.go`
- `internal/api/http/export_handler_test.go`
- `internal/api/export.go`
- `internal/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.go`
- `internal/api/audit.go`
- `internal/api/observability_test.go`
- `internal/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`, and `govulncheck ./...`.
- [ ] 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.