# 1688 Auto Procurement


## Supabase 原始文件上传

### 1. 安装依赖

项目使用 `pnpm` 管理 Node.js workspace。PDF、Word、图片等非 Excel 原始文件由 GLM-5.1 直接识别，不需要额外的 Python 文档转换环境。

```bash
# 要求 Node.js >= 20
corepack enable   # 如已安装 pnpm，可跳过
pnpm install
```
> 非 Excel 原始文件识别依赖支持图片/附件输入的模型。图片会先走 `DOCUMENT_OCR_LLM_PROVIDER` 输出 OCR 文本，再走 `DOCUMENT_EXTRACTION_LLM_PROVIDER` 提取结构化物料。DeepSeek 网页聊天窗支持传图不代表开放平台 API 支持；不要把文档阶段配置为官方 `https://api.deepseek.com`，除非已验证该端点支持图片/附件输入。

如需本地运行 Playwright 自动化，可安装 Chromium：

```bash
pnpm exec playwright install chromium
```

### 2. 配置环境变量

在项目根目录创建 .env.local：

```bash
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
VITE_SUPABASE_SOURCE_FILES_BUCKET=source-files
```

服务端自动化进程使用 `.env`。LLM 支持多 Provider 配置：先按阶段路由选择 Provider，再使用对应 Provider 的 Base URL/API Key；旧的 `LLM_BASE_URL` / `LLM_API_KEY` 只作为 legacy fallback。

```bash
# Legacy fallback
LLM_PROVIDER=
LLM_BASE_URL=
LLM_API_KEY=
LLM_MODEL=

# Provider 凭证
DEEPSEEK_LLM_BASE_URL=https://api.deepseek.com
DEEPSEEK_LLM_API_KEY=sk-...
GLM_LLM_BASE_URL=https://open.bigmodel.cn/api/paas/v4
GLM_LLM_API_KEY=sk-...
GEMINI_LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai
GEMINI_LLM_API_KEY=

# 文档 OCR 与文档物料提取。需使用支持图片/附件输入的 Provider。
DOCUMENT_OCR_LLM_PROVIDER=
DOCUMENT_OCR_LLM_MODEL=glm-5v-turbo
DOCUMENT_EXTRACTION_LLM_PROVIDER=
DOCUMENT_EXTRACTION_LLM_MODEL=glm-5.1

# 标准化与关键词语义
STANDARDIZATION_LLM_PROVIDER=deepseek
STANDARDIZATION_LLM_MODEL=deepseek-v4-pro
KEYWORD_SEMANTIC_LLM_PROVIDER=deepseek
KEYWORD_SEMANTIC_LLM_MODEL=deepseek-v4-flash

# 搜索视觉融合；SEARCH_VISION_MODEL 是历史 alias，仅用于兼容旧配置
SEARCH_VISION_LLM_PROVIDER=gemini
SEARCH_VISION_LLM_MODEL=gemini-2.5-pro-preview-p
SEARCH_VISION_MODEL=

# 固定 Batch 匹配与客服询价意图
FIXED_SEARCH_LLM_PROVIDER=glm
FIXED_SEARCH_LLM_MODEL=glm-4-plus
CHATBOT_INTENT_LLM_PROVIDER=deepseek
CHATBOT_INTENT_LLM_MODEL=deepseek-v4-flash
```

这些阶段模型会写入对应数据库审计字段和本地 artifact，例如 `standardized_results.llm_model`、`keyword_process.llm_model`、文档提取 response artifact 的 `model`、搜索视觉 debug artifact 的 `model_used`。Prompt Store 查询 scope 也使用各阶段最终模型，避免误用全局 `LLM_MODEL`。

如果新服务器上的 Node 进程访问 Supabase 时出现 TLS 错误（例如 UNABLE_TO_GET_ISSUER_CERT_LOCALLY），可以只对服务端脚本额外配置以下变量之一：

```bash
# 推荐：指定 CA 证书文件
SUPABASE_TLS_CA_CERT_PATH=/etc/ssl/certs/your-ca-chain.pem

# 或者：直接提供 PEM 文本 / base64
SUPABASE_TLS_CA_CERT="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
SUPABASE_TLS_CA_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...

# 仅限应急排障，不建议长期使用
SUPABASE_TLS_INSECURE_SKIP_VERIFY=1
```

优先方案仍然是修复服务器系统证书链；以上配置只会作用于 Node 侧 Supabase 客户端，不影响浏览器端。

### 3. 初始化 Supabase

```bash
# 把 supabase/migrations/ 下的全部脚本应用到目标项目
supabase db push
```

这会创建主业务库所需的全部 schema（`source_files` 元数据表、`source-files` bucket 策略、各业务表等）。如需独立的 prompt 库，再单独跑：

```bash
node --import tsx scripts/seed-prompt-store.ts
# 该脚本会用 supabase/sql/prompt-store-schema.sql 初始化 PROMPT_SUPABASE_URL 指向的库
```

> 关于 `supabase/migrations/` 中的 `*_remote_baseline_placeholder.sql` 文件，请参阅
> [supabase/migrations/README.md](supabase/migrations/README.md)。

### 4. 使用方式

启动项目后，进入侧边栏的“原始文件上传”页面：

- 填写 batch ID
- 选择一个或多个原始文件
- 点击“开始上传”
- 上传成功后，可在下方列表直接看到记录并下载

### 5. 当前实现范围

当前实现仅覆盖：
- 原始文件上传到 Supabase Storage
- 文件元数据写入 source_files 表
- 按批次查询已上传文件
- 生成下载 signed URL
- 从非 Excel 原始文件直接提取 materials 草稿

尚未覆盖：
- 用户鉴权
- 细粒度按用户隔离 bucket 访问

### 6. 在线标准化 size 修改 最大 50
STANDARDIZE_ONLINE_BATCH_SIZE 
