docs: update deployment env and runtime docs for convex qwen minio

This commit is contained in:
Codex
2026-02-18 13:59:11 +00:00
parent b1eed7fa2c
commit e056d38ec7
4 changed files with 69 additions and 46 deletions

View File

@@ -1,10 +1,20 @@
# Runtime
NODE_ENV=production
PORT=3000
STATE_FILE_PATH=/data/state.json
LOG_LEVEL=info
APP_BASE_URL=https://xartaudio.example.com
# Better Auth
BETTER_AUTH_SECRET=replace-me
BETTER_AUTH_BASE_PATH=/api/auth
BETTER_AUTH_DEV_PASSWORD=replace-me
# Convex
CONVEX_DEPLOYMENT_URL=https://your-deployment.convex.cloud
CONVEX_AUTH_TOKEN=
CONVEX_STATE_QUERY=state:getLatestSnapshot
CONVEX_STATE_MUTATION=state:saveSnapshot
# Webhook secrets
X_WEBHOOK_SECRET=replace-me
POLAR_WEBHOOK_SECRET=replace-me
@@ -18,19 +28,22 @@ POLAR_ACCESS_TOKEN=replace-me
POLAR_SERVER=production
POLAR_PRODUCT_IDS=prod_123
# TTS (OpenAI-compatible)
TTS_API_KEY=replace-me
TTS_BASE_URL=
TTS_MODEL=gpt-4o-mini-tts
TTS_VOICE=alloy
# Qwen3 TTS
QWEN_TTS_API_KEY=replace-me
QWEN_TTS_BASE_URL=https://dashscope-intl.aliyuncs.com/compatible-mode/v1
QWEN_TTS_MODEL=qwen-tts-latest
QWEN_TTS_VOICE=Cherry
QWEN_TTS_FORMAT=mp3
# S3-compatible object storage
S3_BUCKET=replace-me
S3_REGION=us-east-1
S3_ENDPOINT=
S3_ACCESS_KEY_ID=replace-me
S3_SECRET_ACCESS_KEY=replace-me
S3_SIGNED_URL_TTL_SEC=3600
# MinIO object storage
MINIO_ENDPOINT=minio.example.com
MINIO_PORT=443
MINIO_USE_SSL=true
MINIO_BUCKET=replace-me
MINIO_REGION=us-east-1
MINIO_ACCESS_KEY=replace-me
MINIO_SECRET_KEY=replace-me
MINIO_SIGNED_URL_TTL_SEC=3600
# Credit policy
BASE_CREDITS=1

View File

@@ -4,7 +4,7 @@ WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
ENV STATE_FILE_PATH=/data/state.json
ENV CONVEX_DEPLOYMENT_URL=
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
@@ -15,7 +15,6 @@ COPY spec.md ./spec.md
RUN bun run build:css
EXPOSE 3000
VOLUME ["/data"]
HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD bun -e "fetch('http://127.0.0.1:'+process.env.PORT+'/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

View File

