01关于这个站
一个很朴素的个人技术笔记站。
这里只放我自己折腾技术的过程记录:做过的项目、架构怎么想的、踩过哪些坑、哪些还没做完。不写公司的事,也不放任何业务数据——文中出现的数字都是结构性的(表数、页面数、接口数),没有业务量。
本页是静态内容,不收集访问者信息、不设登录、不提供任何业务系统入口。
02我写的一个质量管理系统
起因是工作里天天跟质量记录打交道,市面上的系统要么太重、要么太贵,索性自己写一个够用的。
它从一个很小的需求长起来——最开始只是想有个地方把客诉工单记下来、能查、能追状态。后来陆续加上了阶段评审、纠正预防、生产质量、变更、文件、实验室、供应商这些模块,现在到了 v2.0.0,单机部署,我自己每天在用。
这篇笔记把它摊开讲清楚:架构长什么样、模块怎么分、踩了哪些坑、哪些还没做完。
03在线演示
这套系统我放了一个只读的在线演示,欢迎技术交流。
演示环境里所有数据都是虚拟生成的,仅供技术测试与交流。访客可以自由浏览全部页面,但不能修改任何数据(写操作在服务端被拦截)。
04技术栈与总体架构
原则很朴素:单机 SQLite 扛得住的量,就不引入分布式复杂度。
| 层 | 选型 | 说明 |
|---|---|---|
| 后端 | Python + FastAPI | 单入口装配十余个业务 router,按域拆分 |
| 数据 | SQLite(单文件库) | 一百余张表,数据访问集中在一个数据层模块 |
| 鉴权 | 自研中间件 | 统一拦认证,并按模块做权限判定;前端只做可见性 |
| 前端 | 原生 HTML / CSS / JS | 无构建步骤,改完刷新即可 |
| 守卫 | 启动时路由自检 | 启动即校验路由表,防"改了不生效" |
分层逻辑:router 只做参数校验与响应组装,业务逻辑和 SQL 收在数据层,中间件统一拦鉴权。没有微服务、没有 ORM。
05部署拓扑
浏览器 │ HTTPS ▼ nginx ── TLS 终结 / 反向代理 / 静态资源 │ HTTP (回环) ▼ uvicorn 127.0.0.1:8765 ◄── systemd 托管,开机自启 │ ▼ SQLite 单文件库(备份 = 拷文件)
- 应用只监听回环地址,公网入口只有 nginx 一层。
- 备份:每日一次全量 + 每周一次二次全量,并保留手动快照目录。
- 附带几个自动化任务:基础数据定期同步、数据完整性自检、到期提醒。
06模块地图(10 个)
按业务域切分,每个域一张前缀命名,互不干扰。
首页仪表盘
全局指标汇总、待办入口
KPI 汇总客诉工单
登记 · 分级 · 处理 · 关闭,编号自动生成
工单流转新产品阶段评审
项目分阶段门径,阶段任务 + 证据 + 评审计时
门径管理纠正与预防
问题 → 根因 → 措施 → 有效性验证闭环
闭环管理生产质量
批次各环节良率、巡检、异常单
过程数据变更管理
变更分级,不同级别走不同评审链,前后可追溯
评审链受控文件
文件登记 · 版本序列 · 唯一现行版 · 分发回收
版本控制实验室信息
样品 → 任务 → 结果 → 审核,四段流转
全库最大域供应商 / 来料质量
合格方名录、来料问题、审核记录
外部协同基础信息与组织
字典集中维护、岗位与权限矩阵
主数据另有认证、审计、法规、培训、证件等支撑表若干。
07数据模型要点
- 按域前缀分表:单库多域,跨模块查询不用跨服务 join。
- 软删除:约三成表带删除标记。质量记录的删除本身就是风险动作,宁可留痕不物理删——代价是每条查询都得记得带过滤条件(这个坑踩过)。
- 时间戳:约六成表统一由数据层填
created_at/updated_at。 - 审计轨迹:不做通用 binlog,而是各域自建 trail 表,记录"谁在什么时间把哪个字段从 A 改成 B"。取舍:粒度按需定制、查询顺手;缺点是每加一个模块就要多写一张,没做到全局统一。
- 关系:用显式
xxx_id维护,未强制外键约束——改表结构时省事,但孤儿数据要靠自检任务兜底。
08踩过的坑
这些都已经改掉了。写下来是因为每条都值得记住。
1 · 写操作忘了提交,会静默丢数据
有一批写操作只执行了语句、没有提交,接口返回成功、数据却没落盘,数据库还不报错——只有读的时候才发现没了。后来把提交点统一收口到数据层。教训:持久化不能靠"每个调用点都记得"。
2 · 权限只做在前端,等于没做
早期把权限矩阵渲染得很漂亮,但判定只发生在前端——前端能藏起来的东西,后端并不拦。后来把认证与授权判定都收口到中间件层,按模块判权限,前端保留一层可见性提示。教训:鉴权必须在中间件,散落在各个接口里的判断等于没有;前端只负责"好看",不负责"安全"。
3 · 同名双实现互相遮蔽:改了没反应
同一个功能早期有过两份实现,路由注册顺序让旧的那份一路被优先命中,新代码根本没被执行。排查很久才发现"改的文件压根没跑"。后来加了启动时的路由自检:有冲突就直接打印出来。教训:能自动检出的问题,别留给人的记忆力。
4 · 软删除 + 忘带过滤 = 幽灵数据
删除路径收口之前,已删除的记录在部分列表接口照样返回,界面上表现为"删了又出现"。教训:凡软删除,查询就必须走统一的过滤构建器,不能让每个接口各写一遍 where。
5 · 开关型配置,两种状态都要冒烟
一个默认关闭的开关,关着的时候一切正常;打开之后才发现放行清单有遗漏,连锁让登录页拿不到静态资源——差点把自己锁在门外。教训:开与关都是"生产状态",两种都要过一遍冒烟。
09还没做完的部分
- 权限粒度:目前判到"模块级",还没有细化到"同一模块内不同角色的操作差异"。
- 变更管理模块:需求文档里明确标着待完善,列表与状态流转还有几处逻辑洞。
- 实验室模块前端滞后:后端表与接口都在了,页面只覆盖了样品和结果两段,审核流还没接完。
- 审计轨迹该统一:各域自建 trail 表的方式该收敛成一个统一的变更日志机制,否则每加模块都重复劳动。
- 数据治理:有空表没清理;测试数据与演示数据该分离,最好有个独立的演练环境。