# --------------------------------------------------------------------------- # Smart Organization — sample environment file. # Copy to `.env` and fill in real values. NEVER commit a real `.env`. # Every external provider defaults to `mock` so the stack runs with zero # credentials. Flip the *_PROVIDER vars once real credentials exist. # --------------------------------------------------------------------------- APP_ENV=development APP_URL=http://localhost:3000 API_URL=http://localhost:8000 # Origins the browser is allowed to call the API from, comma-separated. # `localhost` and `127.0.0.1` are DIFFERENT origins to a browser: if you start # the dev server with `-H 127.0.0.1` and this list only has `localhost`, every # request fails with an opaque "Disallowed CORS origin". Both are listed here. # Production must set this explicitly — the dev default is rejected at boot. CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 # --- Data stores ----------------------------------------------------------- DATABASE_URL=postgresql+psycopg://agy:agy@localhost:5432/agy_web REDIS_URL=redis://localhost:6379/0 # --- Security -------------------------------------------------------------- # Generate with: python -c "import secrets; print(secrets.token_urlsafe(48))" JWT_SECRET=change-me # Must be exactly 32 bytes, base64/hex encoded. ENCRYPTION_KEY=change-me-32-bytes # --- AI models (hidden from customers) ------------------------------------- # agy (Google Antigravity) is the only model provider. The setting is kept for # compatibility with older .env files; any value is ignored (with a warning). AI_DEFAULT_PROVIDER=agy # --- agy (Google Antigravity) ---------------------------------------------- # The only model provider. There are no API keys: accounts are Google # identities logged in via OAuth from the admin console # (/admin/agy-accounts → افزودن اکانت agy). Any number of accounts can be added — # the rotation pool spreads load across them and benches a rate-limited one # until its quota window resets. AGY_CLIENT_ID/SECRET default to the public # Antigravity CLI application; override them to use your own Google OAuth # client. AGY_REDIRECT_URI must stay a loopback URL. AGY_CLIENT_ID= AGY_CLIENT_SECRET= AGY_REDIRECT_URI=http://localhost:51121/oauth-callback # Seconds an account is benched after a 429 when Google sends no Retry-After. AGY_429_COOLDOWN_SECONDS=900 # --- Git provider ---------------------------------------------------------- # mock | gitea GIT_PROVIDER=mock GITEA_URL= GITEA_INTERNAL_URL= GITEA_ADMIN_TOKEN= # --- Preview domain routing ------------------------------------------------ # mock | caddy DOMAIN_ROUTER=mock PREVIEW_ROOT_DOMAIN=msa.artacloud.ir PREVIEW_PORT_START=8080 PREVIEW_PORT_END=8999 CADDYFILE_PATH=/etc/caddy/Caddyfile # --- Sandbox --------------------------------------------------------------- # mock | daytona | e2b SANDBOX_PROVIDER=mock DAYTONA_API_KEY= DAYTONA_API_URL= E2B_API_KEY= # --- Payments -------------------------------------------------------------- # mock | stripe PAYMENT_PROVIDER=mock STRIPE_SECRET_KEY= STRIPE_WEBHOOK_SECRET= # --- Error logging --------------------------------------------------------- # Every failure the platform catches is written to the `error_events` table and # is readable at /admin/errors (platform owner only). Errors are redacted before # they are stored — passwords, tokens, API keys, JWTs and DSN credentials are # stripped by app/core/redact.py. # # ERROR_LOG_ENABLED=0 turns persistence off entirely; failures still reach # stderr, but nothing is written to the database. ERROR_LOG_ENABLED=1 # Whether 4xx responses are recorded too. Off by default: a public API receives # a constant stream of 404s from scanners, and recording them all buries the # genuine bugs. Turn it on while debugging a misbehaving client. # 5xx responses are always recorded, whatever this is set to. ERROR_LOG_CLIENT_ERRORS=0