openapi: 3.0.3
info:
  title: CLXEND P2P Payment API
  version: 0.1.0-mvp
  description: |
    CLXEND backend API for web + future React Native mobile clients.
    Server-side logic uses TanStack Start `createServerFn` (RPC over POST/GET)
    rather than classic REST routes. Mobile clients call the same Supabase
    backend directly (publishable key + JWT) for reads, and call the server
    functions via the published HTTPS endpoint for writes that need elevated
    privileges or business-logic enforcement.

servers:
  - url: https://project--a060f8fb-5fe1-49a0-b8c6-869d50500708.lovable.app
    description: Preview
  - url: https://YOUR_PROD_DOMAIN
    description: Production

security:
  - bearerAuth: []

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Supabase access token from `supabase.auth.getSession()`.
  schemas:
    Wallet:
      type: object
      properties:
        id: { type: string, format: uuid }
        currency: { type: string, example: USDC }
        kind: { type: string, enum: [FIAT, CRYPTO] }
        balance: { type: number }
    Transaction:
      type: object
      properties:
        id: { type: string, format: uuid }
        sender_id: { type: string, format: uuid }
        recipient_email: { type: string, format: email }
        amount: { type: number }
        currency: { type: string }
        chain: { type: string, enum: [ethereum, polygon, bsc, off-chain] }
        rail: { type: string }
        corridor: { type: string }
        tx_hash: { type: string, nullable: true }
        fraud_score: { type: integer }
        status: { type: string, enum: [PENDING, CONFIRMED, FLAGGED, FAILED, REJECTED] }
        created_at: { type: string, format: date-time }
    Profile:
      type: object
      properties:
        id: { type: string, format: uuid }
        email: { type: string, format: email }
        full_name: { type: string, nullable: true }
        country: { type: string, nullable: true }
        kyc_status: { type: string, enum: [NONE, PENDING, APPROVED, REJECTED] }
        did: { type: string, nullable: true }

paths:
  /api/auth/face-login:
    post:
      summary: Face-based passwordless login (server fn `faceLogin`)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, selfie_base64]
              properties:
                email: { type: string, format: email }
                selfie_base64: { type: string }
      responses:
        '200':
          description: OTP issued — client must verify
          content:
            application/json:
              schema:
                type: object
                properties:
                  otp_sent: { type: boolean }
                  similarity: { type: number }

  /api/kyc/verify:
    post:
      summary: Submit KYC selfie + ID (server fn `submitKyc`)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [selfie_path, id_doc_path, id_type]
              properties:
                selfie_path: { type: string }
                id_doc_path: { type: string }
                id_type: { type: string, enum: [passport, drivers_license, national_id] }
      responses:
        '200':
          description: KYC submission accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: { type: string, enum: [PENDING, APPROVED] }
                  similarity: { type: number }

  /api/remit/send:
    post:
      summary: Send a remittance (server fn `sendTransfer`)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [recipient_email, amount, currency, chain]
              properties:
                recipient_email: { type: string, format: email }
                amount: { type: number, minimum: 0.01 }
                currency: { type: string, enum: [USD, EUR, USDC, USDT, ETH] }
                chain: { type: string, enum: [ethereum, polygon, bsc, off-chain] }
                corridor_code: { type: string }
      responses:
        '200':
          description: Transaction created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Transaction' }

  /api/wallet/balance:
    get:
      summary: Get caller's wallets + profile (server fn `getMyWallet`)
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Wallets
          content:
            application/json:
              schema:
                type: object
                properties:
                  wallets:
                    type: array
                    items: { $ref: '#/components/schemas/Wallet' }
                  profile: { $ref: '#/components/schemas/Profile' }
                  roles:
                    type: array
                    items: { type: string }

  /api/transactions:
    get:
      summary: Paginated transaction history (server fn `listMyTransactions`)
      security:
        - bearerAuth: []
      parameters:
        - in: query
          name: page
          schema: { type: integer, default: 0 }
        - in: query
          name: pageSize
          schema: { type: integer, default: 20, maximum: 100 }
      responses:
        '200':
          description: Page of transactions
          content:
            application/json:
              schema:
                type: object
                properties:
                  transactions:
                    type: array
                    items: { $ref: '#/components/schemas/Transaction' }
                  total: { type: integer }

  /api/admin/overview:
    get:
      summary: Admin dashboard data (server fn `adminOverview`)
      security:
        - bearerAuth: []
      responses:
        '200': { description: Pending KYC, flagged tx, audit, corridors }

  /api/admin/kyc/review:
    post:
      summary: Approve/reject KYC submission (server fn `reviewKyc`)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [submission_id, decision]
              properties:
                submission_id: { type: string, format: uuid }
                decision: { type: string, enum: [APPROVED, REJECTED] }
                notes: { type: string }
      responses:
        '200': { description: KYC reviewed }

  /api/admin/tx/review:
    post:
      summary: Confirm/reject a flagged transaction (server fn `reviewTransaction`)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [tx_id, decision]
              properties:
                tx_id: { type: string, format: uuid }
                decision: { type: string, enum: [CONFIRMED, REJECTED] }
                notes: { type: string }
      responses:
        '200': { description: Decision recorded }

  /api/admin/audit/verify:
    get:
      summary: Re-hash the audit chain and report breaks (server fn `verifyAuditChain`)
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Verification result
          content:
            application/json:
              schema:
                type: object
                properties:
                  total: { type: integer }
                  valid: { type: integer }
                  head_hash: { type: string }
                  breaks:
                    type: array
                    items:
                      type: object
                      properties:
                        id: { type: integer }
                        reason: { type: string }

  /api/compliance/export:
    post:
      summary: GDPR data export — full bundle of caller's data
      security:
        - bearerAuth: []
      responses:
        '200': { description: JSON dump of all user-owned rows }

  /api/compliance/delete:
    post:
      summary: GDPR deletion request (logged, not executed in demo)
      security:
        - bearerAuth: []
      responses:
        '200': { description: Deletion request received }
