From d133019a14cdab03cb38920e6889970efeb3d812 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Thu, 20 Aug 2026 18:17:19 +0330 Subject: [PATCH] docs(api): localize CSV columns in Persian --- docs/API-SPEC.md | 12 ++++++------ docs/openapi.yaml | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/docs/API-SPEC.md b/docs/API-SPEC.md index 245c445..791d64a 100644 --- a/docs/API-SPEC.md +++ b/docs/API-SPEC.md @@ -128,7 +128,7 @@ Detail rows expose only fields available in the authorized view: opaque merchant - `Content-Type: text/csv; charset=utf-8` - UTF-8 with one leading BOM for common Persian spreadsheet compatibility - RFC 4180-style comma separation, header row, CRLF records, and doubled quotes -- Stable ASCII `snake_case` column names; Persian values remain UTF-8 +- Stable Persian column names separated by normal spaces, with Persian status labels - UTC ISO timestamps with `Z`; Rial integer values; no locale-formatted numbers - `Content-Disposition: attachment` with an ASCII `filename` fallback followed by an RFC 6266 `filename*=UTF-8''...` value - `Cache-Control: private, no-store` and `X-Content-Type-Options: nosniff` @@ -273,14 +273,14 @@ Correlate `requestId`, authenticated user/merchant internal ids, run id, section - Merchant-facing detail CSV export is synchronous in the MVP and honors the current authorized tenant scope and approved filters. - CSV export is capped at 100,000 rows, 50 MiB estimated uncompressed output, and a 60-second deadline. - CSV export is limited to 3 requests per 10 minutes with burst 1 in independent authenticated-user and merchant buckets. +- CSV uses UTF-8 with a BOM, Persian column names separated by normal spaces, and Persian status labels. Numeric cells remain plain calculation-safe numbers and timestamps remain UTC ISO values. ## Remaining product questions -1. Approve UTF-8 BOM output for spreadsheet compatibility and stable ASCII column headers, or require localized Persian header names. -2. Define retention and operator access policy for analytics-access and CSV-export audit records; Identity's 30-day demo-auth retention does not automatically cover these events. -3. Confirm whether terminal identifiers may be shown/exported as their existing opaque source reference or require a separate merchant-facing display alias. -4. Choose the production base URI used for dereferenceable Problem Details `type` documentation; `https://api.zarinpal.example/problems/...` is a non-production placeholder in the draft contract. -5. Approve or revise the proposed public-edge request limits: 16 KiB for JSON bodies and 8 KiB for the request target/query string. +1. Define retention and operator access policy for analytics-access and CSV-export audit records; Identity's 30-day demo-auth retention does not automatically cover these events. +2. Confirm whether terminal identifiers may be shown/exported as their existing opaque source reference or require a separate merchant-facing display alias. +3. Choose the production base URI used for dereferenceable Problem Details `type` documentation; `https://api.zarinpal.example/problems/...` is a non-production placeholder in the draft contract. +4. Approve or revise the proposed public-edge request limits: 16 KiB for JSON bodies and 8 KiB for the request target/query string. ## Standards references diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 975464d..06b96c9 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -453,14 +453,19 @@ paths: description: | Uses the same tenant scope, approved period, filters, and allowlisted projection as `listAnalyticsSessionDetails`. Cursor and page limit do not - apply. Output is UTF-8 with a BOM, an ASCII snake_case header row, comma - separators, CRLF records, and RFC 4180 quoting. + apply. Output is UTF-8 with a BOM, a Persian header row whose labels use + normal spaces, comma separators, CRLF records, and RFC 4180 quoting. Stable columns are: - `session_id`, `terminal_id`, `session_status`, `amount_rial`, - `fee_amount_rial`, `created_at`, `expires_at`, `attempt_count`, - `latest_attempt_status`, `latest_attempt_at`, `verified_at`, `settled_at`, - `failure_stage`. + `شناسه نشست پرداخت`, `شناسه پایانه`, `وضعیت پرداخت`, `مبلغ ریال`, + `کارمزد ریال`, `زمان ایجاد`, `زمان انقضا`, `تعداد تلاش`, + `وضعیت آخرین تلاش`, `زمان آخرین تلاش`, `زمان تأیید`, `زمان تسویه`, + `مرحله مشاهده شده شکست`. + + CSV status labels are Persian: `Paid` is `پرداخت شده و تأیید نشده`, + `Verified` is `تأیید شده`, `Failed` is `ناموفق`, `Reversed` is + `برگشت خورده`, and `InBank` is `در بانک`. Numeric cells remain plain + calculation-safe numbers and timestamps remain UTC ISO values. Columns unavailable to the chosen authorized view are empty. Payer tokens, credentials, peer data, internal ids, and any field unavailable in the JSON @@ -497,7 +502,7 @@ paths: schema: type: string contentMediaType: text/csv - example: "\uFEFFsession_id,terminal_id,session_status,amount_rial,fee_amount_rial,created_at,expires_at,attempt_count,latest_attempt_status,latest_attempt_at,verified_at,settled_at,failure_stage\r\nses_01K2M8,term_0042,Paid,1500000,2000,2026-06-01T08:00:00Z,2026-06-01T08:15:00Z,1,Paid,2026-06-01T08:02:00Z,,,\r\n" + example: "\uFEFF\"شناسه نشست پرداخت\",\"شناسه پایانه\",\"وضعیت پرداخت\",\"مبلغ ریال\",\"کارمزد ریال\",\"زمان ایجاد\",\"زمان انقضا\",\"تعداد تلاش\",\"وضعیت آخرین تلاش\",\"زمان آخرین تلاش\",\"زمان تأیید\",\"زمان تسویه\",\"مرحله مشاهده شده شکست\"\r\nses_01K2M8,term_0042,پرداخت شده و تأیید نشده,1500000,2000,2026-06-01T08:00:00Z,2026-06-01T08:15:00Z,1,پرداخت شده و تأیید نشده,2026-06-01T08:02:00Z,,,\r\n" '400': $ref: '#/components/responses/BadRequest' '401':