Prmbr/docs/deployment-fix.md
2025-08-05 23:42:48 +08:00

148 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 部署修复说明
## 问题解决
已修复在推送到现有环境时遇到的外键约束错误:
```
Error: insert or update on table "users" violates foreign key constraint "users_subscriptionPlanId_fkey"
```
## 解决方案
通过修改种子脚本 (`prisma/seed.ts`),确保在数据库推送时:
1. **创建必需的套餐**:使用 `upsert` 确保 'free' 和 'pro' 套餐存在
2. **修复用户数据**:自动修复无效的套餐引用
3. **验证数据完整性**:确保所有用户都有有效的套餐关联
## 使用方法
现在可以直接使用现有命令进行部署:
```bash
npm run db:push
```
这个命令会:
1. 推送数据库架构 (`prisma db push`)
2. 运行种子脚本 (`npm run db:seed`)
3. 自动处理数据修复
## 种子脚本改进
### 主要变更
1. **使用 upsert 而不是 create**
```typescript
// 之前:如果套餐存在就跳过
if (existingPlans > 0) return
// 现在:确保必需套餐存在
await prisma.subscriptionPlan.upsert({
where: { id: 'free' },
update: { name: 'free', isActive: true },
create: { /* 完整套餐数据 */ }
})
```
2. **智能用户数据修复**
```typescript
// 检查所有用户的套餐引用
const validPlanIds = ['free', 'pro']
const usersToUpdate = users.filter(user => {
const hasValidSubscribePlan = validPlanIds.includes(user.subscribePlan)
const hasValidSubscriptionPlanId = validPlanIds.includes(user.subscriptionPlanId)
return !hasValidSubscribePlan || !hasValidSubscriptionPlanId
})
// 修复无效引用
for (const user of usersToUpdate) {
await prisma.user.update({
where: { id: user.id },
data: {
subscribePlan: validPlanIds.includes(user.subscribePlan) ? user.subscribePlan : 'free',
subscriptionPlanId: validPlanIds.includes(user.subscribePlan) ? user.subscribePlan : 'free'
}
})
}
```
### 执行流程
1. **创建/更新套餐**:确保 'free' 和 'pro' 套餐存在
2. **检查用户数据**:找出有无效套餐引用的用户
3. **修复用户数据**:将无效引用改为 'free'
4. **验证结果**:确认所有数据都是一致的
## 测试验证
种子脚本运行结果:
```
🌱 Starting database seeding...
📦 Ensuring essential subscription plans exist...
✅ Created subscription plan: Free Plan
✅ Created subscription plan: Pro Plan
👥 Updating existing users...
👥 No users need subscription plan updates
📊 Seeding completed:
• 2 subscription plans created
• 2 users have valid plan associations
🎉 Database seeding finished successfully!
```
## 部署到现有环境
现在可以安全地部署到任何现有环境:
1. **本地测试**
```bash
npm run db:push
npm run build
```
2. **生产部署**
```bash
npm run db:push
npm start
```
## 优势
1. **无需额外脚本**:使用现有的 `npm run db:push` 命令
2. **自动修复**:种子脚本自动处理数据不一致问题
3. **向后兼容**:不会破坏现有数据
4. **幂等操作**:可以重复运行而不会出错
## 注意事项
1. **Stripe 配置**:部署后需要设置 Pro 套餐的 Stripe 价格 ID
```sql
UPDATE subscription_plans
SET "stripePriceId" = 'price_your_stripe_price_id'
WHERE name = 'pro';
```
2. **数据验证**:部署后验证定价页面和订阅功能
3. **备份建议**:在生产环境部署前建议备份数据库
## 故障排除
如果仍然遇到问题:
1. **检查套餐**
```sql
SELECT id, name, "isActive" FROM subscription_plans;
```
2. **检查用户**
```sql
SELECT "subscribePlan", COUNT(*) FROM users GROUP BY "subscribePlan";
```
3. **手动修复**
```sql
UPDATE users SET "subscribePlan" = 'free'
WHERE "subscribePlan" NOT IN ('free', 'pro');
```