Skip to content

Configuration

This document provides an overview of the key dependencies and external services used in the platform.

Dependencies

Setup for external services:

  • Twilio - Used to send SMS messages containing important notifications. These include alerts when produce is nearing the end of its shelf life, when a product is sold on the marketplace, or when inviting users to join the app.
  • Sentry - Used for real-time error tracking and performance monitoring across both frontend and backend. Sentry helps developers quickly identify, triage, and resolve issues in production.
  • Paystack - Integrated as the payment gateway for handling financial transactions. It enables secure payment processing for marketplace sales and other financial operations within the platform.
  • Sendgrid - Used for sending transactional emails, such as operator notifications and invitations to join the app. It ensures reliable email delivery and provides analytics for engagement tracking.

All credentials for these services should be treated as deployment-time secrets. Checked-in configuration files should contain placeholders only.

Sensor Provider Settings

Inficold and Ecozen use server-side credentials. These are Base API settings, read by the web and Celery containers. They aren't mobile app settings: the app never receives them, and setting them in the mobile environment has no effect.

Variable Default Purpose
INFICOLD_API_URL https://infilog.com/api/coldtivate/get_scr_data.php Inficold's official history endpoint. Configurable so mock-server and staging runs can point elsewhere.
INFICOLD_API_TOKEN (empty) Secret. Coldtivate's bearer token for the Inficold history API. Required for Inficold setup and polling.
ECOZEN_CLIENT_ID (empty) Coldtivate's Ecozen OAuth2 client ID. Required for Ecozen connection tests and polling. Save verifies the successful-test ticket without requesting a token.
ECOZEN_CLIENT_SECRET (empty) Secret. Coldtivate's Ecozen OAuth2 client secret.

If a provider's settings are empty, only that provider's setup and polling fail, with a configuration error. The rest of the platform is unaffected.

Ecozen OAuth2

Ecozen data requests use OAuth2 client credentials. The endpoints are fixed in the code:

  • Token endpoint: https://openid.ecozen.ai/realms/ecozen/protocol/openid-connect/token
  • Graph endpoint: https://apis.ecozen.ai/dashboard/v3/ecofrost/graph/{machine_id}

The Base API requests a token with a form-encoded client_credentials grant (client_id, client_secret, grant_type=client_credentials), then sends Authorization: Bearer <access_token> on graph requests.

  • Token reuse:
    • Tokens are shared through the Base API's Redis cache until their reported expiry, minus a safety margin.
    • One worker renews a token at a time, and a token is refreshed at most once if a graph request is rejected with 401.
    • A token without a reported expiry isn't shared.
  • No stored tokens: tokens are never saved to the database, logs or app responses. Cache keys are HMACs, never the client ID or secret.
  • Rate limits: a 429 starts a cooldown shared by all workers, honouring Retry-After. See Ecozen rate limits.

The following optional environment variables are read directly by ecozen.py, which owns their defaults; they are not registered in Django settings. They apply only to Ecozen. The defaults are cautious placeholders, not confirmed Ecozen limits:

Variable Default Purpose
ECOZEN_MAX_CONCURRENT_REQUESTS 2 Graph requests in flight per client across all workers. 0 disables the limit.
ECOZEN_CONCURRENCY_RETRY_SECONDS 60 When polls retry after finding every request slot busy.
ECOZEN_RATE_LIMIT_BACKOFF_SECONDS 60 First cooldown after a 429 without a usable Retry-After. It doubles per consecutive 429.
ECOZEN_RATE_LIMIT_MAX_BACKOFF_SECONDS 900 Longest such backoff.
ECOZEN_POLL_RESCHEDULE_JITTER_SECONDS 120 Random spread added when polls are rescheduled after a rate limit or cooldown.
ECOZEN_POLL_MAX_RESCHEDULE_SECONDS 3000 Longest single poll reschedule. Keep it below the Celery broker's visibility timeout (1 hour by default). Longer cooldowns become several shorter waits.

The coordination needs the shared Redis cache (REDIS_*) to be reachable from the web and Celery containers.

Secret handling

  • Keep INFICOLD_API_TOKEN and ECOZEN_CLIENT_SECRET in deployment secret storage. Checked-in dotenv files contain empty placeholders only.
  • Both settings are read on every token request or poll, so a rotated value takes effect for the next request after the web and Celery containers restart. Polling history is kept.
  • Never paste real tokens, client secrets, portal credentials, cookies or captured sessions into issues, logs or documentation.

For setup and troubleshooting, see the Ecozen Integration Guide and the Inficold Integration Guide.

Trusted Proxy Configuration

The Base API uses NUM_PROXIES to determine the client IP used by IP-based rate limits.

NUM_PROXIES=2

The default value of 2 matches the hosted production path:

client -> Cloudflare -> Caddy -> Base API

Set the value to the number of trusted proxy hops in the deployment. For example, a direct local connection to Django has no trusted proxies, while a tunnel placed in front of the standard stack adds another hop. Do not copy the production default blindly into a topology with a different proxy chain: selecting the wrong address from X-Forwarded-For can make rate limits ineffective or cause unrelated clients to share a throttle bucket.