diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c3f9185 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,53 @@ +# 版本控制 +.git +.github + +# 构建产物(builder 阶段重新生成) +.next +node_modules + +# 测试 +coverage +tests +vitest.config.ts +docker-compose.test.yml + +# 运行时数据 +logs +data +certificates +backups +uploads + +# IDE 和 AI 工具 +.vscode +.cursor +.claude +.gemini +.agent +.shared +.artifacts + +# 数据库文件 +*.db +*.db-journal +prisma/data + +# 临时文件 +.DS_Store +*.tsbuildinfo +.tmp-old-snapshot-* + +# 环境变量 +.env +.env.local +.env.*.local +.env.test + +# 文档和杂项 +*.md +*.py +debug-request.json +AGENTS.md +docs +agent diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c7aacf5 --- /dev/null +++ b/.env.example @@ -0,0 +1,80 @@ +# ==================== 数据库 ==================== +# 本地开发模式:docker-compose.yml 将 MySQL 映射到宿主机的 13306 端口 +# Docker 容器模式:docker-compose.yml 会自动覆盖此配置 +DATABASE_URL="mysql://root:waoowaoo123@localhost:13306/waoowaoo" + +# ==================== 存储 ==================== +# minio: S3 兼容对象存储(默认) +# local: 本地文件存储(仅开发调试) +# cos: 预留 provider(当前版本未实现) +STORAGE_TYPE=minio + +# MinIO / S3 兼容存储配置 +# 本地开发模式:docker-compose.yml 将 MinIO 映射到宿主机的 19000 端口 +MINIO_ENDPOINT=http://localhost:19000 +MINIO_REGION=us-east-1 +MINIO_BUCKET=waoowaoo +MINIO_ACCESS_KEY=minioadmin +MINIO_SECRET_KEY=minioadmin +MINIO_FORCE_PATH_STYLE=true + +# COS 配置(预留) +# COS_SECRET_ID= +# COS_SECRET_KEY= +# COS_BUCKET= +# COS_REGION= + +# ==================== 认证 ==================== +# 本地开发模式(方式三):使用 http://localhost:3000 +# Docker 容器模式(方式一、二):由 docker-compose.yml 注入为 http://localhost:13000 +NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_SECRET=please-change-this-to-a-random-string + +# ==================== 应用内部自调用地址 ==================== +# 仅用于服务端内部 fetch 本应用 API / 文件。 +# 本地开发模式通常与 NEXTAUTH_URL 一致;Docker 模式由 docker-compose.yml 注入为 http://127.0.0.1:3000 +INTERNAL_APP_URL=http://127.0.0.1:3000 + +# ==================== 内部密钥 ==================== +CRON_SECRET=please-change-this-cron-secret +INTERNAL_TASK_TOKEN=please-change-this-task-token +API_ENCRYPTION_KEY=waoowaoo-opensource-fixed-key-2026 + +# ==================== Redis ==================== +# 本地开发模式:docker-compose.yml 将 Redis 映射到宿主机的 16379 端口 +# Docker 容器模式:docker-compose.yml 会自动覆盖此配置 +REDIS_HOST=127.0.0.1 +REDIS_PORT=16379 +REDIS_USERNAME= +REDIS_PASSWORD= +REDIS_TLS= + +# ==================== Worker 配置 ==================== +WATCHDOG_INTERVAL_MS=30000 +TASK_HEARTBEAT_TIMEOUT_MS=90000 +QUEUE_CONCURRENCY_IMAGE=50 +QUEUE_CONCURRENCY_VIDEO=50 +QUEUE_CONCURRENCY_VOICE=20 +QUEUE_CONCURRENCY_TEXT=50 + +# ==================== Bull Board (任务管理面板) ==================== +BULL_BOARD_HOST=0.0.0.0 +BULL_BOARD_PORT=3010 +BULL_BOARD_BASE_PATH=/admin/queues +BULL_BOARD_USER= +BULL_BOARD_PASSWORD= + +# ==================== 日志 ==================== +LOG_UNIFIED_ENABLED=true +LOG_LEVEL=ERROR +LOG_FORMAT=json +LOG_DEBUG_ENABLED=false +LOG_AUDIT_ENABLED=true +LOG_SERVICE=waoowaoo +LOG_REDACT_KEYS=password,token,apiKey,apikey,authorization,cookie,secret,access_token,refresh_token + +# ==================== 计费 ==================== +BILLING_MODE=OFF + +# ==================== 流式输出 ==================== +LLM_STREAM_EPHEMERAL_ENABLED=true diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..68cf89e --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": "next/core-web-vitals", + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@next/next/no-img-element": "warn", + "react-hooks/exhaustive-deps": "warn" + } +} + diff --git a/.gitignore b/.gitignore index a6693ea..8e89272 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,90 @@ -node_modules/ -logs/ \ No newline at end of file +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# vercel +.vercel + +# IDE and AI tools +.vscode/ +.idea/ +.claude/ +.cursor/ +.gemini/ +.artifacts/ +.agent/ +.shared/ + +# typescript +*.tsbuildinfo +next-env.d.ts + +/src/generated/prisma + +# logs +/logs +*.log + +# environment variables +.env +.env.local +.env.test +.env.*.local +docker-logs/ + +# database +*.db +*.db-journal +prisma/data/ + +# uploads (user data) +uploads/ +/data/ + +certificates + +# local temporary snapshots for old-version verification +.tmp-old-snapshot-*/ + +# temporary files +tmp/ + +# internal AI agent config (not for public) +AGENTS.md +agent/ + +# internal docs (not for public) +docs/ + +# GitHub CI workflows (internal) +# .github/ — 只保留 workflows,忽略其他 +.github/* +!.github/workflows/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..7d41c73 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.14.0 diff --git a/.tmp_check_task.ts b/.tmp_check_task.ts new file mode 100644 index 0000000..92924a3 --- /dev/null +++ b/.tmp_check_task.ts @@ -0,0 +1,40 @@ +import { prisma } from '@/lib/prisma' + +const id = 'a3cbc6d3-8720-4584-addd-e2bc4ace7759' + +async function main() { + const t = await prisma.task.findUnique({ + where: { id }, + select: { + id: true, + type: true, + userId: true, + projectId: true, + payload: true, + errorMessage: true, + createdAt: true, + }, + }) + console.log(JSON.stringify(t, null, 2)) + + if (!t) return + + const pref = await prisma.userPreference.findUnique({ + where: { userId: t.userId }, + select: { + analysisModel: true, + customProviders: true, + customModels: true, + }, + }) + console.log('userPreference', JSON.stringify(pref, null, 2)) +} + +main() + .catch((err) => { + console.error(err) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + })