INOVIT 经销商门户
独立开发,完整替换遗留 C#/.NET 4.8 经销商门户 —— 新旧系统共用同一生产数据库,处理实际订单,零停机、零 schema 变更。
- 角色
- 独立开发 · 从架构到部署
- 年份
- 2026
- 类型
- B2B 电商 · ERP
- 状态
- 运行中

替换遗留 .NET ERP 的 B2B 电商平台 —— 全程不停机。
新 Django API 与旧 .NET 系统并行读写同一批 SQL Server 表,处理实际经销商订单。49 个 API 端点、一套代码背后的四个区域数据库、跨仓库 OpenAPI 类型生成,以及一次没有改动生产 schema 任何一列的迁移。
我的角色
全部。架构设计、前端、后端、数据库映射、CI/CD 流水线、Docker 基础设施、监控和生产部署。一人从零重写。
旧 .NET ERP 每天处理实际订单 —— 不能停机,数据库结构不能动。我要在旧系统毫无感知的情况下,构建一个同时读写相同数据表的新系统。
一览
技术栈
- 前端
- React · TypeScript · Vite · Ant Design
- 后端
- Django · DRF · Python · Gunicorn
- 数据库
- SQL Server 2025 — 4 个区域数据库,42 个通过 mssql-django 映射的非托管模型
- 基础设施
- AWS Lightsail · Docker · Caddy · GitHub Actions · S3 · Lambda · SES (SMTP)
- 测试
- Vitest · Playwright · pytest · CI 中的 OpenAPI 契约漂移检查
两套系统,一个数据库
新 Django API 和旧 .NET ERP 同时读写相同的 SQL Server 表。Django 用 managed = False 映射 42 张遗留表 —— ORM 正常使用,但 Django 不会尝试创建、修改或迁移这些表。另外 2 张新 managed 表用于 ERP 不涉及的资产分类功能。两套系统在互不感知的情况下并行处理订单。
新系统
- React SPA
- Caddy
- Django API
共享基础设施
- SQL Server 2025
- 遗留 .NET ERP
支撑服务
- S3 + CDN
- 监控
一套代码,四个数据库
澳洲、英国、美国的经销商各自有独立的 SQL Server 数据库,包含区域定价、库存和订单。没有为每个区域单独部署后端,而是让一个 Django 实例根据 JWT 中的 region 字段,通过自定义中间件 + 数据库路由,将每个 ORM 查询路由到对应数据库。
经销商登录
JWT 携带 region 字段
中间件
每次请求提取 region
数据库路由
路由 ORM 到正确数据库
AU / UK / US / Demo
每区域独立数据
权衡
OpenAPI 作为契约边界
三个仓库,一个人 —— 后端 API 变了,前端必须立刻报错。后端 CI 生成 OpenAPI 规范,自动同步到前端仓库并生成 TypeScript 类型。契约偏差是构建失败,而非经销商发现的运行时 bug。
跨 AWS 实例的认证缓存
SQL Server 在另一台 AWS 实例上,每次认证查询都要跨网络。API 服务器上的 5 分钟 LocMemCache 消除了重复请求的网络往返 —— 足够短,ERP 侧的用户变更(禁用账号、修改权限)几分钟内仍能生效。
2 MB 打包预算
2 MB 的 CI 硬限制在合并前拦截体积退化 —— 不依赖人工 review 来发现臃肿的引入。
构建时架构约束
9 个功能模块很容易变成依赖蜘蛛网。ESLint 规则编码了依赖方向(types → services → hooks → features),禁止跨模块引用。架构违规直接构建失败 —— 不会以"以后再改"的 TODO 存活。


