时间:2026-09-23
来源:gpt-6-astra(medium 档)独立评审,由 Bob 对照真实代码去伪存真。
背景:老板定调 B端 = 通用底座 + 按行业定制的软件管理平台;原则 = 不大而全 / 不按业态锁死功能(A端人工开通)/ 重点先做住宿(房态)。
第1节 · 底座+行业包架构(针对"A端人工开通")
feature_packs(包目录)+ membership_feature_packs(商户开通关系)两表,功能包落在商户/会员维度而非 business_type。GET /me/feature-packs);前端路由 + 后端接口双重校验(防越权直调)。第2节 · 住宿包(房态)MVP 范围
第3节 · item_type 标记标准统一
accommodation_room / accommodation_package / dining_item / retail_item / scenic_ticket / experience_session / transport_vehicle / generic_service。lodging_display 是否全是房型、有无混入套餐/展示类。第4节 · 执行者遗漏的关键风险
| gpt6 假设/盲区 | 真实代码核实结果 | 结论 |
|---|---|---|
存在 membership 表,开通关系挂 membership_id | 后端无 membership 表;身份走 merchant_staff(user_id→merchant_id+role)+ merchants。前端变量名 memberships[0] 只是前端叫法 | 修正:新表应挂 merchant_id 维度(如 merchant_feature_packs),对齐真实结构 |
room_calendar 需加 version 防并发 | 表字段:id, merchant_id, room_type_id, biz_date, total, sold, status, updated_at——无 version 字段;UPSERT 按 (merchant_id,room_type_id,biz_date) 会直接覆盖 | 属实:并发覆盖是真实风险,需加 version 或靠 updated_at 条件更新 |
| 担心商户串数据(未做隔离) | rooms.py 已 mid = staff["merchant_id"] 只查本商户 + 校验 role∈(owner/manager/operator) | 部分成立:归属隔离已做;但角色仅粗粒度,未细分 read/edit_quantity/change_status |
| item_type 不匹配(后端认 room/stay/accommodation) | rooms.py:27 硬编码 item_type IN ('room','stay','accommodation');prod 真实住宿标记是 lodging_display、餐饮 dining | 实证成立:直接接会拉错房型,必须先统一标记 |
merchant_staff/merchants 完整字段 + 角色模型(老板/店长/收银员如何落库),再定开通关系表。accommodation_room 标准,rooms.py 改过滤条件 + 抽样核验 lodging_display,分批回填。accommodation_room 这套枚举(影响 A端录入、商户自录、C端展示三处)?用户明确纠偏(回应上轮"老板/店长/收银员"三档提案):
tenant_feature_entitlements(挂 merchant 维度)→ B端拉本租户已授权 feature_key 列表 → 路由 + 接口双校验显隐。命名严格区别于 packages(商品套餐),详见下方术语对齐。为避免"功能包"与系统已有"套餐(packages)"混淆、以及"开通"归属不清,按多租户 SaaS 行业标准重定义:
| 我们的语境 | 行业标准术语 | 含义 |
|---|---|---|
| 商户 | 租户 (Tenant) | 一个入驻商户 = 一个租户实例 |
| 功能包 | 功能/能力 (Feature / Capability) 或 应用 (App/Module) | 可独立开通的商户经营能力(如房态、进销存) |
| 开通功能包 | 租户功能授权 (Tenant Feature Entitlement / Provisioning) | 平台为租户启用某能力 |
| A端 | 平台运营后台 / 控制面 (Control Plane) | 管租户 + 授权 |
| B端 | 商户工作台 / 数据面 (Tenant Console / Data Plane) | 租户使用已授权能力 |
关键边界(消除歧义):
packages 表是面向消费者的商品套餐(如「测试套餐001」),与商户功能授权无关;命名、存储、接口三者隔离,禁止用"包/套餐"一词指代功能授权。数据模型(标准):
feature_catalog(功能目录:feature_key, name, industry, desc)—— 业内 Feature Catalog / App Directorytenant_feature_entitlements(授权关系:merchant_id, feature_key, status, granted_by, granted_at)—— 业内 Entitlement Record,挂 merchant 维度(已核实后端无 membership 表)GET /me/features 返回本租户已开通 feature_key 列表 → 路由 + 接口双校验merchant_staff.role 取值 owner(32)/manager(1)/promoter(3) → 统一收口为 owner + staff 两类(manager/promoter 当 staff 处理;operator 是代码幻觉,库里不存在,清掉)。require_role(merchant_id, allow=[...]) 只需区分 owner / staff 两档(敏感操作如成员管理、收款配置仅 allow=[owner];其余经营操作 allow=[owner,staff])。packages(商品套餐) 严格隔离。详见上方术语对齐。service_items.item_type 现状混乱(prod 实测 14 种:meal20/hotel5/lodging_display2/room2/dining1/restaurant5/vehicle2/transport2/guide1/experience1/attraction1/scenic5/retail5/other5)。按国家文旅"旅游六要素"(食·住·行·游·购·娱)这一行业标准 taxonomy 收敛为受控词表,覆盖全部历史值:
| 规范值(canonical) | 中文 | 六要素 | 兼容读取(legacy prod 值) | 说明 |
|---|---|---|---|---|
accommodation | 住宿 | 住 | hotel, lodging_display, room, stay | 房型/房间/民宿/酒店;rooms.py 已认 accommodation/room/stay |
dining | 餐饮 | 食 | meal, dining, restaurant, food | 餐/菜/饮品/套餐 |
transport | 交通 | 行 | vehicle, transport | 车票/租车/接送 |
retail | 零售特产 | 购 | retail, goods, souvenir | 商品/伴手礼 |
attraction | 景点门票 | 游 | scenic, attraction, ticket | 门票/景点 |
experience | 体验活动 | 娱 | experience, activity | 体验/活动/娱乐 |
guide | 向导服务 | 衍生 | guide, service, companion | 向导/陪护 |
other | 其它 | — | other | 兜底,不进任何行业包 |
要点:
accommodation/dining/transport 而非早前样本的 hotel/restaurant/vehicle——酒店/餐厅/车辆太窄(民宿/小吃/接送都算对应业态),宽义词才贴合行业包语义。IN ('room','stay','accommodation') 已含 accommodation,只需把 hotel/lodging_display 也纳入兼容读取即可,无需改写入逻辑即可先接真房态。feature_catalog 行业包一一对应(accommodation↔房态包、retail↔进销存包…),是 B端行业包显隐的数据基础。GET /merchant-console/features 数据面只读;admin_router GET/PUT /admin/merchants/{id}/features 控制面 _require_admin 全量覆盖);main.py 注册两 router。GET calendar / PUT /rooms/{id}/{date} 实时乐观更新);App.tsx/Workbench.tsx 注册入口并随 hotel 包显隐。PUT 全量覆盖;contract.ts/api.ts 加 MerchantFeaturesResp + getMerchantFeatures/setMerchantFeatures。GET /admin/merchants/1/features → entitled:["hotel"] + 5 项 catalog;B端数据面 GET /merchant-console/features → feature_keys:["hotel"];房态 GET calendar → 冈仁波齐城堡酒店(id=1) 神山观景双人间 真数据、09-25=full/total:3(印证前次 PUT 持久化);PUT /rooms/1/2026-09-25 full+total=3 实时落库(DB 直查 total=3,sold=3)。已为城堡(1)、温泉(8) 开通 hotel 包。