# render.yaml — ViVest (FREE TIER)
# 3 web services + 3 cron jobs — all on Render free plan.
#
# HOW IT WORKS:
#   - The API may sleep after 15 min of inactivity on free tier.
#   - Cron Job services wake it up on schedule by calling /cron/* endpoints.
#   - A "keep-alive" cron pings the API, frontend, and admin dashboard
#     every 14 minutes so all three stay warm during business hours
#     (6 AM – midnight WAT).
#
# DEPLOY: Render Dashboard → New → Blueprint → select this repo.

services:

  # ===========================================================
  # 1. BACKEND API  (Node.js / Express)
  # ===========================================================
  - type: web
    name: dsl-api
    runtime: node
    rootDir: backend
    buildCommand: npm install && npm run build
    startCommand: npm start
    healthCheckPath: /health
    plan: free
    autoDeploy: true
    buildFilter:
      paths:
        - backend/**
    envVars:
      - key: NODE_ENV
        value: production
      - key: API_VERSION
        value: v1

      # Supabase — fill in Render Dashboard (mark as secret)
      - key: SUPABASE_URL
        sync: false
      - key: SUPABASE_ANON_KEY
        sync: false
      - key: SUPABASE_SERVICE_ROLE_KEY
        sync: false

      # JWT — Set a stable secret in Render Dashboard after first deploy.
      # Do NOT use generateValue: Render regenerates it on every deploy,
      # which invalidates all active user sessions on each redeploy.
      - key: JWT_SECRET
        sync: false
      - key: JWT_EXPIRES_IN
        value: 7d
      - key: JWT_REFRESH_EXPIRES_IN
        value: 30d

      # Paystack — fill in Render Dashboard
      - key: PAYSTACK_SECRET_KEY
        sync: false
      - key: PAYSTACK_PUBLIC_KEY
        sync: false
      - key: PAYSTACK_WEBHOOK_SECRET
        sync: false

      # Termii (SMS/OTP) — fill in Render Dashboard
      # The codebase uses Termii (src/utils/otp.ts), not Twilio.
      - key: TERMII_API_KEY
        sync: false
      - key: TERMII_SENDER_ID
        sync: false

      # Web Push (VAPID) — generate once with: npx web-push generate-vapid-keys
      # then paste the values in the Render Dashboard
      - key: VAPID_PUBLIC_KEY
        sync: false
      - key: VAPID_PRIVATE_KEY
        sync: false
      - key: VAPID_SUBJECT
        value: "mailto:support@decembersavings.ng"

      # Email (SMTP) — fill in Render Dashboard
      - key: SMTP_HOST
        sync: false
      - key: SMTP_PORT
        value: "587"
      - key: SMTP_USER
        sync: false
      - key: SMTP_PASS
        sync: false
      - key: EMAIL_FROM
        value: "ViVest <noreply@vivest.ng>"

      # CRON_SECRET — protects /cron/* endpoints
      # Must match the value set in all cron job services below
      - key: CRON_SECRET
        generateValue: true

      # Update these after first deploy to your real Render URLs
      - key: FRONTEND_URL
        value: https://dsl-frontend.onrender.com
      - key: ADMIN_URL
        value: https://dsl-admin.onrender.com

      - key: APP_NAME
        value: "ViVest"

  # ===========================================================
  # 2. USER FRONTEND  (Next.js)
  # ===========================================================
  - type: web
    name: dsl-frontend
    runtime: node
    rootDir: frontend
    buildCommand: npm install && npm run build
    startCommand: npm start
    plan: free
    autoDeploy: true
    buildFilter:
      paths:
        - frontend/**
    envVars:
      - key: NODE_ENV
        value: production
      - key: NEXT_PUBLIC_API_URL
        value: https://dsl-api.onrender.com/api/v1
      # Fill these in Render Dashboard, then manually redeploy frontend
      - key: NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY
        sync: false
      - key: NEXT_PUBLIC_SUPABASE_URL
        sync: false
      - key: NEXT_PUBLIC_SUPABASE_ANON_KEY
        sync: false
      - key: NEXT_PUBLIC_APP_NAME
        value: "ViVest"

  # ===========================================================
  # 3. ADMIN DASHBOARD  (Next.js)
  # ===========================================================
  - type: web
    name: dsl-admin
    runtime: node
    rootDir: admin
    buildCommand: npm install && npm run build
    startCommand: npm start
    plan: free
    autoDeploy: true
    buildFilter:
      paths:
        - admin/**
    envVars:
      - key: NODE_ENV
        value: production
      - key: NEXT_PUBLIC_API_URL
        value: https://dsl-api.onrender.com/api/v1

  # ===========================================================
  # 4. CRON: KEEP-ALIVE PINGER
  # Pings the API, frontend, and admin dashboard every 14 min during
  # business hours to prevent the free-tier services from sleeping.
  # Uses backend/scripts/keep-alive.js — retries once on a cold-start
  # timeout instead of failing immediately (see script comments).
  # WAT = UTC+1. This runs 5 AM–11 PM UTC (6 AM–midnight WAT).
  # ===========================================================
  - type: cron
    name: dsl-keep-alive
    runtime: node
    rootDir: backend
    buildCommand: npm install && npm run build
    schedule: "*/14 5-23 * * *"
    startCommand: node scripts/keep-alive.js
    plan: free
    envVars:
      - key: PING_URLS
        value: "api=https://dsl-api.onrender.com/health,frontend=https://dsl-frontend.onrender.com,admin=https://dsl-admin.onrender.com"
      - key: PING_TIMEOUT_MS
        value: "20000"

  # ===========================================================
  # 5. CRON: AUTO-DEBIT
  # Runs at 9:00 AM WAT (8:00 AM UTC) daily.
  # Charges saved card authorizations for all due schedules.
  # ===========================================================
  - type: cron
    name: dsl-cron-auto-debit
    runtime: node
    rootDir: backend
    buildCommand: npm install && npm run build
    schedule: "0 8 * * *"
    startCommand: >
      node -e "
        fetch(process.env.API_URL + '/cron/auto-debit', {
          method: 'POST',
          headers: { 'Authorization': 'Bearer ' + process.env.CRON_SECRET }
        })
        .then(r => r.json())
        .then(d => { console.log('Auto-debit result:', JSON.stringify(d)); process.exit(d.success ? 0 : 1); })
        .catch(e => { console.error('Auto-debit failed:', e.message); process.exit(1); });
      "
    plan: free
    envVars:
      - key: API_URL
        value: https://dsl-api.onrender.com
      - key: CRON_SECRET
        sync: false   # Copy value from dsl-api service after first deploy

  # ===========================================================
  # 6. CRON: RETRY FAILED DEBITS
  # Runs at 2:00 PM WAT (1:00 PM UTC) daily.
  # Retries any auto-debits that failed in the morning run.
  # ===========================================================
  - type: cron
    name: dsl-cron-retry-debits
    runtime: node
    rootDir: backend
    buildCommand: npm install && npm run build
    schedule: "0 13 * * *"
    startCommand: >
      node -e "
        fetch(process.env.API_URL + '/cron/retry-debits', {
          method: 'POST',
          headers: { 'Authorization': 'Bearer ' + process.env.CRON_SECRET }
        })
        .then(r => r.json())
        .then(d => { console.log('Retry result:', JSON.stringify(d)); process.exit(d.success ? 0 : 1); })
        .catch(e => { console.error('Retry failed:', e.message); process.exit(1); });
      "
    plan: free
    envVars:
      - key: API_URL
        value: https://dsl-api.onrender.com
      - key: CRON_SECRET
        sync: false

  # ===========================================================
  # 7. CRON: MATURITY CHECK
  # Runs at midnight UTC daily.
  # Marks matured plans, creates delivery records.
  # ===========================================================
  - type: cron
    name: dsl-cron-maturity
    runtime: node
    rootDir: backend
    buildCommand: npm install && npm run build
    schedule: "0 0 * * *"
    startCommand: >
      node -e "
        fetch(process.env.API_URL + '/cron/maturity-check', {
          method: 'POST',
          headers: { 'Authorization': 'Bearer ' + process.env.CRON_SECRET }
        })
        .then(r => r.json())
        .then(d => { console.log('Maturity result:', JSON.stringify(d)); process.exit(d.success ? 0 : 1); })
        .catch(e => { console.error('Maturity check failed:', e.message); process.exit(1); });
      "
    plan: free
    envVars:
      - key: API_URL
        value: https://dsl-api.onrender.com
      - key: CRON_SECRET
        sync: false