@@ -330,10 +330,10 @@ This repository now contains a deployable production-style app (single container
5. Real integration adapters implemented:
- X API (`twitter-api-v2`)
- Polar SDK checkout/webhook handling (`@polar-sh/sdk`)
- TTS (`openai`)
- Object storage + signed URLs (`@aws-sdk/client-s3`, `@aws-sdk/s3-request-presigner`)
- TTS (`Qwen3 TTS`, OpenAI-compatible endpoint via `fetch`)
- Object storage + signed URLs (`minio`)
6. Persistent state across restarts:
- all wallet/job/asset/access state is snapshotted and stored to `STATE_FILE_PATH`
- all wallet/job/asset/access state is snapshotted through Convex query/mutation functions
7. Abuse protection:
- fixed-window rate limiting for webhook, auth, and action routes
8. PWA support:
@@ -344,9 +344,9 @@ This repository now contains a deployable production-style app (single container
- `bun run lint`
### Authentication model
1. Browser flow uses secure-ish HTTP-only cookie session (`xartaudio_user`) via `/auth/dev-login`.
2. API calls also support `x-user-id` header for scripted usage/testing.
3. This auth layer is intentionally replaceable with X OAuth in production rollout.
1. Browser flow is powered by Better Auth under `/api/auth/*`.
2. `/auth/dev-login` bootstraps a Better Auth session for local/dev testing.
3. API calls also support `x-user-id` header for scripted usage/testing.
### Runtime endpoints
1. Public:
@@ -380,10 +380,17 @@ Use `.env.example` as the source of truth.
1. Runtime:
- `PORT`
- `STATE_FILE_PATH`
- `LOG_LEVEL`
- `APP_BASE_URL`
2. Secrets:
2. Auth + state:
- `BETTER_AUTH_SECRET`
- `BETTER_AUTH_BASE_PATH`
- `BETTER_AUTH_DEV_PASSWORD`
- `CONVEX_DEPLOYMENT_URL`
- `CONVEX_AUTH_TOKEN`
- `CONVEX_STATE_QUERY`
- `CONVEX_STATE_MUTATION`
3. Secrets:
- `X_WEBHOOK_SECRET`
- `POLAR_WEBHOOK_SECRET`
- `X_BEARER_TOKEN`
@@ -391,23 +398,26 @@ Use `.env.example` as the source of truth.
- `POLAR_ACCESS_TOKEN`
- `POLAR_SERVER`
- `POLAR_PRODUCT_IDS`
- `TTS_API_KEY`
- `TTS_BASE_URL`
- `TTS_MODEL`
- `TTS_VOICE`
- `S3_BUCKET`
- `S3_REGION`
- `S3_ENDPOINT`
- `S3_ACCESS_KEY_ID`
- `S3_SECRET_ACCESS_KEY`
- `S3_SIGNED_URL_TTL_SEC`
3. Credit model:
- `QWEN_TTS_API_KEY`
- `QWEN_TTS_BASE_URL`
- `QWEN_TTS_MODEL`
- `QWEN_TTS_VOICE`
- `QWEN_TTS_FORMAT`
- `MINIO_ENDPOINT`
- `MINIO_PORT`
- `MINIO_USE_SSL`
- `MINIO_BUCKET`
- `MINIO_REGION`
- `MINIO_ACCESS_KEY`
- `MINIO_SECRET_KEY`
- `MINIO_SIGNED_URL_TTL_SEC`
4. Credit model:
- `BASE_CREDITS`
- `INCLUDED_CHARS`
- `STEP_CHARS`
- `STEP_CREDITS`
- `MAX_CHARS_PER_ARTICLE`
4. Rate limits:
5. Rate limits:
- `WEBHOOK_RPM`
- `AUTH_RPM`
- `ACTION_RPM`
@@ -416,17 +426,16 @@ Use `.env.example` as the source of truth.
1. Create a new service from this repository and select `Dockerfile` build mode.
2. Set container port to `3000`.
3. Add a persistent volume mounted at `/data`.
4. Set `STATE_FILE_PATH=/data/state.json`.
5. Configure all secrets and policy env vars from `.env.example`.
6. Expose HTTPS URL and point providers to:
3. Configure all secrets and policy env vars from `.env.example`.
4. Ensure `CONVEX_DEPLOYMENT_URL` is reachable from the container network.
5. Expose HTTPS URL and point providers to:
- `https://<your-domain>/api/webhooks/x`
- `https://<your-domain>/api/webhooks/polar`
7. Verify deployment health with `GET /health`.
6. Verify deployment health with `GET /health`.
## Production Checklist
1. Replace dev-login cookie auth with X OAuth before public launch.
2. Populate integration keys in Coolify environment for X, Polar, TTS, and S3.
3. Replace local state file with managed database for multi-replica scaling.
1. Replace `/auth/dev-login` with direct Better Auth UI/OAuth sign-in for public launch.
2. Populate integration keys in Coolify environment for X, Polar, Qwen3 TTS, MinIO, and Convex.
3. Implement Convex functions named by `CONVEX_STATE_QUERY` and `CONVEX_STATE_MUTATION`.
4. Add tracing and external alerting.

View File

@@ -8,7 +8,7 @@ test("Dockerfile contains production container essentials", () => {
const dockerfile = fs.readFileSync("Dockerfile", "utf8");
assert.match(dockerfile, /FROM oven\/bun:1\.3\.5-alpine/);
assert.match(dockerfile, /EXPOSE 3000/);
assert.match(dockerfile, /STATE_FILE_PATH=\/data\/state\.json/);
assert.match(dockerfile, /CONVEX_DEPLOYMENT_URL=/);
assert.match(dockerfile, /bun install --frozen-lockfile/);
assert.match(dockerfile, /bun run build:css/);
assert.match(dockerfile, /HEALTHCHECK/);
@@ -25,8 +25,10 @@ test("env example includes required webhook and credit settings", () => {
assert.match(envFile, /POLAR_WEBHOOK_SECRET=/);
assert.match(envFile, /POLAR_ACCESS_TOKEN=/);
assert.match(envFile, /POLAR_PRODUCT_IDS=/);
assert.match(envFile, /TTS_API_KEY=/);
assert.match(envFile, /S3_BUCKET=/);
assert.match(envFile, /QWEN_TTS_API_KEY=/);
assert.match(envFile, /MINIO_ENDPOINT=/);
assert.match(envFile, /CONVEX_DEPLOYMENT_URL=/);
assert.match(envFile, /BETTER_AUTH_SECRET=/);
assert.match(envFile, /INCLUDED_CHARS=/);
assert.match(envFile, /WEBHOOK_RPM=/);
});