我们从 2 个 Ozon 店铺起步,现在运营 5 个。这次变化里真正有意思的不是数量,而是我们发现:两个店铺让我们保留了多少未经检验的假设。
只有两个店铺时,整个业务图景可以装在一个人脑子里。哪个 Listing 属于哪个店铺、哪个价格属于哪个渠道、两个店铺同时卖最后一件货会发生什么,都能靠记忆回答。到第三个店铺时这套方法就失效了,到五个店铺时会失效得非常明显。
店铺隔离是边界,不是副本
新增店铺时的第一反应是复制:复制商品目录、复制库存数字、复制映射表,然后把店铺标识改掉。它看起来很快,但会造出第二个版本的"事实",而它在一周之内就会和第一个版本互相矛盾。
我们选择了相反的立场:
- 原则
- 在实际系统中的含义
- 店铺是身份,不是库存容器
- 店铺拥有 Listing、价格和渠道规则,但不拥有自己的库存台账
- Listing 是渠道产物
- 两个店铺可以用不同的 Listing 身份销售同一件实物商品
- 商品身份是共享的
- 被销售的东西只描述一次,其它地方都引用它
- 库存只能被观测,不能被复制
- 店铺上报它看到的结果,系统记录这次观测,而不是凭空生成一个余额
现在新增一个店铺,是新增一个渠道身份,而不是新增一份库存。
为什么用"观测库存"取代"每店余额"
平台按自己的节奏、用自己的口径告诉你信息。一个渠道上报的是扣除自身预留之后的可售数量;另一个渠道上报的是昨晚被告知的数量。这两个数字都没有错,但也都不是实物库存的全部事实。
所以我们不再要求每个渠道充当"余额的来源"。渠道上报的是一次观测:这是我在这个时间点、从我的口径能看到的结果。观测会被记录、比对和核对,而不会被静默合并成一个谁也无法追溯的单一数字。
正是这一个建模决定,让五个店铺变得可管理,而不是变成五倍的维护量。
为了让它成立,我们必须构建什么
在一套运营模型下同时运行五个店铺,需要三件在两个店铺时并不明显的东西:
- 一个被所有 Listing 指向的统一商品身份,让同一件实物不会在每个渠道被重新描述一遍。
- 一层位于平台 Listing 身份与我们自己的 SKU 之间的映射,因为卖家货号和内部标识并不是同一件事。
- 一个解析器,回答"哪些渠道可以卖它、以什么价格卖",同时不允许任何单一渠道覆盖共享记录。
这些东西都不玄妙。但它们必须被强制执行,因为失败模式是静默的:一个被复制出来的库存数字,看起来依然是一个有效数字。
多店铺的代价不是第五个店铺,而是你没注意到自己创建出来的第二份"事实"。
随着店铺增加,什么发生了变化
当隔离被固定在渠道边界上之后,新增店铺就变成一项运营任务,而不是一个数据迁移项目。下一个店铺可以带着自己的 Listing 组合、自己的定价规则和自己的报表上线,而它引用的商品与实物库存,仍然留在原来的地方。
这才是我们构建这套模型时真正要买的东西:不是更多的店铺,而是每个店铺更少的意外。