单教练卖课包、排课、记课时的系统。卖了几节、上了几节、还剩几节,教练和学员看的是同一本账。
单教练卖的是课包次卡(一次买 10 节、20 节),不是按月订阅。麻烦全在中间那些不确定的事上:
| 学员爽约 | 教练已经到场、场地已经占用 —— 这一节要扣,否则爽约没有成本。 |
| 教练有事取消 | 责任在教练 —— 不扣。 |
| 已经扣了又要退回 | 学员受伤请假、下雨换场、教练记错 —— 能退,但必须写明理由,否则这本账随手就能抹平,学员对不上就不信了。 |
| 学员想自己看余额 | 又不能给他登录账号 —— 用不可枚举的私密链接,只读。 |
| 后端 | Python + FastAPI + SQLite,服务端渲染(Jinja2),没有前端框架。单教练的量级,一个进程一个文件足够,省掉整条前后端分离的复杂度。 |
| 余额 | 不存字段,实时算:余额 = 课包总数 − 该包下所有「扣次状态」的课次数。存字段就会有「改了课次没改余额」的不一致,而这种不一致在对账时才会暴露。 |
| 状态机 | 四态 已排课 / 已上课 / 未到 / 已取消;只有前两类里的「已上课、未到」扣次。从扣次态改到取消归类为 concession,强制填理由码并写审计。 |
| 学员端 | 每位学员一枚长随机 token,独立路由只读渲染,与教练端共用同一套领域函数 —— 两端看到的数不可能对不上。 |
| 双端 | 网页端 + 微信小程序,同一个后端。教练在健身房用手机排课,学员在微信里看余额。 |