forked from wangziqi/gongxue-base
190 lines
8.6 KiB
Plaintext
190 lines
8.6 KiB
Plaintext
# Supabase/PostgreSQL SaaS 题库后端配置(服务端/worker 使用,前端不读取此文件)
|
||
# 复制此文件为 .env 并填写实际值。
|
||
# 生产上线前运行:
|
||
# npm run readiness:production
|
||
# npm run readiness:production:db
|
||
|
||
# 运行环境。生产必须是 production;本地开发可用 development。
|
||
NODE_ENV=development
|
||
|
||
# API 服务端口
|
||
PORT=8787
|
||
API_HEADERS_TIMEOUT_MS=15000
|
||
API_REQUEST_TIMEOUT_MS=120000
|
||
API_KEEP_ALIVE_TIMEOUT_MS=5000
|
||
API_SHUTDOWN_GRACE_PERIOD_MS=30000
|
||
API_MAX_REQUESTS_PER_SOCKET=1000
|
||
|
||
# Supabase/PostgreSQL 重构 API
|
||
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
|
||
# 本地 postgres 可留空;生产 API 必须为 tiku_api,worker 必须为 tiku_worker。
|
||
DB_EXPECTED_RUNTIME_ROLE=
|
||
# 不要在 .env 中持久化 SMOKE_SEED_CONFIRM;破坏性测试只通过受控 npm script/CLI 临时确认。
|
||
# API/worker 各自进程使用。生产建议 API 10-20、worker 4-8,并结合 PgBouncer/连接池总量核算。
|
||
DB_POOL_MAX=10
|
||
DB_CONNECTION_TIMEOUT_MS=5000
|
||
DB_QUERY_TIMEOUT_MS=35000
|
||
DB_STATEMENT_TIMEOUT_MS=30000
|
||
DB_LOCK_TIMEOUT_MS=5000
|
||
DB_IDLE_IN_TRANSACTION_TIMEOUT_MS=30000
|
||
DB_IDLE_TIMEOUT_MS=30000
|
||
DB_POOL_MAX_USES=7500
|
||
DB_POOL_MAX_LIFETIME_SECONDS=1800
|
||
DB_APPLICATION_NAME=tiku-local
|
||
DEFAULT_TENANT_SLUG=master
|
||
# 生产只列中央平台/运维的固定 HTTPS Origin,不能包含 *。
|
||
# 各租户 H5 Origin 从 active tenant_domains + active tenants 动态准入,不要把数百个租户域名展开到此列表。
|
||
CORS_ORIGIN=http://127.0.0.1:5173,http://localhost:5173
|
||
CORS_TENANT_DOMAINS_ENABLED=false
|
||
CORS_TENANT_DOMAIN_CACHE_TTL_MS=60000
|
||
CORS_TENANT_DOMAIN_NEGATIVE_CACHE_TTL_MS=10000
|
||
CORS_TENANT_DOMAIN_CACHE_MAX_ENTRIES=10000
|
||
MAX_JSON_BODY_BYTES=1048576
|
||
MAX_IMPORT_JSON_BODY_BYTES=10485760
|
||
|
||
# 认证迁移期配置:生产环境必须替换为高强度随机值,并配置 Supabase Auth JWT
|
||
AUTH_SMS_PROVIDER=mock
|
||
AUTH_CODE_PEPPER=replace_with_a_long_random_secret
|
||
AUTH_SESSION_SECRET=replace_with_another_long_random_secret
|
||
# 生产推荐使用 Supabase Auth JWKS:
|
||
# AUTH_JWT_ISSUER=https://<project-ref>.supabase.co/auth/v1
|
||
# AUTH_JWT_JWKS_URL=https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json
|
||
# 自托管或旧项目兼容才使用强随机 AUTH_JWT_SECRET;配置 JWKS 时必须同时配置 issuer。
|
||
AUTH_JWT_ISSUER=
|
||
AUTH_JWT_AUDIENCE=authenticated
|
||
AUTH_JWT_SECRET=development-jwt-secret-change-me
|
||
AUTH_JWT_JWKS_URL=
|
||
AUTH_CODE_TTL_SECONDS=300
|
||
AUTH_SMS_COOLDOWN_SECONDS=60
|
||
AUTH_SMS_TENANT_DAILY_LIMIT=20000
|
||
AUTH_SMS_PHONE_DAILY_LIMIT=10
|
||
# 校园/运营商 NAT 会共享 IP,IP 配额应宽于手机号/设备配额。
|
||
AUTH_SMS_IP_HOURLY_LIMIT=120
|
||
AUTH_SMS_DEVICE_HOURLY_LIMIT=10
|
||
AUTH_SESSION_TTL_SECONDS=604800
|
||
|
||
# 远程 Auth/JWKS 验收脚本配置。只在预生产/生产验收命令行临时设置真实 access token,
|
||
# 不要把真实 token 写入仓库、前端 runtime-config 或长期 .env。
|
||
# AUTH_SMOKE_API_BASE_URL=https://api.example.com
|
||
# AUTH_SMOKE_TENANT_ID=<tenant-uuid>
|
||
# AUTH_SMOKE_STUDENT_ACCESS_TOKEN=<real-supabase-access-token>
|
||
# AUTH_SMOKE_TENANT_ADMIN_ACCESS_TOKEN=<tenant-admin-supabase-access-token>
|
||
# AUTH_SMOKE_PLATFORM_ADMIN_ACCESS_TOKEN=<platform-admin-supabase-access-token>
|
||
# AUTH_SMOKE_WRONG_TENANT_ID=<another-tenant-uuid>
|
||
# AUTH_SMOKE_REQUIRE_ADMIN_TOKENS=true
|
||
|
||
# 安全目标默认关闭迁移期身份头。仅本地兼容旧测试/旧前端时可临时设为 true。
|
||
ALLOW_LEGACY_AUTH_HEADERS=false
|
||
ALLOW_PLATFORM_ADMIN_KEY=false
|
||
|
||
# 迁移期平台管理 API Key。生产环境必须使用平台管理员 JWT/服务端会话,不能开启 ALLOW_PLATFORM_ADMIN_KEY。
|
||
PLATFORM_ADMIN_API_KEY=replace_with_platform_admin_key
|
||
|
||
# Worker 配置:CRM webhook、支付补偿、导入复检等后台任务使用
|
||
WORKER_CRM_BATCH_SIZE=20
|
||
WORKER_CRM_POLL_INTERVAL_MS=10000
|
||
WORKER_CRM_MAX_ATTEMPTS=5
|
||
WORKER_CRM_BACKOFF_SECONDS=5,30,120,600,1800
|
||
WORKER_CRM_REQUEST_TIMEOUT_MS=10000
|
||
# 仅本地 fake webhook 测试允许 http://127.0.0.1;生产建议 false
|
||
WORKER_CRM_ALLOW_INSECURE_LOCALHOST=false
|
||
|
||
# Worker 配置:支付/退款补偿
|
||
WORKER_COMMERCE_BATCH_SIZE=20
|
||
WORKER_COMMERCE_MIN_AGE_SECONDS=300
|
||
WORKER_COMMERCE_REQUEST_TIMEOUT_MS=10000
|
||
|
||
# Worker 配置:平台 SaaS 订阅自动开票和逾期催缴。
|
||
# 自动开票只处理有明确 expires_at 且未开过非 void 订阅账单的订阅。
|
||
WORKER_PLATFORM_BILLING_BATCH_SIZE=50
|
||
WORKER_PLATFORM_BILLING_DAYS_AHEAD=45
|
||
WORKER_PLATFORM_BILLING_DUE_DAYS=15
|
||
WORKER_PLATFORM_BILLING_ID=platform-billing-1
|
||
# 平台 SaaS 用量超额自动开票默认处理上一个自然月,也可用 YYYY-MM 补跑指定月份。
|
||
WORKER_PLATFORM_USAGE_OVERAGE_BATCH_SIZE=100
|
||
WORKER_PLATFORM_USAGE_OVERAGE_MONTH=
|
||
WORKER_PLATFORM_USAGE_OVERAGE_DUE_DAYS=15
|
||
WORKER_PLATFORM_USAGE_OVERAGE_ID=platform-usage-overage-1
|
||
# 逾期催缴只标记 overdue、写 tenant_invoice_reminders 和审计,不自动停用租户。
|
||
WORKER_PLATFORM_DUNNING_BATCH_SIZE=100
|
||
WORKER_PLATFORM_DUNNING_ID=platform-dunning-1
|
||
# 逾期催缴外部通知会消费 tenant_invoice_reminders,并发送到 generic/钉钉/飞书/企微 webhook。
|
||
WORKER_PLATFORM_DUNNING_NOTIFICATION_BATCH_SIZE=50
|
||
WORKER_PLATFORM_DUNNING_NOTIFICATION_MAX_ATTEMPTS=5
|
||
WORKER_PLATFORM_DUNNING_NOTIFICATION_BACKOFF_SECONDS=10,60,300,900,1800
|
||
WORKER_PLATFORM_DUNNING_NOTIFICATION_REQUEST_TIMEOUT_MS=10000
|
||
# 仅本地 fake webhook 测试允许 http://127.0.0.1;生产必须 false
|
||
WORKER_PLATFORM_DUNNING_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
|
||
|
||
# Worker 配置:平台审计告警生成和外部通知。
|
||
WORKER_PLATFORM_AUDIT_ALERT_BATCH_SIZE=200
|
||
WORKER_PLATFORM_AUDIT_ALERT_LOOKBACK_DAYS=14
|
||
WORKER_PLATFORM_AUDIT_ALERT_ID=platform-audit-alerts-1
|
||
WORKER_PLATFORM_AUDIT_NOTIFICATION_BATCH_SIZE=50
|
||
WORKER_PLATFORM_AUDIT_NOTIFICATION_MAX_ATTEMPTS=5
|
||
WORKER_PLATFORM_AUDIT_NOTIFICATION_BACKOFF_SECONDS=10,60,300,900,1800
|
||
WORKER_PLATFORM_AUDIT_NOTIFICATION_REQUEST_TIMEOUT_MS=10000
|
||
# 仅本地 fake webhook 测试允许 http://127.0.0.1;生产必须 false
|
||
WORKER_PLATFORM_AUDIT_NOTIFICATION_ALLOW_INSECURE_LOCALHOST=false
|
||
|
||
# Worker 配置:内容资源复检。异常托管对象会被标记 failed 并从 active 退回 draft。
|
||
WORKER_ASSET_BATCH_SIZE=50
|
||
WORKER_ASSET_MIN_AGE_SECONDS=300
|
||
WORKER_ASSET_RECHECK_INTERVAL_SECONDS=86400
|
||
WORKER_ASSET_REQUEST_TIMEOUT_MS=10000
|
||
# 内容资源安全扫描。生产必须使用 metadata_rules,http,HTTP scanner 必须是 HTTPS 且 fail-open=false。
|
||
WORKER_ASSET_SECURITY_SCANNER=metadata_rules
|
||
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=
|
||
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=
|
||
WORKER_ASSET_SECURITY_SCAN_HTTP_TIMEOUT_MS=10000
|
||
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
|
||
|
||
# Worker 配置:大批量内容导入
|
||
WORKER_IMPORT_BATCH_SIZE=5
|
||
WORKER_IMPORT_ID=imports-1
|
||
WORKER_IMPORT_LEASE_SECONDS=120
|
||
WORKER_IMPORT_HEARTBEAT_INTERVAL_MS=30000
|
||
WORKER_IMPORT_BACKOFF_SECONDS=30,120,600,1800
|
||
|
||
# Worker 配置:公共题库自动同步。冲突会保留租户自改题目并等待后台处理。
|
||
WORKER_PUBLIC_BANK_SYNC_BATCH_SIZE=5
|
||
WORKER_PUBLIC_BANK_SYNC_COPY_LIMIT=1000
|
||
WORKER_PUBLIC_BANK_SYNC_ID=public-banks-1
|
||
WORKER_PUBLIC_BANK_SYNC_CLAIM_STALE_SECONDS=900
|
||
|
||
# Worker 配置:题库 PDF/Word 导出。生产建议使用真实对象存储 provider;local_dev 只用于本地开发。
|
||
WORKER_EXPORT_BATCH_SIZE=5
|
||
WORKER_EXPORT_ID=exports-1
|
||
WORKER_EXPORT_BACKOFF_SECONDS=30,120,600,1800
|
||
EXPORT_LOCAL_STORAGE_ROOT=.local-storage
|
||
# Windows 本地可填 C:\Windows\Fonts\NotoSansSC-VF.ttf;Linux 生产建议安装 Noto Sans CJK 并配置路径。
|
||
EXPORT_PDF_FONT_PATH=
|
||
|
||
# 对象存储配置:API 和 assets worker 共用
|
||
STORAGE_DEFAULT_PROVIDER=local_dev
|
||
STORAGE_DEFAULT_BUCKET=tenant-assets
|
||
STORAGE_PUBLIC_BASE_URL=
|
||
STORAGE_MAX_UPLOAD_BYTES=524288000
|
||
STORAGE_ALLOWED_MIME_PREFIXES=image/,video/,audio/
|
||
STORAGE_ALLOWED_MIME_TYPES=application/pdf,application/json,application/zip,application/x-zip-compressed,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/octet-stream,text/plain,text/markdown,text/csv
|
||
STORAGE_REQUIRE_TENANT_PREFIX=true
|
||
|
||
ALIYUN_OSS_REGION=
|
||
ALIYUN_OSS_ENDPOINT=
|
||
ALIYUN_OSS_ACCESS_KEY_ID=
|
||
ALIYUN_OSS_ACCESS_KEY_SECRET=
|
||
ALIYUN_OSS_STS_TOKEN=
|
||
ALIYUN_OSS_INTERNAL=false
|
||
|
||
TENCENT_COS_REGION=
|
||
TENCENT_COS_APP_ID=
|
||
TENCENT_COS_SECRET_ID=
|
||
TENCENT_COS_SECRET_KEY=
|
||
TENCENT_COS_SECURITY_TOKEN=
|
||
|
||
SUPABASE_STORAGE_URL=
|
||
SUPABASE_STORAGE_SERVICE_KEY=
|
||
|
||
# 国内短信/OAuth/支付的租户级密钥不建议放在 .env。
|
||
# 正式使用时请通过租户后台写入 app_private.tenant_secrets,并只在 config_public 暴露非敏感配置。
|