注册邮箱域名白名单策略上线,后台大数据场景性能大幅优化。 - 注册邮箱域名白名单:支持管理员配置允许注册的邮箱域名策略 - Keys 页面表单筛选:用户 /keys 页面支持按条件筛选 API Key - Settings 页面分 Tab 拆分:管理后台设置页面按功能模块分 Tab 展示 - 后台大数据场景加载性能优化:仪表盘/用户/账号/Ops 页面大数据集加载显著提速 - Usage 大表分页优化:默认避免全量 COUNT(*),大幅降低分页查询耗时 - 消除重复的 normalizeAccountIDList,补充新增组件的单元测试 - 清理无用文件和过时文档,精简项目结构 - EmailVerifyView 硬编码英文字符串替换为 i18n 调用 - 修复 Anthropic 平台无限流重置时间的 429 误标记账号限流问题 - 修复自定义菜单页面管理员视角菜单不生效问题 - 修复 Ops 错误详情弹窗未展示真实上游 payload 的问题 - 修复充值/订阅菜单 icon 显示问题 # Conflicts: # .gitignore # backend/cmd/server/VERSION # backend/ent/group.go # backend/ent/runtime/runtime.go # backend/ent/schema/group.go # backend/go.sum # backend/internal/handler/admin/account_handler.go # backend/internal/handler/admin/dashboard_handler.go # backend/internal/pkg/usagestats/usage_log_types.go # backend/internal/repository/group_repo.go # backend/internal/repository/usage_log_repo.go # backend/internal/server/middleware/security_headers.go # backend/internal/server/router.go # backend/internal/service/account_usage_service.go # backend/internal/service/admin_service_bulk_update_test.go # backend/internal/service/dashboard_service.go # backend/internal/service/gateway_service.go # frontend/src/api/admin/dashboard.ts # frontend/src/components/account/BulkEditAccountModal.vue # frontend/src/components/charts/GroupDistributionChart.vue # frontend/src/components/layout/AppSidebar.vue # frontend/src/i18n/locales/en.ts # frontend/src/i18n/locales/zh.ts # frontend/src/views/admin/GroupsView.vue # frontend/src/views/admin/SettingsView.vue # frontend/src/views/admin/UsageView.vue # frontend/src/views/user/PurchaseSubscriptionView.vue
Database Migrations
Overview
This directory contains SQL migration files for database schema changes. The migration system uses SHA256 checksums to ensure migration immutability and consistency across environments.
Migration File Naming
Format: NNN_description.sql
NNN: Sequential number (e.g., 001, 002, 003)description: Brief description in snake_case
Example: 017_add_gemini_tier_id.sql
_notx.sql 命名与执行语义(并发索引专用)
当迁移包含 CREATE INDEX CONCURRENTLY 或 DROP INDEX CONCURRENTLY 时,必须使用 _notx.sql 后缀,例如:
062_add_accounts_priority_indexes_notx.sql063_drop_legacy_indexes_notx.sql
运行规则:
*.sql(不带_notx)按事务执行。*_notx.sql按非事务执行,不会包裹在BEGIN/COMMIT中。*_notx.sql仅允许并发索引语句,不允许混入事务控制语句或其他 DDL/DML。
幂等要求(必须):
- 创建索引:
CREATE INDEX CONCURRENTLY IF NOT EXISTS ... - 删除索引:
DROP INDEX CONCURRENTLY IF EXISTS ...
这样可以保证灾备重放、重复执行时不会因对象已存在/不存在而失败。
Migration File Structure
-- +goose Up
-- +goose StatementBegin
-- Your forward migration SQL here
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
-- Your rollback migration SQL here
-- +goose StatementEnd
Important Rules
⚠️ Immutability Principle
Once a migration is applied to ANY environment (dev, staging, production), it MUST NOT be modified.
Why?
- Each migration has a SHA256 checksum stored in the
schema_migrationstable - Modifying an applied migration causes checksum mismatch errors
- Different environments would have inconsistent database states
- Breaks audit trail and reproducibility
✅ Correct Workflow
-
Create new migration
# Create new file with next sequential number touch migrations/018_your_change.sql -
Write Up and Down migrations
- Up: Apply the change
- Down: Revert the change (should be symmetric with Up)
-
Test locally
# Apply migration make migrate-up # Test rollback make migrate-down -
Commit and deploy
git add migrations/018_your_change.sql git commit -m "feat(db): add your change"
❌ What NOT to Do
- ❌ Modify an already-applied migration file
- ❌ Delete migration files
- ❌ Change migration file names
- ❌ Reorder migration numbers
🔧 If You Accidentally Modified an Applied Migration
Error message:
migration 017_add_gemini_tier_id.sql checksum mismatch (db=abc123... file=def456...)
Solution:
# 1. Find the original version
git log --oneline -- migrations/017_add_gemini_tier_id.sql
# 2. Revert to the commit when it was first applied
git checkout <commit-hash> -- migrations/017_add_gemini_tier_id.sql
# 3. Create a NEW migration for your changes
touch migrations/018_your_new_change.sql
Migration System Details
- Checksum Algorithm: SHA256 of trimmed file content
- Tracking Table:
schema_migrations(filename, checksum, applied_at) - Runner:
internal/repository/migrations_runner.go - Auto-run: Migrations run automatically on service startup
Best Practices
-
Keep migrations small and focused
- One logical change per migration
- Easier to review and rollback
-
Write reversible migrations
- Always provide a working Down migration
- Test rollback before committing
-
Use transactions
- Wrap DDL statements in transactions when possible
- Ensures atomicity
-
Add comments
- Explain WHY the change is needed
- Document any special considerations
-
Test in development first
- Apply migration locally
- Verify data integrity
- Test rollback
Example Migration
-- +goose Up
-- +goose StatementBegin
-- Add tier_id field to Gemini OAuth accounts for quota tracking
UPDATE accounts
SET credentials = jsonb_set(
credentials,
'{tier_id}',
'"LEGACY"',
true
)
WHERE platform = 'gemini'
AND type = 'oauth'
AND credentials->>'tier_id' IS NULL;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
-- Remove tier_id field
UPDATE accounts
SET credentials = credentials - 'tier_id'
WHERE platform = 'gemini'
AND type = 'oauth'
AND credentials->>'tier_id' = 'LEGACY';
-- +goose StatementEnd
Troubleshooting
Checksum Mismatch
See "If You Accidentally Modified an Applied Migration" above.
Migration Failed
# Check migration status
psql -d sub2api -c "SELECT * FROM schema_migrations ORDER BY applied_at DESC;"
# Manually rollback if needed (use with caution)
# Better to fix the migration and create a new one
Need to Skip a Migration (Emergency Only)
-- DANGEROUS: Only use in development or with extreme caution
INSERT INTO schema_migrations (filename, checksum, applied_at)
VALUES ('NNN_migration.sql', 'calculated_checksum', NOW());
References
- Migration runner:
internal/repository/migrations_runner.go - Goose syntax: https://github.com/pressly/goose
- PostgreSQL docs: https://www.postgresql.org/docs/