Wocart

Configuration

Every value lives in one of four places. Each file has an .example beside it in the repository: copy it, then change what this page says to change.

FileHoldsCommitted?
.env (repository root)Resource names the setup and deploy scripts useNo
cod-server/wrangler.tomlThe API server's bindings and variablesNo: it holds your resource IDs
cod-client-astro/wrangler.tomlThe dashboard's bindings and variablesNo
.dev.vars (in each application)Secrets for local developmentNo

Deployed, a secret is never in a file: it is set with wrangler secret put <NAME> and read by the Worker at runtime.

Store settings (payments, carriers, Meta, verification) are not configuration: a merchant sets them in the dashboard, and they are kept in the store's database.

Root .env

Read by the database scripts, the media bucket setup and the storefront's deploy script. A value in the environment wins over the file, and the file wins over the default.

KeyDefaultMeaning
COD_ACCOUNT_IDnoneYour Cloudflare account ID
COD_DB_NAMEcodflow-os-dbThe D1 database's name: the same as database_name in both wrangler.toml files
COD_R2_BUCKET_NAMEcodflow-imagesThe R2 bucket's name
COD_SERVER_URLhttp://localhost:8787The deployed API's origin, which the storefront calls. The storefront's deploy refuses a localhost value
ASTRO_KEYnoneThe storefront build's server-island key (npx astro create-key in cod-astro/theme-00). Keep it: a new key per deploy breaks pages still in the cache

API server

Bindings

BindingTypeRequiredWhat it is for
DBD1YesThe store's database (migrations_dir = "src/db/migrations")
MEDIA_BUCKETR2YesUploads waiting to be prepared, and the store's files when they are kept on R2
OAUTH_KVKVYesAI-agent sign-in: clients, grants and tokens
RATE_LIMITKVRecommendedRate limits on verification codes and on AI-agent calls
IMAGE_TRANSFORMImagesRecommendedRe-encodes uploaded photos to WebP, which drops their location data. Without it, an uploaded photo is never kept
EVENTS_QUEUEQueue (producer and consumer)YesWakes the delivery of events and the carriers' webhook inbox
LP_IMAGE_UPLOAD_WORKFLOWWorkflowYesPrepares images an AI agent adds to a landing page
REVIEW_MEDIA_WORKFLOWWorkflowFor review mediaPrepares a review's photos and voice note
CAPI_WORKFLOWWorkflowYes, for nowLets conversions started by an older release finish
REVIEW_RATE_LIMITERRate limitRecommendedReview attempts per order number

The server also needs both scheduled triggers:

Code
[triggers] crons = ["0 * * * *", "*/5 * * * *"]

Production bindings are not inherited

In Wrangler, a binding declared at the top of wrangler.toml does not reach [env.production]. The example declares every binding twice; keep both lists complete, or a production deploy ships without the missing one.

Variables

VariableExampleMeaning
ENVIRONMENTproductiondevelopment locally
WORKER_URLhttps://api.yourdomain.comThe server's public URL
WORKER_SELF_URLhttps://api.yourdomain.com/The server's own origin: AI-agent tokens must be issued for it, and Telegram calls it back
BETTER_AUTH_URLhttps://dashboard.yourdomain.com/api/authWhere the dashboard signs users in; the server checks the dashboard's tokens against it
ALLOWED_ORIGINShttps://dashboard.yourdomain.com,https://shop.yourdomain.comOrigins allowed to call the API from a browser, comma-separated. * locally
STOREFRONT_URLhttps://shop.yourdomain.comOptional: the storefront's address for landing-page links, until the merchant sets the store's domain
MEDIA_HOST, MEDIA_DELIVERY, MEDIA_ORIGIN, IMAGEKIT_PUBLIC_KEY, IMAGEKIT_FOLDERWhere files are kept and served: Media
TELEGRAM_UPDATES_ORIGINhttps://<name>.trycloudflare.comOptional, local only: a tunnel Telegram can reach

Secrets

SecretRequiredMeaning
MCP_LOGIN_TICKET_SECRETFor AI agentsAt least 32 bytes. The same value as the dashboard's. Without it, AI-agent sign-in is refused
REVIEW_UPLOAD_SECRETFor review mediaAt least 32 bytes. Without it, reviews are text only
IMAGEKIT_PRIVATE_KEYWith ImageKitImageKit's private key

Generate a value with openssl rand -hex 32.

Dashboard

Bindings and variables

NameMeaning
DBThe same D1 database as the API server: users and their sessions live there
RATE_LIMIT_KVSign-in rate limits and sessions: a KV namespace of its own
PUBLIC_APP_URLThe dashboard's own URL
PUBLIC_API_URLThe API server's origin, which the browser calls
PUBLIC_TRUSTED_ORIGINSEvery origin the dashboard is opened from, comma-separated: its workers.dev address and its custom domain. A missing one answers 403 INVALID_ORIGIN on sign-in

PUBLIC_API_URL is written into the browser code when the dashboard is built, so changing it needs a rebuild. Locally it comes from .dev.vars; deployed, from wrangler.toml. A value in .env is ignored: .dev.vars outranks it. npm run deploy sets .dev.vars aside while it builds and refuses to upload a dashboard that still calls localhost.

Secrets

SecretMeaning
BETTER_AUTH_SECRETThe sign-in secret. Set it once and keep it
MCP_LOGIN_TICKET_SECRETThe same value as the API server's

Storefront

Theme-00 reads three values, the same on Cloudflare and on Vercel:

NameKindMeaning
COD_SERVER_URLVariableThe API's origin. Its deploy script takes it from the root .env
STORE_API_KEYSecretThe store's API key, as it was given to db:seed:remote
WOCART_PREVIEW_KEYSecret, optionalThe public key that checks preview tokens; without it, preview is off

Locally all three are in cod-astro/theme-00/.dev.vars.

The store API key

The store API key is created by the database setup, which keeps only its hash. The storefront holds the key itself. Locally, both use the default in cod-astro/theme-00/.dev.vars.example. Deployed, choose one (openssl rand -hex 32), give it to db:seed:remote as STORE_API_KEY, and set the same value as the storefront's secret. The API server does not need it.