[{"data":1,"prerenderedAt":6446},["ShallowReactive",2],{"content-/topics/engineering/ecommerce-system-refactor-log":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"category":5,"tags":11,"author":17,"featured":18,"series":19,"seriesOrder":20,"readingTime":21,"image":22,"body":23,"_type":6440,"_id":6441,"_source":6442,"_file":6443,"_stem":6444,"_extension":6445},"/topics/engineering/ecommerce-system-refactor-log","engineering",false,"","【真实案例】一个电商系统的重构日志：50 人团队如何在不停机的情况下翻新系统","不是“重写一遍就好了”的爽文，而是一份真的踩过坑的重构日志：从立项、拆边界、灰度发布到指标回收，完整复盘一个 50 人电商团队如何在不停业务的前提下完成前端与 BFF 重构。","2026-03-07",[12,13,14,15,16],"电商系统","系统重构","前端架构","BFF","工程治理","小明",true,"large-scale-application-architecture",2,16,"/images/articles/ecommerce-system-refactor-log-cover.jpg",{"type":24,"children":25,"toc":6357},"root",[26,34,40,45,59,64,77,82,119,124,128,135,140,147,152,176,181,187,192,315,321,326,337,342,513,518,536,539,545,550,562,568,573,580,585,591,603,609,614,620,625,643,649,654,659,665,670,675,698,704,709,713,731,737,742,770,781,784,790,802,808,813,836,842,959,965,970,1005,1010,1181,1186,1233,1236,1242,1248,1253,1258,1263,1290,1295,1313,1318,1341,1347,1528,1534,1546,1569,1574,1579,1590,1595,1598,1604,1610,1615,1620,1625,1631,1636,1810,1815,1820,1843,1849,2350,2355,2373,2378,2381,2387,2393,2398,2409,2415,2420,2448,2453,2471,2477,3214,3219,3237,3243,3832,3837,3842,3845,3851,3857,3862,3867,3872,3894,3900,4138,4143,4161,4167,4452,4457,4470,4475,4478,4484,4489,4495,4500,4523,4528,4533,4631,4636,4642,4647,4683,4688,4706,4709,4715,4721,4726,4734,4746,4751,4757,4990,4995,5018,5023,5029,5034,5167,5172,5175,5181,5187,5192,5210,5215,5220,5343,5348,5381,5386,5394,5397,5403,5409,5414,5432,5437,5460,5466,5529,5535,5540,5545,5550,5555,5578,5583,5591,5594,5600,5605,5610,5616,5781,5787,5903,5909,6005,6010,6015,6023,6026,6032,6038,6043,6049,6054,6060,6065,6071,6076,6082,6087,6093,6098,6104,6109,6112,6118,6123,6175,6180,6229,6234,6274,6277,6282,6287,6295,6300,6305,6310,6328,6333,6338,6346,6351],{"type":27,"tag":28,"props":29,"children":31},"element","h1",{"id":30},"真实案例一个电商系统的重构日志50-人团队如何在不停机的情况下翻新系统",[32],{"type":33,"value":8},"text",{"type":27,"tag":35,"props":36,"children":37},"p",{},[38],{"type":33,"value":39},"周五晚上 23:40，大促开始前 20 分钟，运营突然发现商品详情页的“满减预估”展示错了。",{"type":27,"tag":35,"props":41,"children":42},{},[43],{"type":33,"value":44},"表面上看，这只是一个前端文案问题。真正可怕的是：没有人敢立刻改。",{"type":27,"tag":35,"props":46,"children":47},{},[48,50,57],{"type":33,"value":49},"原因很简单——这个页面背后缠着 4 个接口、3 套价格口径、2 个历史活动系统，还有一堆“先这么写，回头再整理”的临时代码。你改一个 ",{"type":27,"tag":51,"props":52,"children":54},"code",{"className":53},[],[55],{"type":33,"value":56},"computed",{"type":33,"value":58},"，购物车可能炸；你补一个字段，订单确认页可能白屏；你修一个 bug，第二天埋点报表又会对不上。",{"type":27,"tag":35,"props":60,"children":61},{},[62],{"type":33,"value":63},"这不是某一个人的代码写得烂。",{"type":27,"tag":35,"props":65,"children":66},{},[67,69,75],{"type":33,"value":68},"这是",{"type":27,"tag":70,"props":71,"children":72},"strong",{},[73],{"type":33,"value":74},"系统已经超过了原来那套组织方式的承载上限",{"type":33,"value":76},"。",{"type":27,"tag":35,"props":78,"children":79},{},[80],{"type":33,"value":81},"这篇文章不讲“理想中的重构”，讲的是一次真实得有点狼狈的电商系统重构：",{"type":27,"tag":83,"props":84,"children":85},"ul",{},[86,92,97,102,107],{"type":27,"tag":87,"props":88,"children":89},"li",{},[90],{"type":33,"value":91},"团队 50 人，前端 12 人，后端 18 人，测试 8 人，产品/运营 12 人",{"type":27,"tag":87,"props":93,"children":94},{},[95],{"type":33,"value":96},"业务不能停，每周仍然要发版本",{"type":27,"tag":87,"props":98,"children":99},{},[100],{"type":33,"value":101},"不能“大爆炸式重写”",{"type":27,"tag":87,"props":103,"children":104},{},[105],{"type":33,"value":106},"必须在 6 周内交出阶段性结果",{"type":27,"tag":87,"props":108,"children":109},{},[110,112,117],{"type":33,"value":111},"最终目标不是“代码更优雅”，而是",{"type":27,"tag":70,"props":113,"children":114},{},[115],{"type":33,"value":116},"需求周期、线上风险、发布效率",{"type":33,"value":118},"都要变好",{"type":27,"tag":35,"props":120,"children":121},{},[122],{"type":33,"value":123},"如果你正在接手一个“谁都知道该重构，但谁都不敢动”的项目，这篇会比“重构原则大全”更有用。",{"type":27,"tag":125,"props":126,"children":127},"hr",{},[],{"type":27,"tag":129,"props":130,"children":132},"h2",{"id":131},"一项目背景系统不是一下子坏掉的",[133],{"type":33,"value":134},"一、项目背景：系统不是一下子坏掉的",{"type":27,"tag":35,"props":136,"children":137},{},[138],{"type":33,"value":139},"先交代基本盘。",{"type":27,"tag":141,"props":142,"children":144},"h3",{"id":143},"_11-业务形态",[145],{"type":33,"value":146},"1.1 业务形态",{"type":27,"tag":35,"props":148,"children":149},{},[150],{"type":33,"value":151},"这是一个做消费电子的电商站，核心链路有四条：",{"type":27,"tag":153,"props":154,"children":155},"ol",{},[156,161,166,171],{"type":27,"tag":87,"props":157,"children":158},{},[159],{"type":33,"value":160},"商品浏览",{"type":27,"tag":87,"props":162,"children":163},{},[164],{"type":33,"value":165},"搜索与筛选",{"type":27,"tag":87,"props":167,"children":168},{},[169],{"type":33,"value":170},"购物车与结算",{"type":27,"tag":87,"props":172,"children":173},{},[174],{"type":33,"value":175},"活动会场与优惠计算",{"type":27,"tag":35,"props":177,"children":178},{},[179],{"type":33,"value":180},"大促期间，前端日活峰值能到 180 万，移动端占 82%。",{"type":27,"tag":141,"props":182,"children":184},{"id":183},"_12-技术栈现状",[185],{"type":33,"value":186},"1.2 技术栈现状",{"type":27,"tag":35,"props":188,"children":189},{},[190],{"type":33,"value":191},"重构开始前的主栈如下：",{"type":27,"tag":193,"props":194,"children":195},"table",{},[196,220],{"type":27,"tag":197,"props":198,"children":199},"thead",{},[200],{"type":27,"tag":201,"props":202,"children":203},"tr",{},[204,210,215],{"type":27,"tag":205,"props":206,"children":207},"th",{},[208],{"type":33,"value":209},"层级",{"type":27,"tag":205,"props":211,"children":212},{},[213],{"type":33,"value":214},"旧方案",{"type":27,"tag":205,"props":216,"children":217},{},[218],{"type":33,"value":219},"典型问题",{"type":27,"tag":221,"props":222,"children":223},"tbody",{},[224,243,261,279,297],{"type":27,"tag":201,"props":225,"children":226},{},[227,233,238],{"type":27,"tag":228,"props":229,"children":230},"td",{},[231],{"type":33,"value":232},"前端",{"type":27,"tag":228,"props":234,"children":235},{},[236],{"type":33,"value":237},"Vue 2 + Vuex + Webpack 4",{"type":27,"tag":228,"props":239,"children":240},{},[241],{"type":33,"value":242},"页面过大、状态堆积、构建缓慢",{"type":27,"tag":201,"props":244,"children":245},{},[246,251,256],{"type":27,"tag":228,"props":247,"children":248},{},[249],{"type":33,"value":250},"Node 中间层",{"type":27,"tag":228,"props":252,"children":253},{},[254],{"type":33,"value":255},"Express + 手写聚合逻辑",{"type":27,"tag":228,"props":257,"children":258},{},[259],{"type":33,"value":260},"路由胖、容错弱、日志碎",{"type":27,"tag":201,"props":262,"children":263},{},[264,269,274],{"type":27,"tag":228,"props":265,"children":266},{},[267],{"type":33,"value":268},"后端 API",{"type":27,"tag":228,"props":270,"children":271},{},[272],{"type":33,"value":273},"多个 Java / Go 服务",{"type":27,"tag":228,"props":275,"children":276},{},[277],{"type":33,"value":278},"字段口径不一致",{"type":27,"tag":201,"props":280,"children":281},{},[282,287,292],{"type":27,"tag":228,"props":283,"children":284},{},[285],{"type":33,"value":286},"监控",{"type":27,"tag":228,"props":288,"children":289},{},[290],{"type":33,"value":291},"Sentry + ELK + 自建埋点",{"type":27,"tag":228,"props":293,"children":294},{},[295],{"type":33,"value":296},"监控割裂，无法串链路",{"type":27,"tag":201,"props":298,"children":299},{},[300,305,310],{"type":27,"tag":228,"props":301,"children":302},{},[303],{"type":33,"value":304},"发布",{"type":27,"tag":228,"props":306,"children":307},{},[308],{"type":33,"value":309},"Jenkins + 手工灰度",{"type":27,"tag":228,"props":311,"children":312},{},[313],{"type":33,"value":314},"发版慢，回滚重",{"type":27,"tag":141,"props":316,"children":318},{"id":317},"_13-最危险的不是代码丑而是改动不可预测",[319],{"type":33,"value":320},"1.3 最危险的不是“代码丑”，而是“改动不可预测”",{"type":27,"tag":35,"props":322,"children":323},{},[324],{"type":33,"value":325},"大家常把重构理解成“历史包袱太多”。",{"type":27,"tag":35,"props":327,"children":328},{},[329,331,336],{"type":33,"value":330},"更准确的说法是：",{"type":27,"tag":70,"props":332,"children":333},{},[334],{"type":33,"value":335},"系统已经失去了局部改动的可预测性",{"type":33,"value":76},{"type":27,"tag":35,"props":338,"children":339},{},[340],{"type":33,"value":341},"当时我们统计了 3 个月的数据：",{"type":27,"tag":193,"props":343,"children":344},{},[345,372],{"type":27,"tag":197,"props":346,"children":347},{},[348],{"type":27,"tag":201,"props":349,"children":350},{},[351,356,362,367],{"type":27,"tag":205,"props":352,"children":353},{},[354],{"type":33,"value":355},"指标",{"type":27,"tag":205,"props":357,"children":359},{"align":358},"right",[360],{"type":33,"value":361},"3 个月前",{"type":27,"tag":205,"props":363,"children":364},{"align":358},[365],{"type":33,"value":366},"重构前",{"type":27,"tag":205,"props":368,"children":369},{"align":358},[370],{"type":33,"value":371},"变化",{"type":27,"tag":221,"props":373,"children":374},{},[375,398,421,444,467,490],{"type":27,"tag":201,"props":376,"children":377},{},[378,383,388,393],{"type":27,"tag":228,"props":379,"children":380},{},[381],{"type":33,"value":382},"首页首屏 JS 体积",{"type":27,"tag":228,"props":384,"children":385},{"align":358},[386],{"type":33,"value":387},"420KB",{"type":27,"tag":228,"props":389,"children":390},{"align":358},[391],{"type":33,"value":392},"890KB",{"type":27,"tag":228,"props":394,"children":395},{"align":358},[396],{"type":33,"value":397},"+112%",{"type":27,"tag":201,"props":399,"children":400},{},[401,406,411,416],{"type":27,"tag":228,"props":402,"children":403},{},[404],{"type":33,"value":405},"商品详情页平均改动文件数",{"type":27,"tag":228,"props":407,"children":408},{"align":358},[409],{"type":33,"value":410},"4.1",{"type":27,"tag":228,"props":412,"children":413},{"align":358},[414],{"type":33,"value":415},"9.8",{"type":27,"tag":228,"props":417,"children":418},{"align":358},[419],{"type":33,"value":420},"+139%",{"type":27,"tag":201,"props":422,"children":423},{},[424,429,434,439],{"type":27,"tag":228,"props":425,"children":426},{},[427],{"type":33,"value":428},"MR 平均评审时长",{"type":27,"tag":228,"props":430,"children":431},{"align":358},[432],{"type":33,"value":433},"28 分钟",{"type":27,"tag":228,"props":435,"children":436},{"align":358},[437],{"type":33,"value":438},"97 分钟",{"type":27,"tag":228,"props":440,"children":441},{"align":358},[442],{"type":33,"value":443},"+246%",{"type":27,"tag":201,"props":445,"children":446},{},[447,452,457,462],{"type":27,"tag":228,"props":448,"children":449},{},[450],{"type":33,"value":451},"热修复次数 / 月",{"type":27,"tag":228,"props":453,"children":454},{"align":358},[455],{"type":33,"value":456},"3",{"type":27,"tag":228,"props":458,"children":459},{"align":358},[460],{"type":33,"value":461},"11",{"type":27,"tag":228,"props":463,"children":464},{"align":358},[465],{"type":33,"value":466},"+267%",{"type":27,"tag":201,"props":468,"children":469},{},[470,475,480,485],{"type":27,"tag":228,"props":471,"children":472},{},[473],{"type":33,"value":474},"大促前冻结时长",{"type":27,"tag":228,"props":476,"children":477},{"align":358},[478],{"type":33,"value":479},"1 天",{"type":27,"tag":228,"props":481,"children":482},{"align":358},[483],{"type":33,"value":484},"4 天",{"type":27,"tag":228,"props":486,"children":487},{"align":358},[488],{"type":33,"value":489},"+300%",{"type":27,"tag":201,"props":491,"children":492},{},[493,498,503,508],{"type":27,"tag":228,"props":494,"children":495},{},[496],{"type":33,"value":497},"新人独立接需求时间",{"type":27,"tag":228,"props":499,"children":500},{"align":358},[501],{"type":33,"value":502},"5 天",{"type":27,"tag":228,"props":504,"children":505},{"align":358},[506],{"type":33,"value":507},"14 天",{"type":27,"tag":228,"props":509,"children":510},{"align":358},[511],{"type":33,"value":512},"+180%",{"type":27,"tag":35,"props":514,"children":515},{},[516],{"type":33,"value":517},"你会发现，真正触发重构的，从来不是“代码看着不舒服”，而是：",{"type":27,"tag":83,"props":519,"children":520},{},[521,526,531],{"type":27,"tag":87,"props":522,"children":523},{},[524],{"type":33,"value":525},"发布开始拖慢业务",{"type":27,"tag":87,"props":527,"children":528},{},[529],{"type":33,"value":530},"团队协作成本被技术债吃掉",{"type":27,"tag":87,"props":532,"children":533},{},[534],{"type":33,"value":535},"风险开始超过“继续忍”的阈值",{"type":27,"tag":125,"props":537,"children":538},{},[],{"type":27,"tag":129,"props":540,"children":542},{"id":541},"二先别急着重构先判断是不是到了必须动的时点",[543],{"type":33,"value":544},"二、先别急着重构：先判断是不是到了“必须动”的时点",{"type":27,"tag":35,"props":546,"children":547},{},[548],{"type":33,"value":549},"在这个项目里，第一个关键决策不是“怎么重构”，而是：",{"type":27,"tag":551,"props":552,"children":553},"blockquote",{},[554],{"type":27,"tag":35,"props":555,"children":556},{},[557],{"type":27,"tag":70,"props":558,"children":559},{},[560],{"type":33,"value":561},"现在动，值不值？",{"type":27,"tag":141,"props":563,"children":565},{"id":564},"决策点-1我们用什么信号来证明该重构了",[566],{"type":33,"value":567},"决策点 1：我们用什么信号来证明“该重构了”",{"type":27,"tag":35,"props":569,"children":570},{},[571],{"type":33,"value":572},"我们没有用“工程师受不了了”做理由，而是用 4 组业务信号：",{"type":27,"tag":574,"props":575,"children":577},"h4",{"id":576},"信号-a需求交付变慢",[578],{"type":33,"value":579},"信号 A：需求交付变慢",{"type":27,"tag":35,"props":581,"children":582},{},[583],{"type":33,"value":584},"过去一个商品详情页需求，从设计联调到上线，平均 6 个工作日；重构前已经拉长到 11.5 天。",{"type":27,"tag":574,"props":586,"children":588},{"id":587},"信号-b线上风险上升",[589],{"type":33,"value":590},"信号 B：线上风险上升",{"type":27,"tag":35,"props":592,"children":593},{},[594,596,601],{"type":33,"value":595},"线上 bug 不只是数量变多，而是",{"type":27,"tag":70,"props":597,"children":598},{},[599],{"type":33,"value":600},"影响面变大",{"type":33,"value":602},"。一个价格模块改动，可能同时影响详情页、购物车、订单页。",{"type":27,"tag":574,"props":604,"children":606},{"id":605},"信号-c大促冻结越来越长",[607],{"type":33,"value":608},"信号 C：大促冻结越来越长",{"type":27,"tag":35,"props":610,"children":611},{},[612],{"type":33,"value":613},"冻结时间越长，说明团队越不相信系统的稳定性。",{"type":27,"tag":574,"props":615,"children":617},{"id":616},"信号-d管理层已经开始感知成本",[618],{"type":33,"value":619},"信号 D：管理层已经开始感知成本",{"type":27,"tag":35,"props":621,"children":622},{},[623],{"type":33,"value":624},"管理层不关心“store 太大了”，但关心：",{"type":27,"tag":83,"props":626,"children":627},{},[628,633,638],{"type":27,"tag":87,"props":629,"children":630},{},[631],{"type":33,"value":632},"为什么发版越来越慢？",{"type":27,"tag":87,"props":634,"children":635},{},[636],{"type":33,"value":637},"为什么同样人手做不出更多需求？",{"type":27,"tag":87,"props":639,"children":640},{},[641],{"type":33,"value":642},"为什么每逢大促就不敢动？",{"type":27,"tag":141,"props":644,"children":646},{"id":645},"决策点-2不用大重写而是做业务不中断的结构翻新",[647],{"type":33,"value":648},"决策点 2：不用“大重写”，而是做“业务不中断的结构翻新”",{"type":27,"tag":35,"props":650,"children":651},{},[652],{"type":33,"value":653},"这个选择，基本决定了项目是成功还是死亡。",{"type":27,"tag":35,"props":655,"children":656},{},[657],{"type":33,"value":658},"我们当时拒绝了两个看起来很诱人的方案：",{"type":27,"tag":574,"props":660,"children":662},{"id":661},"方案-a新开一个仓库全部重写",[663],{"type":33,"value":664},"方案 A：新开一个仓库，全部重写",{"type":27,"tag":35,"props":666,"children":667},{},[668],{"type":33,"value":669},"优点：干净，爽。",{"type":27,"tag":35,"props":671,"children":672},{},[673],{"type":33,"value":674},"缺点：",{"type":27,"tag":83,"props":676,"children":677},{},[678,683,688,693],{"type":27,"tag":87,"props":679,"children":680},{},[681],{"type":33,"value":682},"6 周内不可能替换完整业务",{"type":27,"tag":87,"props":684,"children":685},{},[686],{"type":33,"value":687},"重写期原系统还要继续改",{"type":27,"tag":87,"props":689,"children":690},{},[691],{"type":33,"value":692},"双线开发会让团队直接分裂",{"type":27,"tag":87,"props":694,"children":695},{},[696],{"type":33,"value":697},"最后大概率变成“新系统永远差一点”",{"type":27,"tag":574,"props":699,"children":701},{"id":700},"方案-b只做局部性能优化不动结构",[702],{"type":33,"value":703},"方案 B：只做局部性能优化，不动结构",{"type":27,"tag":35,"props":705,"children":706},{},[707],{"type":33,"value":708},"优点：短期见效快。",{"type":27,"tag":35,"props":710,"children":711},{},[712],{"type":33,"value":674},{"type":27,"tag":83,"props":714,"children":715},{},[716,721,726],{"type":27,"tag":87,"props":717,"children":718},{},[719],{"type":33,"value":720},"修的是症状，不是病因",{"type":27,"tag":87,"props":722,"children":723},{},[724],{"type":33,"value":725},"3 个月后还会回到原样",{"type":27,"tag":87,"props":727,"children":728},{},[729],{"type":33,"value":730},"需求流继续把结构拖垮",{"type":27,"tag":574,"props":732,"children":734},{"id":733},"最终选择strangler-fig绞杀者式渐进重构",[735],{"type":33,"value":736},"最终选择：Strangler Fig（绞杀者）式渐进重构",{"type":27,"tag":35,"props":738,"children":739},{},[740],{"type":33,"value":741},"思路是：",{"type":27,"tag":153,"props":743,"children":744},{},[745,750,755,760,765],{"type":27,"tag":87,"props":746,"children":747},{},[748],{"type":33,"value":749},"先找边界最清晰、业务收益最大的模块",{"type":27,"tag":87,"props":751,"children":752},{},[753],{"type":33,"value":754},"新能力在新结构里长出来",{"type":27,"tag":87,"props":756,"children":757},{},[758],{"type":33,"value":759},"旧系统只做必要维护",{"type":27,"tag":87,"props":761,"children":762},{},[763],{"type":33,"value":764},"流量和职责逐步迁移",{"type":27,"tag":87,"props":766,"children":767},{},[768],{"type":33,"value":769},"最后把旧实现“包住并替换掉”",{"type":27,"tag":35,"props":771,"children":772},{},[773,775,780],{"type":33,"value":774},"这套打法的好处不是“优雅”，而是",{"type":27,"tag":70,"props":776,"children":777},{},[778],{"type":33,"value":779},"现实",{"type":33,"value":76},{"type":27,"tag":125,"props":782,"children":783},{},[],{"type":27,"tag":129,"props":785,"children":787},{"id":786},"三先画战场地图重构前必须知道系统到底烂在哪",[788],{"type":33,"value":789},"三、先画战场地图：重构前必须知道系统到底烂在哪",{"type":27,"tag":35,"props":791,"children":792},{},[793,795,800],{"type":33,"value":794},"真正的重构，不是从改目录开始，而是从",{"type":27,"tag":70,"props":796,"children":797},{},[798],{"type":33,"value":799},"建立共享事实",{"type":33,"value":801},"开始。",{"type":27,"tag":141,"props":803,"children":805},{"id":804},"_31-我们先做了一周盘点而不是直接写代码",[806],{"type":33,"value":807},"3.1 我们先做了一周“盘点”，而不是直接写代码",{"type":27,"tag":35,"props":809,"children":810},{},[811],{"type":33,"value":812},"这一周只做 4 件事：",{"type":27,"tag":153,"props":814,"children":815},{},[816,821,826,831],{"type":27,"tag":87,"props":817,"children":818},{},[819],{"type":33,"value":820},"统计页面级性能与依赖",{"type":27,"tag":87,"props":822,"children":823},{},[824],{"type":33,"value":825},"列出核心业务链路",{"type":27,"tag":87,"props":827,"children":828},{},[829],{"type":33,"value":830},"标记高风险共用模块",{"type":27,"tag":87,"props":832,"children":833},{},[834],{"type":33,"value":835},"画出“谁依赖谁”的实际图，而不是理想图",{"type":27,"tag":141,"props":837,"children":839},{"id":838},"_32-盘点结果系统主要烂在-5-个点",[840],{"type":33,"value":841},"3.2 盘点结果：系统主要烂在 5 个点",{"type":27,"tag":193,"props":843,"children":844},{},[845,866],{"type":27,"tag":197,"props":846,"children":847},{},[848],{"type":27,"tag":201,"props":849,"children":850},{},[851,856,861],{"type":27,"tag":205,"props":852,"children":853},{},[854],{"type":33,"value":855},"问题",{"type":27,"tag":205,"props":857,"children":858},{},[859],{"type":33,"value":860},"具体表现",{"type":27,"tag":205,"props":862,"children":863},{},[864],{"type":33,"value":865},"后果",{"type":27,"tag":221,"props":867,"children":868},{},[869,887,905,923,941],{"type":27,"tag":201,"props":870,"children":871},{},[872,877,882],{"type":27,"tag":228,"props":873,"children":874},{},[875],{"type":33,"value":876},"页面过胖",{"type":27,"tag":228,"props":878,"children":879},{},[880],{"type":33,"value":881},"详情页单文件 1400+ 行",{"type":27,"tag":228,"props":883,"children":884},{},[885],{"type":33,"value":886},"修改成本极高",{"type":27,"tag":201,"props":888,"children":889},{},[890,895,900],{"type":27,"tag":228,"props":891,"children":892},{},[893],{"type":33,"value":894},"状态无边界",{"type":27,"tag":228,"props":896,"children":897},{},[898],{"type":33,"value":899},"Vuex 一个 store 负责 11 类状态",{"type":27,"tag":228,"props":901,"children":902},{},[903],{"type":33,"value":904},"改动互相污染",{"type":27,"tag":201,"props":906,"children":907},{},[908,913,918],{"type":27,"tag":228,"props":909,"children":910},{},[911],{"type":33,"value":912},"接口口径不统一",{"type":27,"tag":228,"props":914,"children":915},{},[916],{"type":33,"value":917},"商品价格字段有 4 种命名",{"type":27,"tag":228,"props":919,"children":920},{},[921],{"type":33,"value":922},"前端做了大量胶水转换",{"type":27,"tag":201,"props":924,"children":925},{},[926,931,936],{"type":27,"tag":228,"props":927,"children":928},{},[929],{"type":33,"value":930},"组件与业务缠死",{"type":27,"tag":228,"props":932,"children":933},{},[934],{"type":33,"value":935},"UI 组件里直接请求接口",{"type":27,"tag":228,"props":937,"children":938},{},[939],{"type":33,"value":940},"无法复用、难测",{"type":27,"tag":201,"props":942,"children":943},{},[944,949,954],{"type":27,"tag":228,"props":945,"children":946},{},[947],{"type":33,"value":948},"发布缺少隔离",{"type":27,"tag":228,"props":950,"children":951},{},[952],{"type":33,"value":953},"没有按能力灰度，只能整站发",{"type":27,"tag":228,"props":955,"children":956},{},[957],{"type":33,"value":958},"风险放大",{"type":27,"tag":141,"props":960,"children":962},{"id":961},"_33-我们定义了新的目标结构",[963],{"type":33,"value":964},"3.3 我们定义了新的目标结构",{"type":27,"tag":35,"props":966,"children":967},{},[968],{"type":33,"value":969},"不是“上某个框架”，而是建立 4 条工程纪律：",{"type":27,"tag":153,"props":971,"children":972},{},[973,981,989,997],{"type":27,"tag":87,"props":974,"children":975},{},[976],{"type":27,"tag":70,"props":977,"children":978},{},[979],{"type":33,"value":980},"页面只负责编排，不直接承载复杂业务规则",{"type":27,"tag":87,"props":982,"children":983},{},[984],{"type":27,"tag":70,"props":985,"children":986},{},[987],{"type":33,"value":988},"跨页面复用逻辑沉到领域层 / composable / BFF facade",{"type":27,"tag":87,"props":990,"children":991},{},[992],{"type":27,"tag":70,"props":993,"children":994},{},[995],{"type":33,"value":996},"状态只按边界持有，不按“方便”全局共享",{"type":27,"tag":87,"props":998,"children":999},{},[1000],{"type":27,"tag":70,"props":1001,"children":1002},{},[1003],{"type":33,"value":1004},"每个迁移都必须能灰度、能回滚、能量化收益",{"type":27,"tag":35,"props":1006,"children":1007},{},[1008],{"type":33,"value":1009},"对应的目标结构如下：",{"type":27,"tag":1011,"props":1012,"children":1015},"pre",{"className":1013,"code":1014,"language":33,"meta":7,"style":7},"language-text shiki shiki-themes github-dark","apps/web/\n├── pages/\n│   ├── product-detail/\n│   ├── cart/\n│   └── checkout/\n├── features/\n│   ├── pricing/\n│   ├── promotion/\n│   ├── inventory/\n│   └── recommendation/\n├── shared/\n│   ├── ui/\n│   ├── lib/\n│   └── telemetry/\n└── bff/\n    ├── product/\n    ├── order/\n    └── promotion/\n",[1016],{"type":27,"tag":51,"props":1017,"children":1018},{"__ignoreMap":7},[1019,1030,1038,1047,1056,1065,1074,1083,1092,1101,1110,1119,1128,1137,1146,1155,1163,1172],{"type":27,"tag":1020,"props":1021,"children":1024},"span",{"class":1022,"line":1023},"line",1,[1025],{"type":27,"tag":1020,"props":1026,"children":1027},{},[1028],{"type":33,"value":1029},"apps/web/\n",{"type":27,"tag":1020,"props":1031,"children":1032},{"class":1022,"line":20},[1033],{"type":27,"tag":1020,"props":1034,"children":1035},{},[1036],{"type":33,"value":1037},"├── pages/\n",{"type":27,"tag":1020,"props":1039,"children":1041},{"class":1022,"line":1040},3,[1042],{"type":27,"tag":1020,"props":1043,"children":1044},{},[1045],{"type":33,"value":1046},"│   ├── product-detail/\n",{"type":27,"tag":1020,"props":1048,"children":1050},{"class":1022,"line":1049},4,[1051],{"type":27,"tag":1020,"props":1052,"children":1053},{},[1054],{"type":33,"value":1055},"│   ├── cart/\n",{"type":27,"tag":1020,"props":1057,"children":1059},{"class":1022,"line":1058},5,[1060],{"type":27,"tag":1020,"props":1061,"children":1062},{},[1063],{"type":33,"value":1064},"│   └── checkout/\n",{"type":27,"tag":1020,"props":1066,"children":1068},{"class":1022,"line":1067},6,[1069],{"type":27,"tag":1020,"props":1070,"children":1071},{},[1072],{"type":33,"value":1073},"├── features/\n",{"type":27,"tag":1020,"props":1075,"children":1077},{"class":1022,"line":1076},7,[1078],{"type":27,"tag":1020,"props":1079,"children":1080},{},[1081],{"type":33,"value":1082},"│   ├── pricing/\n",{"type":27,"tag":1020,"props":1084,"children":1086},{"class":1022,"line":1085},8,[1087],{"type":27,"tag":1020,"props":1088,"children":1089},{},[1090],{"type":33,"value":1091},"│   ├── promotion/\n",{"type":27,"tag":1020,"props":1093,"children":1095},{"class":1022,"line":1094},9,[1096],{"type":27,"tag":1020,"props":1097,"children":1098},{},[1099],{"type":33,"value":1100},"│   ├── inventory/\n",{"type":27,"tag":1020,"props":1102,"children":1104},{"class":1022,"line":1103},10,[1105],{"type":27,"tag":1020,"props":1106,"children":1107},{},[1108],{"type":33,"value":1109},"│   └── recommendation/\n",{"type":27,"tag":1020,"props":1111,"children":1113},{"class":1022,"line":1112},11,[1114],{"type":27,"tag":1020,"props":1115,"children":1116},{},[1117],{"type":33,"value":1118},"├── shared/\n",{"type":27,"tag":1020,"props":1120,"children":1122},{"class":1022,"line":1121},12,[1123],{"type":27,"tag":1020,"props":1124,"children":1125},{},[1126],{"type":33,"value":1127},"│   ├── ui/\n",{"type":27,"tag":1020,"props":1129,"children":1131},{"class":1022,"line":1130},13,[1132],{"type":27,"tag":1020,"props":1133,"children":1134},{},[1135],{"type":33,"value":1136},"│   ├── lib/\n",{"type":27,"tag":1020,"props":1138,"children":1140},{"class":1022,"line":1139},14,[1141],{"type":27,"tag":1020,"props":1142,"children":1143},{},[1144],{"type":33,"value":1145},"│   └── telemetry/\n",{"type":27,"tag":1020,"props":1147,"children":1149},{"class":1022,"line":1148},15,[1150],{"type":27,"tag":1020,"props":1151,"children":1152},{},[1153],{"type":33,"value":1154},"└── bff/\n",{"type":27,"tag":1020,"props":1156,"children":1157},{"class":1022,"line":21},[1158],{"type":27,"tag":1020,"props":1159,"children":1160},{},[1161],{"type":33,"value":1162},"    ├── product/\n",{"type":27,"tag":1020,"props":1164,"children":1166},{"class":1022,"line":1165},17,[1167],{"type":27,"tag":1020,"props":1168,"children":1169},{},[1170],{"type":33,"value":1171},"    ├── order/\n",{"type":27,"tag":1020,"props":1173,"children":1175},{"class":1022,"line":1174},18,[1176],{"type":27,"tag":1020,"props":1177,"children":1178},{},[1179],{"type":33,"value":1180},"    └── promotion/\n",{"type":27,"tag":35,"props":1182,"children":1183},{},[1184],{"type":33,"value":1185},"这里最重要的不是目录本身，而是：",{"type":27,"tag":83,"props":1187,"children":1188},{},[1189,1200,1211,1222],{"type":27,"tag":87,"props":1190,"children":1191},{},[1192,1198],{"type":27,"tag":51,"props":1193,"children":1195},{"className":1194},[],[1196],{"type":33,"value":1197},"features",{"type":33,"value":1199}," 负责领域能力",{"type":27,"tag":87,"props":1201,"children":1202},{},[1203,1209],{"type":27,"tag":51,"props":1204,"children":1206},{"className":1205},[],[1207],{"type":33,"value":1208},"shared",{"type":33,"value":1210}," 负责无业务语义的可复用部分",{"type":27,"tag":87,"props":1212,"children":1213},{},[1214,1220],{"type":27,"tag":51,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":33,"value":1219},"bff",{"type":33,"value":1221}," 负责后端口径适配与容错",{"type":27,"tag":87,"props":1223,"children":1224},{},[1225,1231],{"type":27,"tag":51,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":33,"value":1230},"pages",{"type":33,"value":1232}," 只做组装与页面路由",{"type":27,"tag":125,"props":1234,"children":1235},{},[],{"type":27,"tag":129,"props":1237,"children":1239},{"id":1238},"四6-周是怎么拆出来的不是按技术拆是按风险拆",[1240],{"type":33,"value":1241},"四、6 周是怎么拆出来的：不是按技术拆，是按风险拆",{"type":27,"tag":141,"props":1243,"children":1245},{"id":1244},"决策点-3先拆哪条链路",[1246],{"type":33,"value":1247},"决策点 3：先拆哪条链路",{"type":27,"tag":35,"props":1249,"children":1250},{},[1251],{"type":33,"value":1252},"很多团队一重构就上来先动“最烂的地方”。",{"type":27,"tag":35,"props":1254,"children":1255},{},[1256],{"type":33,"value":1257},"这是错的。",{"type":27,"tag":35,"props":1259,"children":1260},{},[1261],{"type":33,"value":1262},"应该先动：",{"type":27,"tag":83,"props":1264,"children":1265},{},[1266,1274,1282],{"type":27,"tag":87,"props":1267,"children":1268},{},[1269],{"type":27,"tag":70,"props":1270,"children":1271},{},[1272],{"type":33,"value":1273},"收益高",{"type":27,"tag":87,"props":1275,"children":1276},{},[1277],{"type":27,"tag":70,"props":1278,"children":1279},{},[1280],{"type":33,"value":1281},"边界相对清晰",{"type":27,"tag":87,"props":1283,"children":1284},{},[1285],{"type":27,"tag":70,"props":1286,"children":1287},{},[1288],{"type":33,"value":1289},"失败了也不会把业务整体拖死",{"type":27,"tag":35,"props":1291,"children":1292},{},[1293],{"type":33,"value":1294},"我们最后选的是：",{"type":27,"tag":153,"props":1296,"children":1297},{},[1298,1303,1308],{"type":27,"tag":87,"props":1299,"children":1300},{},[1301],{"type":33,"value":1302},"商品详情页的价格与活动计算链路",{"type":27,"tag":87,"props":1304,"children":1305},{},[1306],{"type":33,"value":1307},"购物车价格汇总链路",{"type":27,"tag":87,"props":1309,"children":1310},{},[1311],{"type":33,"value":1312},"BFF 的聚合层",{"type":27,"tag":35,"props":1314,"children":1315},{},[1316],{"type":33,"value":1317},"原因很简单：",{"type":27,"tag":83,"props":1319,"children":1320},{},[1321,1326,1331,1336],{"type":27,"tag":87,"props":1322,"children":1323},{},[1324],{"type":33,"value":1325},"这些模块是大促高频路径",{"type":27,"tag":87,"props":1327,"children":1328},{},[1329],{"type":33,"value":1330},"之前故障也集中在这里",{"type":27,"tag":87,"props":1332,"children":1333},{},[1334],{"type":33,"value":1335},"它们虽然复杂，但边界比搜索推荐清晰",{"type":27,"tag":87,"props":1337,"children":1338},{},[1339],{"type":33,"value":1340},"改好了，业务能立刻看到价值",{"type":27,"tag":141,"props":1342,"children":1344},{"id":1343},"_41-六周计划表",[1345],{"type":33,"value":1346},"4.1 六周计划表",{"type":27,"tag":193,"props":1348,"children":1349},{},[1350,1376],{"type":27,"tag":197,"props":1351,"children":1352},{},[1353],{"type":27,"tag":201,"props":1354,"children":1355},{},[1356,1361,1366,1371],{"type":27,"tag":205,"props":1357,"children":1358},{},[1359],{"type":33,"value":1360},"周次",{"type":27,"tag":205,"props":1362,"children":1363},{},[1364],{"type":33,"value":1365},"目标",{"type":27,"tag":205,"props":1367,"children":1368},{},[1369],{"type":33,"value":1370},"产出",{"type":27,"tag":205,"props":1372,"children":1373},{},[1374],{"type":33,"value":1375},"风险控制",{"type":27,"tag":221,"props":1377,"children":1378},{},[1379,1402,1425,1454,1482,1505],{"type":27,"tag":201,"props":1380,"children":1381},{},[1382,1387,1392,1397],{"type":27,"tag":228,"props":1383,"children":1384},{},[1385],{"type":33,"value":1386},"第 1 周",{"type":27,"tag":228,"props":1388,"children":1389},{},[1390],{"type":33,"value":1391},"盘点与基线建立",{"type":27,"tag":228,"props":1393,"children":1394},{},[1395],{"type":33,"value":1396},"指标看板、依赖图、迁移清单",{"type":27,"tag":228,"props":1398,"children":1399},{},[1400],{"type":33,"value":1401},"不改线上逻辑",{"type":27,"tag":201,"props":1403,"children":1404},{},[1405,1410,1415,1420],{"type":27,"tag":228,"props":1406,"children":1407},{},[1408],{"type":33,"value":1409},"第 2 周",{"type":27,"tag":228,"props":1411,"children":1412},{},[1413],{"type":33,"value":1414},"搭新骨架",{"type":27,"tag":228,"props":1416,"children":1417},{},[1418],{"type":33,"value":1419},"feature 目录、BFF facade、日志标准",{"type":27,"tag":228,"props":1421,"children":1422},{},[1423],{"type":33,"value":1424},"新旧并存",{"type":27,"tag":201,"props":1426,"children":1427},{},[1428,1433,1438,1449],{"type":27,"tag":228,"props":1429,"children":1430},{},[1431],{"type":33,"value":1432},"第 3 周",{"type":27,"tag":228,"props":1434,"children":1435},{},[1436],{"type":33,"value":1437},"迁移价格计算",{"type":27,"tag":228,"props":1439,"children":1440},{},[1441,1447],{"type":27,"tag":51,"props":1442,"children":1444},{"className":1443},[],[1445],{"type":33,"value":1446},"pricing",{"type":33,"value":1448}," 模块落地",{"type":27,"tag":228,"props":1450,"children":1451},{},[1452],{"type":33,"value":1453},"开关控制",{"type":27,"tag":201,"props":1455,"children":1456},{},[1457,1462,1467,1477],{"type":27,"tag":228,"props":1458,"children":1459},{},[1460],{"type":33,"value":1461},"第 4 周",{"type":27,"tag":228,"props":1463,"children":1464},{},[1465],{"type":33,"value":1466},"迁移活动逻辑",{"type":27,"tag":228,"props":1468,"children":1469},{},[1470,1476],{"type":27,"tag":51,"props":1471,"children":1473},{"className":1472},[],[1474],{"type":33,"value":1475},"promotion",{"type":33,"value":1448},{"type":27,"tag":228,"props":1478,"children":1479},{},[1480],{"type":33,"value":1481},"影子比对",{"type":27,"tag":201,"props":1483,"children":1484},{},[1485,1490,1495,1500],{"type":27,"tag":228,"props":1486,"children":1487},{},[1488],{"type":33,"value":1489},"第 5 周",{"type":27,"tag":228,"props":1491,"children":1492},{},[1493],{"type":33,"value":1494},"购物车与结算接入",{"type":27,"tag":228,"props":1496,"children":1497},{},[1498],{"type":33,"value":1499},"关键页面接新链路",{"type":27,"tag":228,"props":1501,"children":1502},{},[1503],{"type":33,"value":1504},"10% 灰度",{"type":27,"tag":201,"props":1506,"children":1507},{},[1508,1513,1518,1523],{"type":27,"tag":228,"props":1509,"children":1510},{},[1511],{"type":33,"value":1512},"第 6 周",{"type":27,"tag":228,"props":1514,"children":1515},{},[1516],{"type":33,"value":1517},"全量切换与回收旧代码",{"type":27,"tag":228,"props":1519,"children":1520},{},[1521],{"type":33,"value":1522},"指标复盘、删除旧实现",{"type":27,"tag":228,"props":1524,"children":1525},{},[1526],{"type":33,"value":1527},"保留回滚路径",{"type":27,"tag":141,"props":1529,"children":1531},{"id":1530},"决策点-4禁止同时优化所有问题",[1532],{"type":33,"value":1533},"决策点 4：禁止“同时优化所有问题”",{"type":27,"tag":35,"props":1535,"children":1536},{},[1537,1539,1544],{"type":33,"value":1538},"这次重构刻意",{"type":27,"tag":70,"props":1540,"children":1541},{},[1542],{"type":33,"value":1543},"没有",{"type":33,"value":1545},"做这些事：",{"type":27,"tag":83,"props":1547,"children":1548},{},[1549,1554,1559,1564],{"type":27,"tag":87,"props":1550,"children":1551},{},[1552],{"type":33,"value":1553},"没有同步把 Vue 2 全量升级成 Vue 3",{"type":27,"tag":87,"props":1555,"children":1556},{},[1557],{"type":33,"value":1558},"没有顺手换掉所有 UI 组件库",{"type":27,"tag":87,"props":1560,"children":1561},{},[1562],{"type":33,"value":1563},"没有一并改 SSR 方案",{"type":27,"tag":87,"props":1565,"children":1566},{},[1567],{"type":33,"value":1568},"没有顺便重做埋点体系",{"type":27,"tag":35,"props":1570,"children":1571},{},[1572],{"type":33,"value":1573},"因为每多一个目标，项目就少一分成功率。",{"type":27,"tag":35,"props":1575,"children":1576},{},[1577],{"type":33,"value":1578},"重构必须有主目标：",{"type":27,"tag":551,"props":1580,"children":1581},{},[1582],{"type":27,"tag":35,"props":1583,"children":1584},{},[1585],{"type":27,"tag":70,"props":1586,"children":1587},{},[1588],{"type":33,"value":1589},"降低关键业务链路的耦合与发布风险。",{"type":27,"tag":35,"props":1591,"children":1592},{},[1593],{"type":33,"value":1594},"只要不直接服务这个目标，就延后。",{"type":27,"tag":125,"props":1596,"children":1597},{},[],{"type":27,"tag":129,"props":1599,"children":1601},{"id":1600},"五第一刀怎么下先做-bff-防腐层而不是先改页面",[1602],{"type":33,"value":1603},"五、第一刀怎么下：先做 BFF 防腐层，而不是先改页面",{"type":27,"tag":141,"props":1605,"children":1607},{"id":1606},"决策点-5我们为什么先重构-bff",[1608],{"type":33,"value":1609},"决策点 5：我们为什么先重构 BFF",{"type":27,"tag":35,"props":1611,"children":1612},{},[1613],{"type":33,"value":1614},"前端团队一开始都想直接改页面。毕竟页面最痛。",{"type":27,"tag":35,"props":1616,"children":1617},{},[1618],{"type":33,"value":1619},"但如果后端口径还是乱的，前端再怎么拆都只是把脏逻辑从一个文件搬到多个文件。",{"type":27,"tag":35,"props":1621,"children":1622},{},[1623],{"type":33,"value":1624},"所以第一刀砍在 BFF。",{"type":27,"tag":141,"props":1626,"children":1628},{"id":1627},"_51-旧问题前端页面自己做字段适配",[1629],{"type":33,"value":1630},"5.1 旧问题：前端页面自己做字段适配",{"type":27,"tag":35,"props":1632,"children":1633},{},[1634],{"type":33,"value":1635},"当时商品详情页里有这样的代码：",{"type":27,"tag":1011,"props":1637,"children":1641},{"className":1638,"code":1639,"language":1640,"meta":7,"style":7},"language-ts shiki shiki-themes github-dark","const finalPrice =\n  product.activityPrice\n  ?? product.promoPrice\n  ?? product.salePrice\n  ?? product.price\n\nconst inventory = product.stock ?? product.inventoryCount ?? 0\nconst canUseCoupon = product.couponFlag === 1 || product.marketing?.couponEnabled === true\n","ts",[1642],{"type":27,"tag":51,"props":1643,"children":1644},{"__ignoreMap":7},[1645,1665,1674,1687,1699,1711,1719,1760],{"type":27,"tag":1020,"props":1646,"children":1647},{"class":1022,"line":1023},[1648,1654,1660],{"type":27,"tag":1020,"props":1649,"children":1651},{"style":1650},"--shiki-default:#F97583",[1652],{"type":33,"value":1653},"const",{"type":27,"tag":1020,"props":1655,"children":1657},{"style":1656},"--shiki-default:#79B8FF",[1658],{"type":33,"value":1659}," finalPrice",{"type":27,"tag":1020,"props":1661,"children":1662},{"style":1650},[1663],{"type":33,"value":1664}," =\n",{"type":27,"tag":1020,"props":1666,"children":1667},{"class":1022,"line":20},[1668],{"type":27,"tag":1020,"props":1669,"children":1671},{"style":1670},"--shiki-default:#E1E4E8",[1672],{"type":33,"value":1673},"  product.activityPrice\n",{"type":27,"tag":1020,"props":1675,"children":1676},{"class":1022,"line":1040},[1677,1682],{"type":27,"tag":1020,"props":1678,"children":1679},{"style":1650},[1680],{"type":33,"value":1681},"  ??",{"type":27,"tag":1020,"props":1683,"children":1684},{"style":1670},[1685],{"type":33,"value":1686}," product.promoPrice\n",{"type":27,"tag":1020,"props":1688,"children":1689},{"class":1022,"line":1049},[1690,1694],{"type":27,"tag":1020,"props":1691,"children":1692},{"style":1650},[1693],{"type":33,"value":1681},{"type":27,"tag":1020,"props":1695,"children":1696},{"style":1670},[1697],{"type":33,"value":1698}," product.salePrice\n",{"type":27,"tag":1020,"props":1700,"children":1701},{"class":1022,"line":1058},[1702,1706],{"type":27,"tag":1020,"props":1703,"children":1704},{"style":1650},[1705],{"type":33,"value":1681},{"type":27,"tag":1020,"props":1707,"children":1708},{"style":1670},[1709],{"type":33,"value":1710}," product.price\n",{"type":27,"tag":1020,"props":1712,"children":1713},{"class":1022,"line":1067},[1714],{"type":27,"tag":1020,"props":1715,"children":1716},{"emptyLinePlaceholder":18},[1717],{"type":33,"value":1718},"\n",{"type":27,"tag":1020,"props":1720,"children":1721},{"class":1022,"line":1076},[1722,1726,1731,1736,1741,1746,1751,1755],{"type":27,"tag":1020,"props":1723,"children":1724},{"style":1650},[1725],{"type":33,"value":1653},{"type":27,"tag":1020,"props":1727,"children":1728},{"style":1656},[1729],{"type":33,"value":1730}," inventory",{"type":27,"tag":1020,"props":1732,"children":1733},{"style":1650},[1734],{"type":33,"value":1735}," =",{"type":27,"tag":1020,"props":1737,"children":1738},{"style":1670},[1739],{"type":33,"value":1740}," product.stock ",{"type":27,"tag":1020,"props":1742,"children":1743},{"style":1650},[1744],{"type":33,"value":1745},"??",{"type":27,"tag":1020,"props":1747,"children":1748},{"style":1670},[1749],{"type":33,"value":1750}," product.inventoryCount ",{"type":27,"tag":1020,"props":1752,"children":1753},{"style":1650},[1754],{"type":33,"value":1745},{"type":27,"tag":1020,"props":1756,"children":1757},{"style":1656},[1758],{"type":33,"value":1759}," 0\n",{"type":27,"tag":1020,"props":1761,"children":1762},{"class":1022,"line":1085},[1763,1767,1772,1776,1781,1786,1791,1796,1801,1805],{"type":27,"tag":1020,"props":1764,"children":1765},{"style":1650},[1766],{"type":33,"value":1653},{"type":27,"tag":1020,"props":1768,"children":1769},{"style":1656},[1770],{"type":33,"value":1771}," canUseCoupon",{"type":27,"tag":1020,"props":1773,"children":1774},{"style":1650},[1775],{"type":33,"value":1735},{"type":27,"tag":1020,"props":1777,"children":1778},{"style":1670},[1779],{"type":33,"value":1780}," product.couponFlag ",{"type":27,"tag":1020,"props":1782,"children":1783},{"style":1650},[1784],{"type":33,"value":1785},"===",{"type":27,"tag":1020,"props":1787,"children":1788},{"style":1656},[1789],{"type":33,"value":1790}," 1",{"type":27,"tag":1020,"props":1792,"children":1793},{"style":1650},[1794],{"type":33,"value":1795}," ||",{"type":27,"tag":1020,"props":1797,"children":1798},{"style":1670},[1799],{"type":33,"value":1800}," product.marketing?.couponEnabled ",{"type":27,"tag":1020,"props":1802,"children":1803},{"style":1650},[1804],{"type":33,"value":1785},{"type":27,"tag":1020,"props":1806,"children":1807},{"style":1656},[1808],{"type":33,"value":1809}," true\n",{"type":27,"tag":35,"props":1811,"children":1812},{},[1813],{"type":33,"value":1814},"看上去只是“兼容一下字段差异”。",{"type":27,"tag":35,"props":1816,"children":1817},{},[1818],{"type":33,"value":1819},"实际上，这意味着：",{"type":27,"tag":83,"props":1821,"children":1822},{},[1823,1828,1833,1838],{"type":27,"tag":87,"props":1824,"children":1825},{},[1826],{"type":33,"value":1827},"接口变化会在多个页面复制扩散",{"type":27,"tag":87,"props":1829,"children":1830},{},[1831],{"type":33,"value":1832},"业务规则被埋在 UI 层",{"type":27,"tag":87,"props":1834,"children":1835},{},[1836],{"type":33,"value":1837},"没法统一测试",{"type":27,"tag":87,"props":1839,"children":1840},{},[1841],{"type":33,"value":1842},"页面开发者必须理解后端历史包袱",{"type":27,"tag":141,"props":1844,"children":1846},{"id":1845},"_52-新做法bff-统一口径页面只消费标准模型",[1847],{"type":33,"value":1848},"5.2 新做法：BFF 统一口径，页面只消费标准模型",{"type":27,"tag":1011,"props":1850,"children":1852},{"className":1638,"code":1851,"language":1640,"meta":7,"style":7},"// bff/product/getProductView.ts\ninterface ProductViewModel {\n  id: string\n  title: string\n  originPrice: number\n  finalPrice: number\n  inventory: number\n  promotionTags: string[]\n  couponAvailable: boolean\n}\n\nexport async function getProductView(productId: string): Promise\u003CProductViewModel> {\n  const [product, promotion, inventory] = await Promise.all([\n    productService.fetch(productId),\n    promotionService.fetch(productId),\n    inventoryService.fetch(productId),\n  ])\n\n  return {\n    id: product.id,\n    title: product.title,\n    originPrice: product.marketPrice,\n    finalPrice: resolveFinalPrice(product, promotion),\n    inventory: inventory.available,\n    promotionTags: resolvePromotionTags(promotion),\n    couponAvailable: Boolean(promotion.coupon?.enabled),\n  }\n}\n",[1853],{"type":27,"tag":51,"props":1854,"children":1855},{"__ignoreMap":7},[1856,1865,1884,1903,1919,1936,1952,1968,1990,2007,2015,2022,2092,2162,2180,2196,2212,2220,2227,2240,2249,2258,2267,2286,2295,2314,2333,2342],{"type":27,"tag":1020,"props":1857,"children":1858},{"class":1022,"line":1023},[1859],{"type":27,"tag":1020,"props":1860,"children":1862},{"style":1861},"--shiki-default:#6A737D",[1863],{"type":33,"value":1864},"// bff/product/getProductView.ts\n",{"type":27,"tag":1020,"props":1866,"children":1867},{"class":1022,"line":20},[1868,1873,1879],{"type":27,"tag":1020,"props":1869,"children":1870},{"style":1650},[1871],{"type":33,"value":1872},"interface",{"type":27,"tag":1020,"props":1874,"children":1876},{"style":1875},"--shiki-default:#B392F0",[1877],{"type":33,"value":1878}," ProductViewModel",{"type":27,"tag":1020,"props":1880,"children":1881},{"style":1670},[1882],{"type":33,"value":1883}," {\n",{"type":27,"tag":1020,"props":1885,"children":1886},{"class":1022,"line":1040},[1887,1893,1898],{"type":27,"tag":1020,"props":1888,"children":1890},{"style":1889},"--shiki-default:#FFAB70",[1891],{"type":33,"value":1892},"  id",{"type":27,"tag":1020,"props":1894,"children":1895},{"style":1650},[1896],{"type":33,"value":1897},":",{"type":27,"tag":1020,"props":1899,"children":1900},{"style":1656},[1901],{"type":33,"value":1902}," string\n",{"type":27,"tag":1020,"props":1904,"children":1905},{"class":1022,"line":1049},[1906,1911,1915],{"type":27,"tag":1020,"props":1907,"children":1908},{"style":1889},[1909],{"type":33,"value":1910},"  title",{"type":27,"tag":1020,"props":1912,"children":1913},{"style":1650},[1914],{"type":33,"value":1897},{"type":27,"tag":1020,"props":1916,"children":1917},{"style":1656},[1918],{"type":33,"value":1902},{"type":27,"tag":1020,"props":1920,"children":1921},{"class":1022,"line":1058},[1922,1927,1931],{"type":27,"tag":1020,"props":1923,"children":1924},{"style":1889},[1925],{"type":33,"value":1926},"  originPrice",{"type":27,"tag":1020,"props":1928,"children":1929},{"style":1650},[1930],{"type":33,"value":1897},{"type":27,"tag":1020,"props":1932,"children":1933},{"style":1656},[1934],{"type":33,"value":1935}," number\n",{"type":27,"tag":1020,"props":1937,"children":1938},{"class":1022,"line":1067},[1939,1944,1948],{"type":27,"tag":1020,"props":1940,"children":1941},{"style":1889},[1942],{"type":33,"value":1943},"  finalPrice",{"type":27,"tag":1020,"props":1945,"children":1946},{"style":1650},[1947],{"type":33,"value":1897},{"type":27,"tag":1020,"props":1949,"children":1950},{"style":1656},[1951],{"type":33,"value":1935},{"type":27,"tag":1020,"props":1953,"children":1954},{"class":1022,"line":1076},[1955,1960,1964],{"type":27,"tag":1020,"props":1956,"children":1957},{"style":1889},[1958],{"type":33,"value":1959},"  inventory",{"type":27,"tag":1020,"props":1961,"children":1962},{"style":1650},[1963],{"type":33,"value":1897},{"type":27,"tag":1020,"props":1965,"children":1966},{"style":1656},[1967],{"type":33,"value":1935},{"type":27,"tag":1020,"props":1969,"children":1970},{"class":1022,"line":1085},[1971,1976,1980,1985],{"type":27,"tag":1020,"props":1972,"children":1973},{"style":1889},[1974],{"type":33,"value":1975},"  promotionTags",{"type":27,"tag":1020,"props":1977,"children":1978},{"style":1650},[1979],{"type":33,"value":1897},{"type":27,"tag":1020,"props":1981,"children":1982},{"style":1656},[1983],{"type":33,"value":1984}," string",{"type":27,"tag":1020,"props":1986,"children":1987},{"style":1670},[1988],{"type":33,"value":1989},"[]\n",{"type":27,"tag":1020,"props":1991,"children":1992},{"class":1022,"line":1094},[1993,1998,2002],{"type":27,"tag":1020,"props":1994,"children":1995},{"style":1889},[1996],{"type":33,"value":1997},"  couponAvailable",{"type":27,"tag":1020,"props":1999,"children":2000},{"style":1650},[2001],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2003,"children":2004},{"style":1656},[2005],{"type":33,"value":2006}," boolean\n",{"type":27,"tag":1020,"props":2008,"children":2009},{"class":1022,"line":1103},[2010],{"type":27,"tag":1020,"props":2011,"children":2012},{"style":1670},[2013],{"type":33,"value":2014},"}\n",{"type":27,"tag":1020,"props":2016,"children":2017},{"class":1022,"line":1112},[2018],{"type":27,"tag":1020,"props":2019,"children":2020},{"emptyLinePlaceholder":18},[2021],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2023,"children":2024},{"class":1022,"line":1121},[2025,2030,2035,2040,2045,2050,2055,2059,2063,2068,2072,2077,2082,2087],{"type":27,"tag":1020,"props":2026,"children":2027},{"style":1650},[2028],{"type":33,"value":2029},"export",{"type":27,"tag":1020,"props":2031,"children":2032},{"style":1650},[2033],{"type":33,"value":2034}," async",{"type":27,"tag":1020,"props":2036,"children":2037},{"style":1650},[2038],{"type":33,"value":2039}," function",{"type":27,"tag":1020,"props":2041,"children":2042},{"style":1875},[2043],{"type":33,"value":2044}," getProductView",{"type":27,"tag":1020,"props":2046,"children":2047},{"style":1670},[2048],{"type":33,"value":2049},"(",{"type":27,"tag":1020,"props":2051,"children":2052},{"style":1889},[2053],{"type":33,"value":2054},"productId",{"type":27,"tag":1020,"props":2056,"children":2057},{"style":1650},[2058],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2060,"children":2061},{"style":1656},[2062],{"type":33,"value":1984},{"type":27,"tag":1020,"props":2064,"children":2065},{"style":1670},[2066],{"type":33,"value":2067},")",{"type":27,"tag":1020,"props":2069,"children":2070},{"style":1650},[2071],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2073,"children":2074},{"style":1875},[2075],{"type":33,"value":2076}," Promise",{"type":27,"tag":1020,"props":2078,"children":2079},{"style":1670},[2080],{"type":33,"value":2081},"\u003C",{"type":27,"tag":1020,"props":2083,"children":2084},{"style":1875},[2085],{"type":33,"value":2086},"ProductViewModel",{"type":27,"tag":1020,"props":2088,"children":2089},{"style":1670},[2090],{"type":33,"value":2091},"> {\n",{"type":27,"tag":1020,"props":2093,"children":2094},{"class":1022,"line":1130},[2095,2100,2105,2110,2115,2119,2123,2128,2133,2138,2143,2147,2152,2157],{"type":27,"tag":1020,"props":2096,"children":2097},{"style":1650},[2098],{"type":33,"value":2099},"  const",{"type":27,"tag":1020,"props":2101,"children":2102},{"style":1670},[2103],{"type":33,"value":2104}," [",{"type":27,"tag":1020,"props":2106,"children":2107},{"style":1656},[2108],{"type":33,"value":2109},"product",{"type":27,"tag":1020,"props":2111,"children":2112},{"style":1670},[2113],{"type":33,"value":2114},", ",{"type":27,"tag":1020,"props":2116,"children":2117},{"style":1656},[2118],{"type":33,"value":1475},{"type":27,"tag":1020,"props":2120,"children":2121},{"style":1670},[2122],{"type":33,"value":2114},{"type":27,"tag":1020,"props":2124,"children":2125},{"style":1656},[2126],{"type":33,"value":2127},"inventory",{"type":27,"tag":1020,"props":2129,"children":2130},{"style":1670},[2131],{"type":33,"value":2132},"] ",{"type":27,"tag":1020,"props":2134,"children":2135},{"style":1650},[2136],{"type":33,"value":2137},"=",{"type":27,"tag":1020,"props":2139,"children":2140},{"style":1650},[2141],{"type":33,"value":2142}," await",{"type":27,"tag":1020,"props":2144,"children":2145},{"style":1656},[2146],{"type":33,"value":2076},{"type":27,"tag":1020,"props":2148,"children":2149},{"style":1670},[2150],{"type":33,"value":2151},".",{"type":27,"tag":1020,"props":2153,"children":2154},{"style":1875},[2155],{"type":33,"value":2156},"all",{"type":27,"tag":1020,"props":2158,"children":2159},{"style":1670},[2160],{"type":33,"value":2161},"([\n",{"type":27,"tag":1020,"props":2163,"children":2164},{"class":1022,"line":1139},[2165,2170,2175],{"type":27,"tag":1020,"props":2166,"children":2167},{"style":1670},[2168],{"type":33,"value":2169},"    productService.",{"type":27,"tag":1020,"props":2171,"children":2172},{"style":1875},[2173],{"type":33,"value":2174},"fetch",{"type":27,"tag":1020,"props":2176,"children":2177},{"style":1670},[2178],{"type":33,"value":2179},"(productId),\n",{"type":27,"tag":1020,"props":2181,"children":2182},{"class":1022,"line":1148},[2183,2188,2192],{"type":27,"tag":1020,"props":2184,"children":2185},{"style":1670},[2186],{"type":33,"value":2187},"    promotionService.",{"type":27,"tag":1020,"props":2189,"children":2190},{"style":1875},[2191],{"type":33,"value":2174},{"type":27,"tag":1020,"props":2193,"children":2194},{"style":1670},[2195],{"type":33,"value":2179},{"type":27,"tag":1020,"props":2197,"children":2198},{"class":1022,"line":21},[2199,2204,2208],{"type":27,"tag":1020,"props":2200,"children":2201},{"style":1670},[2202],{"type":33,"value":2203},"    inventoryService.",{"type":27,"tag":1020,"props":2205,"children":2206},{"style":1875},[2207],{"type":33,"value":2174},{"type":27,"tag":1020,"props":2209,"children":2210},{"style":1670},[2211],{"type":33,"value":2179},{"type":27,"tag":1020,"props":2213,"children":2214},{"class":1022,"line":1165},[2215],{"type":27,"tag":1020,"props":2216,"children":2217},{"style":1670},[2218],{"type":33,"value":2219},"  ])\n",{"type":27,"tag":1020,"props":2221,"children":2222},{"class":1022,"line":1174},[2223],{"type":27,"tag":1020,"props":2224,"children":2225},{"emptyLinePlaceholder":18},[2226],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2228,"children":2230},{"class":1022,"line":2229},19,[2231,2236],{"type":27,"tag":1020,"props":2232,"children":2233},{"style":1650},[2234],{"type":33,"value":2235},"  return",{"type":27,"tag":1020,"props":2237,"children":2238},{"style":1670},[2239],{"type":33,"value":1883},{"type":27,"tag":1020,"props":2241,"children":2243},{"class":1022,"line":2242},20,[2244],{"type":27,"tag":1020,"props":2245,"children":2246},{"style":1670},[2247],{"type":33,"value":2248},"    id: product.id,\n",{"type":27,"tag":1020,"props":2250,"children":2252},{"class":1022,"line":2251},21,[2253],{"type":27,"tag":1020,"props":2254,"children":2255},{"style":1670},[2256],{"type":33,"value":2257},"    title: product.title,\n",{"type":27,"tag":1020,"props":2259,"children":2261},{"class":1022,"line":2260},22,[2262],{"type":27,"tag":1020,"props":2263,"children":2264},{"style":1670},[2265],{"type":33,"value":2266},"    originPrice: product.marketPrice,\n",{"type":27,"tag":1020,"props":2268,"children":2270},{"class":1022,"line":2269},23,[2271,2276,2281],{"type":27,"tag":1020,"props":2272,"children":2273},{"style":1670},[2274],{"type":33,"value":2275},"    finalPrice: ",{"type":27,"tag":1020,"props":2277,"children":2278},{"style":1875},[2279],{"type":33,"value":2280},"resolveFinalPrice",{"type":27,"tag":1020,"props":2282,"children":2283},{"style":1670},[2284],{"type":33,"value":2285},"(product, promotion),\n",{"type":27,"tag":1020,"props":2287,"children":2289},{"class":1022,"line":2288},24,[2290],{"type":27,"tag":1020,"props":2291,"children":2292},{"style":1670},[2293],{"type":33,"value":2294},"    inventory: inventory.available,\n",{"type":27,"tag":1020,"props":2296,"children":2298},{"class":1022,"line":2297},25,[2299,2304,2309],{"type":27,"tag":1020,"props":2300,"children":2301},{"style":1670},[2302],{"type":33,"value":2303},"    promotionTags: ",{"type":27,"tag":1020,"props":2305,"children":2306},{"style":1875},[2307],{"type":33,"value":2308},"resolvePromotionTags",{"type":27,"tag":1020,"props":2310,"children":2311},{"style":1670},[2312],{"type":33,"value":2313},"(promotion),\n",{"type":27,"tag":1020,"props":2315,"children":2317},{"class":1022,"line":2316},26,[2318,2323,2328],{"type":27,"tag":1020,"props":2319,"children":2320},{"style":1670},[2321],{"type":33,"value":2322},"    couponAvailable: ",{"type":27,"tag":1020,"props":2324,"children":2325},{"style":1875},[2326],{"type":33,"value":2327},"Boolean",{"type":27,"tag":1020,"props":2329,"children":2330},{"style":1670},[2331],{"type":33,"value":2332},"(promotion.coupon?.enabled),\n",{"type":27,"tag":1020,"props":2334,"children":2336},{"class":1022,"line":2335},27,[2337],{"type":27,"tag":1020,"props":2338,"children":2339},{"style":1670},[2340],{"type":33,"value":2341},"  }\n",{"type":27,"tag":1020,"props":2343,"children":2345},{"class":1022,"line":2344},28,[2346],{"type":27,"tag":1020,"props":2347,"children":2348},{"style":1670},[2349],{"type":33,"value":2014},{"type":27,"tag":35,"props":2351,"children":2352},{},[2353],{"type":33,"value":2354},"这个改动的意义，不在于“代码更漂亮”，而在于职责被重新划分了：",{"type":27,"tag":83,"props":2356,"children":2357},{},[2358,2363,2368],{"type":27,"tag":87,"props":2359,"children":2360},{},[2361],{"type":33,"value":2362},"后端异构 -> BFF 负责消化",{"type":27,"tag":87,"props":2364,"children":2365},{},[2366],{"type":33,"value":2367},"领域规则 -> facade 负责封装",{"type":27,"tag":87,"props":2369,"children":2370},{},[2371],{"type":33,"value":2372},"页面 -> 只拿标准结果渲染",{"type":27,"tag":35,"props":2374,"children":2375},{},[2376],{"type":33,"value":2377},"这一步做完，前端页面复杂度立刻下降了一截。",{"type":27,"tag":125,"props":2379,"children":2380},{},[],{"type":27,"tag":129,"props":2382,"children":2384},{"id":2383},"六第二刀把价格逻辑从页面里剥出来",[2385],{"type":33,"value":2386},"六、第二刀：把“价格逻辑”从页面里剥出来",{"type":27,"tag":141,"props":2388,"children":2390},{"id":2389},"决策点-6先抽变化频繁且最容易出事故的规则",[2391],{"type":33,"value":2392},"决策点 6：先抽“变化频繁且最容易出事故”的规则",{"type":27,"tag":35,"props":2394,"children":2395},{},[2396],{"type":33,"value":2397},"我们统计了过去 2 个月的 bug，发现价格相关占了 37%。",{"type":27,"tag":35,"props":2399,"children":2400},{},[2401,2403,2408],{"type":33,"value":2402},"所以第二刀，切的是 ",{"type":27,"tag":51,"props":2404,"children":2406},{"className":2405},[],[2407],{"type":33,"value":1446},{"type":33,"value":76},{"type":27,"tag":141,"props":2410,"children":2412},{"id":2411},"_61-旧实现的问题",[2413],{"type":33,"value":2414},"6.1 旧实现的问题",{"type":27,"tag":35,"props":2416,"children":2417},{},[2418],{"type":33,"value":2419},"旧代码把这些规则都揉在页面里：",{"type":27,"tag":83,"props":2421,"children":2422},{},[2423,2428,2433,2438,2443],{"type":27,"tag":87,"props":2424,"children":2425},{},[2426],{"type":33,"value":2427},"原价 / 到手价展示",{"type":27,"tag":87,"props":2429,"children":2430},{},[2431],{"type":33,"value":2432},"会员价优先级",{"type":27,"tag":87,"props":2434,"children":2435},{},[2436],{"type":33,"value":2437},"限时活动覆盖逻辑",{"type":27,"tag":87,"props":2439,"children":2440},{},[2441],{"type":33,"value":2442},"优惠券可叠加规则",{"type":27,"tag":87,"props":2444,"children":2445},{},[2446],{"type":33,"value":2447},"埋点打点",{"type":27,"tag":35,"props":2449,"children":2450},{},[2451],{"type":33,"value":2452},"结果就是：",{"type":27,"tag":83,"props":2454,"children":2455},{},[2456,2461,2466],{"type":27,"tag":87,"props":2457,"children":2458},{},[2459],{"type":33,"value":2460},"任何一个价格逻辑变更，都要碰 UI",{"type":27,"tag":87,"props":2462,"children":2463},{},[2464],{"type":33,"value":2465},"同一套规则在详情页、购物车、结算页写了 3 次",{"type":27,"tag":87,"props":2467,"children":2468},{},[2469],{"type":33,"value":2470},"测试只能靠手点",{"type":27,"tag":141,"props":2472,"children":2474},{"id":2473},"_62-新实现定价规则内聚到领域模块",[2475],{"type":33,"value":2476},"6.2 新实现：定价规则内聚到领域模块",{"type":27,"tag":1011,"props":2478,"children":2480},{"className":1638,"code":2479,"language":1640,"meta":7,"style":7},"// features/pricing/domain/resolvePrice.ts\nexport interface PriceContext {\n  basePrice: number\n  memberPrice?: number\n  flashSalePrice?: number\n  couponDiscount?: number\n  isMember: boolean\n  now: number\n  flashSaleStartAt?: number\n  flashSaleEndAt?: number\n}\n\nexport function resolvePrice(ctx: PriceContext) {\n  const inFlashSale =\n    ctx.flashSalePrice !== undefined &&\n    ctx.flashSaleStartAt !== undefined &&\n    ctx.flashSaleEndAt !== undefined &&\n    ctx.now >= ctx.flashSaleStartAt &&\n    ctx.now \u003C= ctx.flashSaleEndAt\n\n  let current = ctx.basePrice\n  let source = 'base'\n\n  if (ctx.isMember && ctx.memberPrice !== undefined && ctx.memberPrice \u003C current) {\n    current = ctx.memberPrice\n    source = 'member'\n  }\n\n  if (inFlashSale && ctx.flashSalePrice! \u003C current) {\n    current = ctx.flashSalePrice!\n    source = 'flash-sale'\n  }\n\n  if (ctx.couponDiscount) {\n    current = Math.max(0, current - ctx.couponDiscount)\n  }\n\n  return {\n    finalPrice: current,\n    source,\n    savedAmount: Math.max(0, ctx.basePrice - current),\n  }\n}\n",[2481],{"type":27,"tag":51,"props":2482,"children":2483},{"__ignoreMap":7},[2484,2492,2513,2529,2546,2562,2578,2594,2610,2626,2642,2649,2656,2694,2710,2733,2753,2773,2796,2813,2820,2842,2864,2871,2920,2937,2954,2961,2968,3004,3025,3042,3050,3058,3071,3117,3125,3133,3145,3154,3163,3198,3206],{"type":27,"tag":1020,"props":2485,"children":2486},{"class":1022,"line":1023},[2487],{"type":27,"tag":1020,"props":2488,"children":2489},{"style":1861},[2490],{"type":33,"value":2491},"// features/pricing/domain/resolvePrice.ts\n",{"type":27,"tag":1020,"props":2493,"children":2494},{"class":1022,"line":20},[2495,2499,2504,2509],{"type":27,"tag":1020,"props":2496,"children":2497},{"style":1650},[2498],{"type":33,"value":2029},{"type":27,"tag":1020,"props":2500,"children":2501},{"style":1650},[2502],{"type":33,"value":2503}," interface",{"type":27,"tag":1020,"props":2505,"children":2506},{"style":1875},[2507],{"type":33,"value":2508}," PriceContext",{"type":27,"tag":1020,"props":2510,"children":2511},{"style":1670},[2512],{"type":33,"value":1883},{"type":27,"tag":1020,"props":2514,"children":2515},{"class":1022,"line":1040},[2516,2521,2525],{"type":27,"tag":1020,"props":2517,"children":2518},{"style":1889},[2519],{"type":33,"value":2520},"  basePrice",{"type":27,"tag":1020,"props":2522,"children":2523},{"style":1650},[2524],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2526,"children":2527},{"style":1656},[2528],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2530,"children":2531},{"class":1022,"line":1049},[2532,2537,2542],{"type":27,"tag":1020,"props":2533,"children":2534},{"style":1889},[2535],{"type":33,"value":2536},"  memberPrice",{"type":27,"tag":1020,"props":2538,"children":2539},{"style":1650},[2540],{"type":33,"value":2541},"?:",{"type":27,"tag":1020,"props":2543,"children":2544},{"style":1656},[2545],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2547,"children":2548},{"class":1022,"line":1058},[2549,2554,2558],{"type":27,"tag":1020,"props":2550,"children":2551},{"style":1889},[2552],{"type":33,"value":2553},"  flashSalePrice",{"type":27,"tag":1020,"props":2555,"children":2556},{"style":1650},[2557],{"type":33,"value":2541},{"type":27,"tag":1020,"props":2559,"children":2560},{"style":1656},[2561],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2563,"children":2564},{"class":1022,"line":1067},[2565,2570,2574],{"type":27,"tag":1020,"props":2566,"children":2567},{"style":1889},[2568],{"type":33,"value":2569},"  couponDiscount",{"type":27,"tag":1020,"props":2571,"children":2572},{"style":1650},[2573],{"type":33,"value":2541},{"type":27,"tag":1020,"props":2575,"children":2576},{"style":1656},[2577],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2579,"children":2580},{"class":1022,"line":1076},[2581,2586,2590],{"type":27,"tag":1020,"props":2582,"children":2583},{"style":1889},[2584],{"type":33,"value":2585},"  isMember",{"type":27,"tag":1020,"props":2587,"children":2588},{"style":1650},[2589],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2591,"children":2592},{"style":1656},[2593],{"type":33,"value":2006},{"type":27,"tag":1020,"props":2595,"children":2596},{"class":1022,"line":1085},[2597,2602,2606],{"type":27,"tag":1020,"props":2598,"children":2599},{"style":1889},[2600],{"type":33,"value":2601},"  now",{"type":27,"tag":1020,"props":2603,"children":2604},{"style":1650},[2605],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2607,"children":2608},{"style":1656},[2609],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2611,"children":2612},{"class":1022,"line":1094},[2613,2618,2622],{"type":27,"tag":1020,"props":2614,"children":2615},{"style":1889},[2616],{"type":33,"value":2617},"  flashSaleStartAt",{"type":27,"tag":1020,"props":2619,"children":2620},{"style":1650},[2621],{"type":33,"value":2541},{"type":27,"tag":1020,"props":2623,"children":2624},{"style":1656},[2625],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2627,"children":2628},{"class":1022,"line":1103},[2629,2634,2638],{"type":27,"tag":1020,"props":2630,"children":2631},{"style":1889},[2632],{"type":33,"value":2633},"  flashSaleEndAt",{"type":27,"tag":1020,"props":2635,"children":2636},{"style":1650},[2637],{"type":33,"value":2541},{"type":27,"tag":1020,"props":2639,"children":2640},{"style":1656},[2641],{"type":33,"value":1935},{"type":27,"tag":1020,"props":2643,"children":2644},{"class":1022,"line":1112},[2645],{"type":27,"tag":1020,"props":2646,"children":2647},{"style":1670},[2648],{"type":33,"value":2014},{"type":27,"tag":1020,"props":2650,"children":2651},{"class":1022,"line":1121},[2652],{"type":27,"tag":1020,"props":2653,"children":2654},{"emptyLinePlaceholder":18},[2655],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2657,"children":2658},{"class":1022,"line":1130},[2659,2663,2667,2672,2676,2681,2685,2689],{"type":27,"tag":1020,"props":2660,"children":2661},{"style":1650},[2662],{"type":33,"value":2029},{"type":27,"tag":1020,"props":2664,"children":2665},{"style":1650},[2666],{"type":33,"value":2039},{"type":27,"tag":1020,"props":2668,"children":2669},{"style":1875},[2670],{"type":33,"value":2671}," resolvePrice",{"type":27,"tag":1020,"props":2673,"children":2674},{"style":1670},[2675],{"type":33,"value":2049},{"type":27,"tag":1020,"props":2677,"children":2678},{"style":1889},[2679],{"type":33,"value":2680},"ctx",{"type":27,"tag":1020,"props":2682,"children":2683},{"style":1650},[2684],{"type":33,"value":1897},{"type":27,"tag":1020,"props":2686,"children":2687},{"style":1875},[2688],{"type":33,"value":2508},{"type":27,"tag":1020,"props":2690,"children":2691},{"style":1670},[2692],{"type":33,"value":2693},") {\n",{"type":27,"tag":1020,"props":2695,"children":2696},{"class":1022,"line":1139},[2697,2701,2706],{"type":27,"tag":1020,"props":2698,"children":2699},{"style":1650},[2700],{"type":33,"value":2099},{"type":27,"tag":1020,"props":2702,"children":2703},{"style":1656},[2704],{"type":33,"value":2705}," inFlashSale",{"type":27,"tag":1020,"props":2707,"children":2708},{"style":1650},[2709],{"type":33,"value":1664},{"type":27,"tag":1020,"props":2711,"children":2712},{"class":1022,"line":1148},[2713,2718,2723,2728],{"type":27,"tag":1020,"props":2714,"children":2715},{"style":1670},[2716],{"type":33,"value":2717},"    ctx.flashSalePrice ",{"type":27,"tag":1020,"props":2719,"children":2720},{"style":1650},[2721],{"type":33,"value":2722},"!==",{"type":27,"tag":1020,"props":2724,"children":2725},{"style":1656},[2726],{"type":33,"value":2727}," undefined",{"type":27,"tag":1020,"props":2729,"children":2730},{"style":1650},[2731],{"type":33,"value":2732}," &&\n",{"type":27,"tag":1020,"props":2734,"children":2735},{"class":1022,"line":21},[2736,2741,2745,2749],{"type":27,"tag":1020,"props":2737,"children":2738},{"style":1670},[2739],{"type":33,"value":2740},"    ctx.flashSaleStartAt ",{"type":27,"tag":1020,"props":2742,"children":2743},{"style":1650},[2744],{"type":33,"value":2722},{"type":27,"tag":1020,"props":2746,"children":2747},{"style":1656},[2748],{"type":33,"value":2727},{"type":27,"tag":1020,"props":2750,"children":2751},{"style":1650},[2752],{"type":33,"value":2732},{"type":27,"tag":1020,"props":2754,"children":2755},{"class":1022,"line":1165},[2756,2761,2765,2769],{"type":27,"tag":1020,"props":2757,"children":2758},{"style":1670},[2759],{"type":33,"value":2760},"    ctx.flashSaleEndAt ",{"type":27,"tag":1020,"props":2762,"children":2763},{"style":1650},[2764],{"type":33,"value":2722},{"type":27,"tag":1020,"props":2766,"children":2767},{"style":1656},[2768],{"type":33,"value":2727},{"type":27,"tag":1020,"props":2770,"children":2771},{"style":1650},[2772],{"type":33,"value":2732},{"type":27,"tag":1020,"props":2774,"children":2775},{"class":1022,"line":1174},[2776,2781,2786,2791],{"type":27,"tag":1020,"props":2777,"children":2778},{"style":1670},[2779],{"type":33,"value":2780},"    ctx.now ",{"type":27,"tag":1020,"props":2782,"children":2783},{"style":1650},[2784],{"type":33,"value":2785},">=",{"type":27,"tag":1020,"props":2787,"children":2788},{"style":1670},[2789],{"type":33,"value":2790}," ctx.flashSaleStartAt ",{"type":27,"tag":1020,"props":2792,"children":2793},{"style":1650},[2794],{"type":33,"value":2795},"&&\n",{"type":27,"tag":1020,"props":2797,"children":2798},{"class":1022,"line":2229},[2799,2803,2808],{"type":27,"tag":1020,"props":2800,"children":2801},{"style":1670},[2802],{"type":33,"value":2780},{"type":27,"tag":1020,"props":2804,"children":2805},{"style":1650},[2806],{"type":33,"value":2807},"\u003C=",{"type":27,"tag":1020,"props":2809,"children":2810},{"style":1670},[2811],{"type":33,"value":2812}," ctx.flashSaleEndAt\n",{"type":27,"tag":1020,"props":2814,"children":2815},{"class":1022,"line":2242},[2816],{"type":27,"tag":1020,"props":2817,"children":2818},{"emptyLinePlaceholder":18},[2819],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2821,"children":2822},{"class":1022,"line":2251},[2823,2828,2833,2837],{"type":27,"tag":1020,"props":2824,"children":2825},{"style":1650},[2826],{"type":33,"value":2827},"  let",{"type":27,"tag":1020,"props":2829,"children":2830},{"style":1670},[2831],{"type":33,"value":2832}," current ",{"type":27,"tag":1020,"props":2834,"children":2835},{"style":1650},[2836],{"type":33,"value":2137},{"type":27,"tag":1020,"props":2838,"children":2839},{"style":1670},[2840],{"type":33,"value":2841}," ctx.basePrice\n",{"type":27,"tag":1020,"props":2843,"children":2844},{"class":1022,"line":2260},[2845,2849,2854,2858],{"type":27,"tag":1020,"props":2846,"children":2847},{"style":1650},[2848],{"type":33,"value":2827},{"type":27,"tag":1020,"props":2850,"children":2851},{"style":1670},[2852],{"type":33,"value":2853}," source ",{"type":27,"tag":1020,"props":2855,"children":2856},{"style":1650},[2857],{"type":33,"value":2137},{"type":27,"tag":1020,"props":2859,"children":2861},{"style":2860},"--shiki-default:#9ECBFF",[2862],{"type":33,"value":2863}," 'base'\n",{"type":27,"tag":1020,"props":2865,"children":2866},{"class":1022,"line":2269},[2867],{"type":27,"tag":1020,"props":2868,"children":2869},{"emptyLinePlaceholder":18},[2870],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2872,"children":2873},{"class":1022,"line":2288},[2874,2879,2884,2889,2894,2898,2902,2907,2911,2915],{"type":27,"tag":1020,"props":2875,"children":2876},{"style":1650},[2877],{"type":33,"value":2878},"  if",{"type":27,"tag":1020,"props":2880,"children":2881},{"style":1670},[2882],{"type":33,"value":2883}," (ctx.isMember ",{"type":27,"tag":1020,"props":2885,"children":2886},{"style":1650},[2887],{"type":33,"value":2888},"&&",{"type":27,"tag":1020,"props":2890,"children":2891},{"style":1670},[2892],{"type":33,"value":2893}," ctx.memberPrice ",{"type":27,"tag":1020,"props":2895,"children":2896},{"style":1650},[2897],{"type":33,"value":2722},{"type":27,"tag":1020,"props":2899,"children":2900},{"style":1656},[2901],{"type":33,"value":2727},{"type":27,"tag":1020,"props":2903,"children":2904},{"style":1650},[2905],{"type":33,"value":2906}," &&",{"type":27,"tag":1020,"props":2908,"children":2909},{"style":1670},[2910],{"type":33,"value":2893},{"type":27,"tag":1020,"props":2912,"children":2913},{"style":1650},[2914],{"type":33,"value":2081},{"type":27,"tag":1020,"props":2916,"children":2917},{"style":1670},[2918],{"type":33,"value":2919}," current) {\n",{"type":27,"tag":1020,"props":2921,"children":2922},{"class":1022,"line":2297},[2923,2928,2932],{"type":27,"tag":1020,"props":2924,"children":2925},{"style":1670},[2926],{"type":33,"value":2927},"    current ",{"type":27,"tag":1020,"props":2929,"children":2930},{"style":1650},[2931],{"type":33,"value":2137},{"type":27,"tag":1020,"props":2933,"children":2934},{"style":1670},[2935],{"type":33,"value":2936}," ctx.memberPrice\n",{"type":27,"tag":1020,"props":2938,"children":2939},{"class":1022,"line":2316},[2940,2945,2949],{"type":27,"tag":1020,"props":2941,"children":2942},{"style":1670},[2943],{"type":33,"value":2944},"    source ",{"type":27,"tag":1020,"props":2946,"children":2947},{"style":1650},[2948],{"type":33,"value":2137},{"type":27,"tag":1020,"props":2950,"children":2951},{"style":2860},[2952],{"type":33,"value":2953}," 'member'\n",{"type":27,"tag":1020,"props":2955,"children":2956},{"class":1022,"line":2335},[2957],{"type":27,"tag":1020,"props":2958,"children":2959},{"style":1670},[2960],{"type":33,"value":2341},{"type":27,"tag":1020,"props":2962,"children":2963},{"class":1022,"line":2344},[2964],{"type":27,"tag":1020,"props":2965,"children":2966},{"emptyLinePlaceholder":18},[2967],{"type":33,"value":1718},{"type":27,"tag":1020,"props":2969,"children":2971},{"class":1022,"line":2970},29,[2972,2976,2981,2985,2990,2995,3000],{"type":27,"tag":1020,"props":2973,"children":2974},{"style":1650},[2975],{"type":33,"value":2878},{"type":27,"tag":1020,"props":2977,"children":2978},{"style":1670},[2979],{"type":33,"value":2980}," (inFlashSale ",{"type":27,"tag":1020,"props":2982,"children":2983},{"style":1650},[2984],{"type":33,"value":2888},{"type":27,"tag":1020,"props":2986,"children":2987},{"style":1670},[2988],{"type":33,"value":2989}," ctx.flashSalePrice",{"type":27,"tag":1020,"props":2991,"children":2992},{"style":1650},[2993],{"type":33,"value":2994},"!",{"type":27,"tag":1020,"props":2996,"children":2997},{"style":1650},[2998],{"type":33,"value":2999}," \u003C",{"type":27,"tag":1020,"props":3001,"children":3002},{"style":1670},[3003],{"type":33,"value":2919},{"type":27,"tag":1020,"props":3005,"children":3007},{"class":1022,"line":3006},30,[3008,3012,3016,3020],{"type":27,"tag":1020,"props":3009,"children":3010},{"style":1670},[3011],{"type":33,"value":2927},{"type":27,"tag":1020,"props":3013,"children":3014},{"style":1650},[3015],{"type":33,"value":2137},{"type":27,"tag":1020,"props":3017,"children":3018},{"style":1670},[3019],{"type":33,"value":2989},{"type":27,"tag":1020,"props":3021,"children":3022},{"style":1650},[3023],{"type":33,"value":3024},"!\n",{"type":27,"tag":1020,"props":3026,"children":3028},{"class":1022,"line":3027},31,[3029,3033,3037],{"type":27,"tag":1020,"props":3030,"children":3031},{"style":1670},[3032],{"type":33,"value":2944},{"type":27,"tag":1020,"props":3034,"children":3035},{"style":1650},[3036],{"type":33,"value":2137},{"type":27,"tag":1020,"props":3038,"children":3039},{"style":2860},[3040],{"type":33,"value":3041}," 'flash-sale'\n",{"type":27,"tag":1020,"props":3043,"children":3045},{"class":1022,"line":3044},32,[3046],{"type":27,"tag":1020,"props":3047,"children":3048},{"style":1670},[3049],{"type":33,"value":2341},{"type":27,"tag":1020,"props":3051,"children":3053},{"class":1022,"line":3052},33,[3054],{"type":27,"tag":1020,"props":3055,"children":3056},{"emptyLinePlaceholder":18},[3057],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3059,"children":3061},{"class":1022,"line":3060},34,[3062,3066],{"type":27,"tag":1020,"props":3063,"children":3064},{"style":1650},[3065],{"type":33,"value":2878},{"type":27,"tag":1020,"props":3067,"children":3068},{"style":1670},[3069],{"type":33,"value":3070}," (ctx.couponDiscount) {\n",{"type":27,"tag":1020,"props":3072,"children":3074},{"class":1022,"line":3073},35,[3075,3079,3083,3088,3093,3097,3102,3107,3112],{"type":27,"tag":1020,"props":3076,"children":3077},{"style":1670},[3078],{"type":33,"value":2927},{"type":27,"tag":1020,"props":3080,"children":3081},{"style":1650},[3082],{"type":33,"value":2137},{"type":27,"tag":1020,"props":3084,"children":3085},{"style":1670},[3086],{"type":33,"value":3087}," Math.",{"type":27,"tag":1020,"props":3089,"children":3090},{"style":1875},[3091],{"type":33,"value":3092},"max",{"type":27,"tag":1020,"props":3094,"children":3095},{"style":1670},[3096],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3098,"children":3099},{"style":1656},[3100],{"type":33,"value":3101},"0",{"type":27,"tag":1020,"props":3103,"children":3104},{"style":1670},[3105],{"type":33,"value":3106},", current ",{"type":27,"tag":1020,"props":3108,"children":3109},{"style":1650},[3110],{"type":33,"value":3111},"-",{"type":27,"tag":1020,"props":3113,"children":3114},{"style":1670},[3115],{"type":33,"value":3116}," ctx.couponDiscount)\n",{"type":27,"tag":1020,"props":3118,"children":3120},{"class":1022,"line":3119},36,[3121],{"type":27,"tag":1020,"props":3122,"children":3123},{"style":1670},[3124],{"type":33,"value":2341},{"type":27,"tag":1020,"props":3126,"children":3128},{"class":1022,"line":3127},37,[3129],{"type":27,"tag":1020,"props":3130,"children":3131},{"emptyLinePlaceholder":18},[3132],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3134,"children":3136},{"class":1022,"line":3135},38,[3137,3141],{"type":27,"tag":1020,"props":3138,"children":3139},{"style":1650},[3140],{"type":33,"value":2235},{"type":27,"tag":1020,"props":3142,"children":3143},{"style":1670},[3144],{"type":33,"value":1883},{"type":27,"tag":1020,"props":3146,"children":3148},{"class":1022,"line":3147},39,[3149],{"type":27,"tag":1020,"props":3150,"children":3151},{"style":1670},[3152],{"type":33,"value":3153},"    finalPrice: current,\n",{"type":27,"tag":1020,"props":3155,"children":3157},{"class":1022,"line":3156},40,[3158],{"type":27,"tag":1020,"props":3159,"children":3160},{"style":1670},[3161],{"type":33,"value":3162},"    source,\n",{"type":27,"tag":1020,"props":3164,"children":3166},{"class":1022,"line":3165},41,[3167,3172,3176,3180,3184,3189,3193],{"type":27,"tag":1020,"props":3168,"children":3169},{"style":1670},[3170],{"type":33,"value":3171},"    savedAmount: Math.",{"type":27,"tag":1020,"props":3173,"children":3174},{"style":1875},[3175],{"type":33,"value":3092},{"type":27,"tag":1020,"props":3177,"children":3178},{"style":1670},[3179],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3181,"children":3182},{"style":1656},[3183],{"type":33,"value":3101},{"type":27,"tag":1020,"props":3185,"children":3186},{"style":1670},[3187],{"type":33,"value":3188},", ctx.basePrice ",{"type":27,"tag":1020,"props":3190,"children":3191},{"style":1650},[3192],{"type":33,"value":3111},{"type":27,"tag":1020,"props":3194,"children":3195},{"style":1670},[3196],{"type":33,"value":3197}," current),\n",{"type":27,"tag":1020,"props":3199,"children":3201},{"class":1022,"line":3200},42,[3202],{"type":27,"tag":1020,"props":3203,"children":3204},{"style":1670},[3205],{"type":33,"value":2341},{"type":27,"tag":1020,"props":3207,"children":3209},{"class":1022,"line":3208},43,[3210],{"type":27,"tag":1020,"props":3211,"children":3212},{"style":1670},[3213],{"type":33,"value":2014},{"type":27,"tag":35,"props":3215,"children":3216},{},[3217],{"type":33,"value":3218},"这样做带来了 3 个直接收益：",{"type":27,"tag":153,"props":3220,"children":3221},{},[3222,3227,3232],{"type":27,"tag":87,"props":3223,"children":3224},{},[3225],{"type":33,"value":3226},"页面不再理解复杂价格优先级",{"type":27,"tag":87,"props":3228,"children":3229},{},[3230],{"type":33,"value":3231},"购物车和结算页可直接复用同一规则",{"type":27,"tag":87,"props":3233,"children":3234},{},[3235],{"type":33,"value":3236},"可以把最容易出事故的逻辑做成纯函数测试",{"type":27,"tag":141,"props":3238,"children":3240},{"id":3239},"_63-配套测试不是可选项",[3241],{"type":33,"value":3242},"6.3 配套测试不是“可选项”",{"type":27,"tag":1011,"props":3244,"children":3246},{"className":1638,"code":3245,"language":1640,"meta":7,"style":7},"// features/pricing/domain/resolvePrice.spec.ts\nimport { describe, expect, it } from 'vitest'\nimport { resolvePrice } from './resolvePrice'\n\ndescribe('resolvePrice', () => {\n  it('会员价低于原价时应优先生效', () => {\n    const result = resolvePrice({\n      basePrice: 3999,\n      memberPrice: 3699,\n      isMember: true,\n      now: Date.now(),\n    })\n\n    expect(result.finalPrice).toBe(3699)\n    expect(result.source).toBe('member')\n  })\n\n  it('限时活动价低于会员价时应覆盖会员价', () => {\n    const now = Date.now()\n    const result = resolvePrice({\n      basePrice: 3999,\n      memberPrice: 3699,\n      flashSalePrice: 3499,\n      flashSaleStartAt: now - 1000,\n      flashSaleEndAt: now + 1000,\n      isMember: true,\n      now,\n    })\n\n    expect(result.finalPrice).toBe(3499)\n    expect(result.source).toBe('flash-sale')\n  })\n})\n",[3247],{"type":27,"tag":51,"props":3248,"children":3249},{"__ignoreMap":7},[3250,3258,3281,3302,3309,3340,3369,3395,3413,3430,3447,3465,3473,3480,3511,3540,3548,3555,3583,3613,3636,3651,3666,3683,3704,3725,3740,3748,3755,3762,3789,3817,3824],{"type":27,"tag":1020,"props":3251,"children":3252},{"class":1022,"line":1023},[3253],{"type":27,"tag":1020,"props":3254,"children":3255},{"style":1861},[3256],{"type":33,"value":3257},"// features/pricing/domain/resolvePrice.spec.ts\n",{"type":27,"tag":1020,"props":3259,"children":3260},{"class":1022,"line":20},[3261,3266,3271,3276],{"type":27,"tag":1020,"props":3262,"children":3263},{"style":1650},[3264],{"type":33,"value":3265},"import",{"type":27,"tag":1020,"props":3267,"children":3268},{"style":1670},[3269],{"type":33,"value":3270}," { describe, expect, it } ",{"type":27,"tag":1020,"props":3272,"children":3273},{"style":1650},[3274],{"type":33,"value":3275},"from",{"type":27,"tag":1020,"props":3277,"children":3278},{"style":2860},[3279],{"type":33,"value":3280}," 'vitest'\n",{"type":27,"tag":1020,"props":3282,"children":3283},{"class":1022,"line":1040},[3284,3288,3293,3297],{"type":27,"tag":1020,"props":3285,"children":3286},{"style":1650},[3287],{"type":33,"value":3265},{"type":27,"tag":1020,"props":3289,"children":3290},{"style":1670},[3291],{"type":33,"value":3292}," { resolvePrice } ",{"type":27,"tag":1020,"props":3294,"children":3295},{"style":1650},[3296],{"type":33,"value":3275},{"type":27,"tag":1020,"props":3298,"children":3299},{"style":2860},[3300],{"type":33,"value":3301}," './resolvePrice'\n",{"type":27,"tag":1020,"props":3303,"children":3304},{"class":1022,"line":1049},[3305],{"type":27,"tag":1020,"props":3306,"children":3307},{"emptyLinePlaceholder":18},[3308],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3310,"children":3311},{"class":1022,"line":1058},[3312,3317,3321,3326,3331,3336],{"type":27,"tag":1020,"props":3313,"children":3314},{"style":1875},[3315],{"type":33,"value":3316},"describe",{"type":27,"tag":1020,"props":3318,"children":3319},{"style":1670},[3320],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3322,"children":3323},{"style":2860},[3324],{"type":33,"value":3325},"'resolvePrice'",{"type":27,"tag":1020,"props":3327,"children":3328},{"style":1670},[3329],{"type":33,"value":3330},", () ",{"type":27,"tag":1020,"props":3332,"children":3333},{"style":1650},[3334],{"type":33,"value":3335},"=>",{"type":27,"tag":1020,"props":3337,"children":3338},{"style":1670},[3339],{"type":33,"value":1883},{"type":27,"tag":1020,"props":3341,"children":3342},{"class":1022,"line":1067},[3343,3348,3352,3357,3361,3365],{"type":27,"tag":1020,"props":3344,"children":3345},{"style":1875},[3346],{"type":33,"value":3347},"  it",{"type":27,"tag":1020,"props":3349,"children":3350},{"style":1670},[3351],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3353,"children":3354},{"style":2860},[3355],{"type":33,"value":3356},"'会员价低于原价时应优先生效'",{"type":27,"tag":1020,"props":3358,"children":3359},{"style":1670},[3360],{"type":33,"value":3330},{"type":27,"tag":1020,"props":3362,"children":3363},{"style":1650},[3364],{"type":33,"value":3335},{"type":27,"tag":1020,"props":3366,"children":3367},{"style":1670},[3368],{"type":33,"value":1883},{"type":27,"tag":1020,"props":3370,"children":3371},{"class":1022,"line":1076},[3372,3377,3382,3386,3390],{"type":27,"tag":1020,"props":3373,"children":3374},{"style":1650},[3375],{"type":33,"value":3376},"    const",{"type":27,"tag":1020,"props":3378,"children":3379},{"style":1656},[3380],{"type":33,"value":3381}," result",{"type":27,"tag":1020,"props":3383,"children":3384},{"style":1650},[3385],{"type":33,"value":1735},{"type":27,"tag":1020,"props":3387,"children":3388},{"style":1875},[3389],{"type":33,"value":2671},{"type":27,"tag":1020,"props":3391,"children":3392},{"style":1670},[3393],{"type":33,"value":3394},"({\n",{"type":27,"tag":1020,"props":3396,"children":3397},{"class":1022,"line":1085},[3398,3403,3408],{"type":27,"tag":1020,"props":3399,"children":3400},{"style":1670},[3401],{"type":33,"value":3402},"      basePrice: ",{"type":27,"tag":1020,"props":3404,"children":3405},{"style":1656},[3406],{"type":33,"value":3407},"3999",{"type":27,"tag":1020,"props":3409,"children":3410},{"style":1670},[3411],{"type":33,"value":3412},",\n",{"type":27,"tag":1020,"props":3414,"children":3415},{"class":1022,"line":1094},[3416,3421,3426],{"type":27,"tag":1020,"props":3417,"children":3418},{"style":1670},[3419],{"type":33,"value":3420},"      memberPrice: ",{"type":27,"tag":1020,"props":3422,"children":3423},{"style":1656},[3424],{"type":33,"value":3425},"3699",{"type":27,"tag":1020,"props":3427,"children":3428},{"style":1670},[3429],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3431,"children":3432},{"class":1022,"line":1103},[3433,3438,3443],{"type":27,"tag":1020,"props":3434,"children":3435},{"style":1670},[3436],{"type":33,"value":3437},"      isMember: ",{"type":27,"tag":1020,"props":3439,"children":3440},{"style":1656},[3441],{"type":33,"value":3442},"true",{"type":27,"tag":1020,"props":3444,"children":3445},{"style":1670},[3446],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3448,"children":3449},{"class":1022,"line":1112},[3450,3455,3460],{"type":27,"tag":1020,"props":3451,"children":3452},{"style":1670},[3453],{"type":33,"value":3454},"      now: Date.",{"type":27,"tag":1020,"props":3456,"children":3457},{"style":1875},[3458],{"type":33,"value":3459},"now",{"type":27,"tag":1020,"props":3461,"children":3462},{"style":1670},[3463],{"type":33,"value":3464},"(),\n",{"type":27,"tag":1020,"props":3466,"children":3467},{"class":1022,"line":1121},[3468],{"type":27,"tag":1020,"props":3469,"children":3470},{"style":1670},[3471],{"type":33,"value":3472},"    })\n",{"type":27,"tag":1020,"props":3474,"children":3475},{"class":1022,"line":1130},[3476],{"type":27,"tag":1020,"props":3477,"children":3478},{"emptyLinePlaceholder":18},[3479],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3481,"children":3482},{"class":1022,"line":1139},[3483,3488,3493,3498,3502,3506],{"type":27,"tag":1020,"props":3484,"children":3485},{"style":1875},[3486],{"type":33,"value":3487},"    expect",{"type":27,"tag":1020,"props":3489,"children":3490},{"style":1670},[3491],{"type":33,"value":3492},"(result.finalPrice).",{"type":27,"tag":1020,"props":3494,"children":3495},{"style":1875},[3496],{"type":33,"value":3497},"toBe",{"type":27,"tag":1020,"props":3499,"children":3500},{"style":1670},[3501],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3503,"children":3504},{"style":1656},[3505],{"type":33,"value":3425},{"type":27,"tag":1020,"props":3507,"children":3508},{"style":1670},[3509],{"type":33,"value":3510},")\n",{"type":27,"tag":1020,"props":3512,"children":3513},{"class":1022,"line":1148},[3514,3518,3523,3527,3531,3536],{"type":27,"tag":1020,"props":3515,"children":3516},{"style":1875},[3517],{"type":33,"value":3487},{"type":27,"tag":1020,"props":3519,"children":3520},{"style":1670},[3521],{"type":33,"value":3522},"(result.source).",{"type":27,"tag":1020,"props":3524,"children":3525},{"style":1875},[3526],{"type":33,"value":3497},{"type":27,"tag":1020,"props":3528,"children":3529},{"style":1670},[3530],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3532,"children":3533},{"style":2860},[3534],{"type":33,"value":3535},"'member'",{"type":27,"tag":1020,"props":3537,"children":3538},{"style":1670},[3539],{"type":33,"value":3510},{"type":27,"tag":1020,"props":3541,"children":3542},{"class":1022,"line":21},[3543],{"type":27,"tag":1020,"props":3544,"children":3545},{"style":1670},[3546],{"type":33,"value":3547},"  })\n",{"type":27,"tag":1020,"props":3549,"children":3550},{"class":1022,"line":1165},[3551],{"type":27,"tag":1020,"props":3552,"children":3553},{"emptyLinePlaceholder":18},[3554],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3556,"children":3557},{"class":1022,"line":1174},[3558,3562,3566,3571,3575,3579],{"type":27,"tag":1020,"props":3559,"children":3560},{"style":1875},[3561],{"type":33,"value":3347},{"type":27,"tag":1020,"props":3563,"children":3564},{"style":1670},[3565],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3567,"children":3568},{"style":2860},[3569],{"type":33,"value":3570},"'限时活动价低于会员价时应覆盖会员价'",{"type":27,"tag":1020,"props":3572,"children":3573},{"style":1670},[3574],{"type":33,"value":3330},{"type":27,"tag":1020,"props":3576,"children":3577},{"style":1650},[3578],{"type":33,"value":3335},{"type":27,"tag":1020,"props":3580,"children":3581},{"style":1670},[3582],{"type":33,"value":1883},{"type":27,"tag":1020,"props":3584,"children":3585},{"class":1022,"line":2229},[3586,3590,3595,3599,3604,3608],{"type":27,"tag":1020,"props":3587,"children":3588},{"style":1650},[3589],{"type":33,"value":3376},{"type":27,"tag":1020,"props":3591,"children":3592},{"style":1656},[3593],{"type":33,"value":3594}," now",{"type":27,"tag":1020,"props":3596,"children":3597},{"style":1650},[3598],{"type":33,"value":1735},{"type":27,"tag":1020,"props":3600,"children":3601},{"style":1670},[3602],{"type":33,"value":3603}," Date.",{"type":27,"tag":1020,"props":3605,"children":3606},{"style":1875},[3607],{"type":33,"value":3459},{"type":27,"tag":1020,"props":3609,"children":3610},{"style":1670},[3611],{"type":33,"value":3612},"()\n",{"type":27,"tag":1020,"props":3614,"children":3615},{"class":1022,"line":2242},[3616,3620,3624,3628,3632],{"type":27,"tag":1020,"props":3617,"children":3618},{"style":1650},[3619],{"type":33,"value":3376},{"type":27,"tag":1020,"props":3621,"children":3622},{"style":1656},[3623],{"type":33,"value":3381},{"type":27,"tag":1020,"props":3625,"children":3626},{"style":1650},[3627],{"type":33,"value":1735},{"type":27,"tag":1020,"props":3629,"children":3630},{"style":1875},[3631],{"type":33,"value":2671},{"type":27,"tag":1020,"props":3633,"children":3634},{"style":1670},[3635],{"type":33,"value":3394},{"type":27,"tag":1020,"props":3637,"children":3638},{"class":1022,"line":2251},[3639,3643,3647],{"type":27,"tag":1020,"props":3640,"children":3641},{"style":1670},[3642],{"type":33,"value":3402},{"type":27,"tag":1020,"props":3644,"children":3645},{"style":1656},[3646],{"type":33,"value":3407},{"type":27,"tag":1020,"props":3648,"children":3649},{"style":1670},[3650],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3652,"children":3653},{"class":1022,"line":2260},[3654,3658,3662],{"type":27,"tag":1020,"props":3655,"children":3656},{"style":1670},[3657],{"type":33,"value":3420},{"type":27,"tag":1020,"props":3659,"children":3660},{"style":1656},[3661],{"type":33,"value":3425},{"type":27,"tag":1020,"props":3663,"children":3664},{"style":1670},[3665],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3667,"children":3668},{"class":1022,"line":2269},[3669,3674,3679],{"type":27,"tag":1020,"props":3670,"children":3671},{"style":1670},[3672],{"type":33,"value":3673},"      flashSalePrice: ",{"type":27,"tag":1020,"props":3675,"children":3676},{"style":1656},[3677],{"type":33,"value":3678},"3499",{"type":27,"tag":1020,"props":3680,"children":3681},{"style":1670},[3682],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3684,"children":3685},{"class":1022,"line":2288},[3686,3691,3695,3700],{"type":27,"tag":1020,"props":3687,"children":3688},{"style":1670},[3689],{"type":33,"value":3690},"      flashSaleStartAt: now ",{"type":27,"tag":1020,"props":3692,"children":3693},{"style":1650},[3694],{"type":33,"value":3111},{"type":27,"tag":1020,"props":3696,"children":3697},{"style":1656},[3698],{"type":33,"value":3699}," 1000",{"type":27,"tag":1020,"props":3701,"children":3702},{"style":1670},[3703],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3705,"children":3706},{"class":1022,"line":2297},[3707,3712,3717,3721],{"type":27,"tag":1020,"props":3708,"children":3709},{"style":1670},[3710],{"type":33,"value":3711},"      flashSaleEndAt: now ",{"type":27,"tag":1020,"props":3713,"children":3714},{"style":1650},[3715],{"type":33,"value":3716},"+",{"type":27,"tag":1020,"props":3718,"children":3719},{"style":1656},[3720],{"type":33,"value":3699},{"type":27,"tag":1020,"props":3722,"children":3723},{"style":1670},[3724],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3726,"children":3727},{"class":1022,"line":2316},[3728,3732,3736],{"type":27,"tag":1020,"props":3729,"children":3730},{"style":1670},[3731],{"type":33,"value":3437},{"type":27,"tag":1020,"props":3733,"children":3734},{"style":1656},[3735],{"type":33,"value":3442},{"type":27,"tag":1020,"props":3737,"children":3738},{"style":1670},[3739],{"type":33,"value":3412},{"type":27,"tag":1020,"props":3741,"children":3742},{"class":1022,"line":2335},[3743],{"type":27,"tag":1020,"props":3744,"children":3745},{"style":1670},[3746],{"type":33,"value":3747},"      now,\n",{"type":27,"tag":1020,"props":3749,"children":3750},{"class":1022,"line":2344},[3751],{"type":27,"tag":1020,"props":3752,"children":3753},{"style":1670},[3754],{"type":33,"value":3472},{"type":27,"tag":1020,"props":3756,"children":3757},{"class":1022,"line":2970},[3758],{"type":27,"tag":1020,"props":3759,"children":3760},{"emptyLinePlaceholder":18},[3761],{"type":33,"value":1718},{"type":27,"tag":1020,"props":3763,"children":3764},{"class":1022,"line":3006},[3765,3769,3773,3777,3781,3785],{"type":27,"tag":1020,"props":3766,"children":3767},{"style":1875},[3768],{"type":33,"value":3487},{"type":27,"tag":1020,"props":3770,"children":3771},{"style":1670},[3772],{"type":33,"value":3492},{"type":27,"tag":1020,"props":3774,"children":3775},{"style":1875},[3776],{"type":33,"value":3497},{"type":27,"tag":1020,"props":3778,"children":3779},{"style":1670},[3780],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3782,"children":3783},{"style":1656},[3784],{"type":33,"value":3678},{"type":27,"tag":1020,"props":3786,"children":3787},{"style":1670},[3788],{"type":33,"value":3510},{"type":27,"tag":1020,"props":3790,"children":3791},{"class":1022,"line":3027},[3792,3796,3800,3804,3808,3813],{"type":27,"tag":1020,"props":3793,"children":3794},{"style":1875},[3795],{"type":33,"value":3487},{"type":27,"tag":1020,"props":3797,"children":3798},{"style":1670},[3799],{"type":33,"value":3522},{"type":27,"tag":1020,"props":3801,"children":3802},{"style":1875},[3803],{"type":33,"value":3497},{"type":27,"tag":1020,"props":3805,"children":3806},{"style":1670},[3807],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3809,"children":3810},{"style":2860},[3811],{"type":33,"value":3812},"'flash-sale'",{"type":27,"tag":1020,"props":3814,"children":3815},{"style":1670},[3816],{"type":33,"value":3510},{"type":27,"tag":1020,"props":3818,"children":3819},{"class":1022,"line":3044},[3820],{"type":27,"tag":1020,"props":3821,"children":3822},{"style":1670},[3823],{"type":33,"value":3547},{"type":27,"tag":1020,"props":3825,"children":3826},{"class":1022,"line":3052},[3827],{"type":27,"tag":1020,"props":3828,"children":3829},{"style":1670},[3830],{"type":33,"value":3831},"})\n",{"type":27,"tag":35,"props":3833,"children":3834},{},[3835],{"type":33,"value":3836},"以前一次价格改动要 QA 走半天页面；现在先跑规则测试，再做页面回归。",{"type":27,"tag":35,"props":3838,"children":3839},{},[3840],{"type":33,"value":3841},"不是不需要人工验证，而是人工验证终于不再是唯一防线。",{"type":27,"tag":125,"props":3843,"children":3844},{},[],{"type":27,"tag":129,"props":3846,"children":3848},{"id":3847},"七第三刀引入功能开关和影子比对不让切换变成赌博",[3849],{"type":33,"value":3850},"七、第三刀：引入功能开关和影子比对，不让切换变成赌博",{"type":27,"tag":141,"props":3852,"children":3854},{"id":3853},"决策点-7任何重构路径都必须支持新旧并行",[3855],{"type":33,"value":3856},"决策点 7：任何重构路径，都必须支持“新旧并行”",{"type":27,"tag":35,"props":3858,"children":3859},{},[3860],{"type":33,"value":3861},"很多失败的重构，问题不在代码，而在切换方式。",{"type":27,"tag":35,"props":3863,"children":3864},{},[3865],{"type":33,"value":3866},"如果你只能“今晚全量切新逻辑”，那不是发布，是祈祷。",{"type":27,"tag":35,"props":3868,"children":3869},{},[3870],{"type":33,"value":3871},"我们做了两件事：",{"type":27,"tag":153,"props":3873,"children":3874},{},[3875,3885],{"type":27,"tag":87,"props":3876,"children":3877},{},[3878,3883],{"type":27,"tag":70,"props":3879,"children":3880},{},[3881],{"type":33,"value":3882},"功能开关",{"type":33,"value":3884},"：控制哪些流量走新链路",{"type":27,"tag":87,"props":3886,"children":3887},{},[3888,3892],{"type":27,"tag":70,"props":3889,"children":3890},{},[3891],{"type":33,"value":1481},{"type":33,"value":3893},"：新旧链路同时算，结果不上屏，只做差异监控",{"type":27,"tag":141,"props":3895,"children":3897},{"id":3896},"_71-功能开关控制切流",[3898],{"type":33,"value":3899},"7.1 功能开关控制切流",{"type":27,"tag":1011,"props":3901,"children":3903},{"className":1638,"code":3902,"language":1640,"meta":7,"style":7},"// shared/lib/featureFlags.ts\nexport async function shouldUseNewPricing(ctx: {\n  userId?: string\n  region: string\n  isBigPromotion: boolean\n}) {\n  if (ctx.isBigPromotion) return false\n  if (ctx.region !== 'cn-east-1') return false\n\n  const bucket = hashToPercent(ctx.userId || 'guest')\n  return bucket \u003C 10\n}\n",[3904],{"type":27,"tag":51,"props":3905,"children":3906},{"__ignoreMap":7},[3907,3915,3951,3967,3983,3999,4007,4029,4063,4070,4110,4131],{"type":27,"tag":1020,"props":3908,"children":3909},{"class":1022,"line":1023},[3910],{"type":27,"tag":1020,"props":3911,"children":3912},{"style":1861},[3913],{"type":33,"value":3914},"// shared/lib/featureFlags.ts\n",{"type":27,"tag":1020,"props":3916,"children":3917},{"class":1022,"line":20},[3918,3922,3926,3930,3935,3939,3943,3947],{"type":27,"tag":1020,"props":3919,"children":3920},{"style":1650},[3921],{"type":33,"value":2029},{"type":27,"tag":1020,"props":3923,"children":3924},{"style":1650},[3925],{"type":33,"value":2034},{"type":27,"tag":1020,"props":3927,"children":3928},{"style":1650},[3929],{"type":33,"value":2039},{"type":27,"tag":1020,"props":3931,"children":3932},{"style":1875},[3933],{"type":33,"value":3934}," shouldUseNewPricing",{"type":27,"tag":1020,"props":3936,"children":3937},{"style":1670},[3938],{"type":33,"value":2049},{"type":27,"tag":1020,"props":3940,"children":3941},{"style":1889},[3942],{"type":33,"value":2680},{"type":27,"tag":1020,"props":3944,"children":3945},{"style":1650},[3946],{"type":33,"value":1897},{"type":27,"tag":1020,"props":3948,"children":3949},{"style":1670},[3950],{"type":33,"value":1883},{"type":27,"tag":1020,"props":3952,"children":3953},{"class":1022,"line":1040},[3954,3959,3963],{"type":27,"tag":1020,"props":3955,"children":3956},{"style":1889},[3957],{"type":33,"value":3958},"  userId",{"type":27,"tag":1020,"props":3960,"children":3961},{"style":1650},[3962],{"type":33,"value":2541},{"type":27,"tag":1020,"props":3964,"children":3965},{"style":1656},[3966],{"type":33,"value":1902},{"type":27,"tag":1020,"props":3968,"children":3969},{"class":1022,"line":1049},[3970,3975,3979],{"type":27,"tag":1020,"props":3971,"children":3972},{"style":1889},[3973],{"type":33,"value":3974},"  region",{"type":27,"tag":1020,"props":3976,"children":3977},{"style":1650},[3978],{"type":33,"value":1897},{"type":27,"tag":1020,"props":3980,"children":3981},{"style":1656},[3982],{"type":33,"value":1902},{"type":27,"tag":1020,"props":3984,"children":3985},{"class":1022,"line":1058},[3986,3991,3995],{"type":27,"tag":1020,"props":3987,"children":3988},{"style":1889},[3989],{"type":33,"value":3990},"  isBigPromotion",{"type":27,"tag":1020,"props":3992,"children":3993},{"style":1650},[3994],{"type":33,"value":1897},{"type":27,"tag":1020,"props":3996,"children":3997},{"style":1656},[3998],{"type":33,"value":2006},{"type":27,"tag":1020,"props":4000,"children":4001},{"class":1022,"line":1067},[4002],{"type":27,"tag":1020,"props":4003,"children":4004},{"style":1670},[4005],{"type":33,"value":4006},"}) {\n",{"type":27,"tag":1020,"props":4008,"children":4009},{"class":1022,"line":1076},[4010,4014,4019,4024],{"type":27,"tag":1020,"props":4011,"children":4012},{"style":1650},[4013],{"type":33,"value":2878},{"type":27,"tag":1020,"props":4015,"children":4016},{"style":1670},[4017],{"type":33,"value":4018}," (ctx.isBigPromotion) ",{"type":27,"tag":1020,"props":4020,"children":4021},{"style":1650},[4022],{"type":33,"value":4023},"return",{"type":27,"tag":1020,"props":4025,"children":4026},{"style":1656},[4027],{"type":33,"value":4028}," false\n",{"type":27,"tag":1020,"props":4030,"children":4031},{"class":1022,"line":1085},[4032,4036,4041,4045,4050,4055,4059],{"type":27,"tag":1020,"props":4033,"children":4034},{"style":1650},[4035],{"type":33,"value":2878},{"type":27,"tag":1020,"props":4037,"children":4038},{"style":1670},[4039],{"type":33,"value":4040}," (ctx.region ",{"type":27,"tag":1020,"props":4042,"children":4043},{"style":1650},[4044],{"type":33,"value":2722},{"type":27,"tag":1020,"props":4046,"children":4047},{"style":2860},[4048],{"type":33,"value":4049}," 'cn-east-1'",{"type":27,"tag":1020,"props":4051,"children":4052},{"style":1670},[4053],{"type":33,"value":4054},") ",{"type":27,"tag":1020,"props":4056,"children":4057},{"style":1650},[4058],{"type":33,"value":4023},{"type":27,"tag":1020,"props":4060,"children":4061},{"style":1656},[4062],{"type":33,"value":4028},{"type":27,"tag":1020,"props":4064,"children":4065},{"class":1022,"line":1094},[4066],{"type":27,"tag":1020,"props":4067,"children":4068},{"emptyLinePlaceholder":18},[4069],{"type":33,"value":1718},{"type":27,"tag":1020,"props":4071,"children":4072},{"class":1022,"line":1103},[4073,4077,4082,4086,4091,4096,4101,4106],{"type":27,"tag":1020,"props":4074,"children":4075},{"style":1650},[4076],{"type":33,"value":2099},{"type":27,"tag":1020,"props":4078,"children":4079},{"style":1656},[4080],{"type":33,"value":4081}," bucket",{"type":27,"tag":1020,"props":4083,"children":4084},{"style":1650},[4085],{"type":33,"value":1735},{"type":27,"tag":1020,"props":4087,"children":4088},{"style":1875},[4089],{"type":33,"value":4090}," hashToPercent",{"type":27,"tag":1020,"props":4092,"children":4093},{"style":1670},[4094],{"type":33,"value":4095},"(ctx.userId ",{"type":27,"tag":1020,"props":4097,"children":4098},{"style":1650},[4099],{"type":33,"value":4100},"||",{"type":27,"tag":1020,"props":4102,"children":4103},{"style":2860},[4104],{"type":33,"value":4105}," 'guest'",{"type":27,"tag":1020,"props":4107,"children":4108},{"style":1670},[4109],{"type":33,"value":3510},{"type":27,"tag":1020,"props":4111,"children":4112},{"class":1022,"line":1112},[4113,4117,4122,4126],{"type":27,"tag":1020,"props":4114,"children":4115},{"style":1650},[4116],{"type":33,"value":2235},{"type":27,"tag":1020,"props":4118,"children":4119},{"style":1670},[4120],{"type":33,"value":4121}," bucket ",{"type":27,"tag":1020,"props":4123,"children":4124},{"style":1650},[4125],{"type":33,"value":2081},{"type":27,"tag":1020,"props":4127,"children":4128},{"style":1656},[4129],{"type":33,"value":4130}," 10\n",{"type":27,"tag":1020,"props":4132,"children":4133},{"class":1022,"line":1121},[4134],{"type":27,"tag":1020,"props":4135,"children":4136},{"style":1670},[4137],{"type":33,"value":2014},{"type":27,"tag":35,"props":4139,"children":4140},{},[4141],{"type":33,"value":4142},"这样我们可以做到：",{"type":27,"tag":83,"props":4144,"children":4145},{},[4146,4151,4156],{"type":27,"tag":87,"props":4147,"children":4148},{},[4149],{"type":33,"value":4150},"非大促时只给 10% 用户走新逻辑",{"type":27,"tag":87,"props":4152,"children":4153},{},[4154],{"type":33,"value":4155},"指定区域先试",{"type":27,"tag":87,"props":4157,"children":4158},{},[4159],{"type":33,"value":4160},"有问题一键回旧逻辑",{"type":27,"tag":141,"props":4162,"children":4164},{"id":4163},"_72-影子比对盯差异不直接上生产结果",[4165],{"type":33,"value":4166},"7.2 影子比对盯差异，不直接上生产结果",{"type":27,"tag":1011,"props":4168,"children":4170},{"className":1638,"code":4169,"language":1640,"meta":7,"style":7},"// bff/pricing/getPriceWithShadowCompare.ts\nexport async function getPriceWithShadowCompare(input: PriceInput) {\n  const legacy = await legacyPricingService.calculate(input)\n  const modern = await modernPricingService.calculate(input)\n\n  if (legacy.finalPrice !== modern.finalPrice) {\n    telemetry.capture('pricing_diff_detected', {\n      skuId: input.skuId,\n      legacyPrice: legacy.finalPrice,\n      modernPrice: modern.finalPrice,\n      diff: modern.finalPrice - legacy.finalPrice,\n    })\n  }\n\n  return shouldExposeModernResult(input.userId) ? modern : legacy\n}\n",[4171],{"type":27,"tag":51,"props":4172,"children":4173},{"__ignoreMap":7},[4174,4182,4224,4259,4292,4299,4320,4347,4355,4363,4371,4388,4395,4402,4409,4445],{"type":27,"tag":1020,"props":4175,"children":4176},{"class":1022,"line":1023},[4177],{"type":27,"tag":1020,"props":4178,"children":4179},{"style":1861},[4180],{"type":33,"value":4181},"// bff/pricing/getPriceWithShadowCompare.ts\n",{"type":27,"tag":1020,"props":4183,"children":4184},{"class":1022,"line":20},[4185,4189,4193,4197,4202,4206,4211,4215,4220],{"type":27,"tag":1020,"props":4186,"children":4187},{"style":1650},[4188],{"type":33,"value":2029},{"type":27,"tag":1020,"props":4190,"children":4191},{"style":1650},[4192],{"type":33,"value":2034},{"type":27,"tag":1020,"props":4194,"children":4195},{"style":1650},[4196],{"type":33,"value":2039},{"type":27,"tag":1020,"props":4198,"children":4199},{"style":1875},[4200],{"type":33,"value":4201}," getPriceWithShadowCompare",{"type":27,"tag":1020,"props":4203,"children":4204},{"style":1670},[4205],{"type":33,"value":2049},{"type":27,"tag":1020,"props":4207,"children":4208},{"style":1889},[4209],{"type":33,"value":4210},"input",{"type":27,"tag":1020,"props":4212,"children":4213},{"style":1650},[4214],{"type":33,"value":1897},{"type":27,"tag":1020,"props":4216,"children":4217},{"style":1875},[4218],{"type":33,"value":4219}," PriceInput",{"type":27,"tag":1020,"props":4221,"children":4222},{"style":1670},[4223],{"type":33,"value":2693},{"type":27,"tag":1020,"props":4225,"children":4226},{"class":1022,"line":1040},[4227,4231,4236,4240,4244,4249,4254],{"type":27,"tag":1020,"props":4228,"children":4229},{"style":1650},[4230],{"type":33,"value":2099},{"type":27,"tag":1020,"props":4232,"children":4233},{"style":1656},[4234],{"type":33,"value":4235}," legacy",{"type":27,"tag":1020,"props":4237,"children":4238},{"style":1650},[4239],{"type":33,"value":1735},{"type":27,"tag":1020,"props":4241,"children":4242},{"style":1650},[4243],{"type":33,"value":2142},{"type":27,"tag":1020,"props":4245,"children":4246},{"style":1670},[4247],{"type":33,"value":4248}," legacyPricingService.",{"type":27,"tag":1020,"props":4250,"children":4251},{"style":1875},[4252],{"type":33,"value":4253},"calculate",{"type":27,"tag":1020,"props":4255,"children":4256},{"style":1670},[4257],{"type":33,"value":4258},"(input)\n",{"type":27,"tag":1020,"props":4260,"children":4261},{"class":1022,"line":1049},[4262,4266,4271,4275,4279,4284,4288],{"type":27,"tag":1020,"props":4263,"children":4264},{"style":1650},[4265],{"type":33,"value":2099},{"type":27,"tag":1020,"props":4267,"children":4268},{"style":1656},[4269],{"type":33,"value":4270}," modern",{"type":27,"tag":1020,"props":4272,"children":4273},{"style":1650},[4274],{"type":33,"value":1735},{"type":27,"tag":1020,"props":4276,"children":4277},{"style":1650},[4278],{"type":33,"value":2142},{"type":27,"tag":1020,"props":4280,"children":4281},{"style":1670},[4282],{"type":33,"value":4283}," modernPricingService.",{"type":27,"tag":1020,"props":4285,"children":4286},{"style":1875},[4287],{"type":33,"value":4253},{"type":27,"tag":1020,"props":4289,"children":4290},{"style":1670},[4291],{"type":33,"value":4258},{"type":27,"tag":1020,"props":4293,"children":4294},{"class":1022,"line":1058},[4295],{"type":27,"tag":1020,"props":4296,"children":4297},{"emptyLinePlaceholder":18},[4298],{"type":33,"value":1718},{"type":27,"tag":1020,"props":4300,"children":4301},{"class":1022,"line":1067},[4302,4306,4311,4315],{"type":27,"tag":1020,"props":4303,"children":4304},{"style":1650},[4305],{"type":33,"value":2878},{"type":27,"tag":1020,"props":4307,"children":4308},{"style":1670},[4309],{"type":33,"value":4310}," (legacy.finalPrice ",{"type":27,"tag":1020,"props":4312,"children":4313},{"style":1650},[4314],{"type":33,"value":2722},{"type":27,"tag":1020,"props":4316,"children":4317},{"style":1670},[4318],{"type":33,"value":4319}," modern.finalPrice) {\n",{"type":27,"tag":1020,"props":4321,"children":4322},{"class":1022,"line":1076},[4323,4328,4333,4337,4342],{"type":27,"tag":1020,"props":4324,"children":4325},{"style":1670},[4326],{"type":33,"value":4327},"    telemetry.",{"type":27,"tag":1020,"props":4329,"children":4330},{"style":1875},[4331],{"type":33,"value":4332},"capture",{"type":27,"tag":1020,"props":4334,"children":4335},{"style":1670},[4336],{"type":33,"value":2049},{"type":27,"tag":1020,"props":4338,"children":4339},{"style":2860},[4340],{"type":33,"value":4341},"'pricing_diff_detected'",{"type":27,"tag":1020,"props":4343,"children":4344},{"style":1670},[4345],{"type":33,"value":4346},", {\n",{"type":27,"tag":1020,"props":4348,"children":4349},{"class":1022,"line":1085},[4350],{"type":27,"tag":1020,"props":4351,"children":4352},{"style":1670},[4353],{"type":33,"value":4354},"      skuId: input.skuId,\n",{"type":27,"tag":1020,"props":4356,"children":4357},{"class":1022,"line":1094},[4358],{"type":27,"tag":1020,"props":4359,"children":4360},{"style":1670},[4361],{"type":33,"value":4362},"      legacyPrice: legacy.finalPrice,\n",{"type":27,"tag":1020,"props":4364,"children":4365},{"class":1022,"line":1103},[4366],{"type":27,"tag":1020,"props":4367,"children":4368},{"style":1670},[4369],{"type":33,"value":4370},"      modernPrice: modern.finalPrice,\n",{"type":27,"tag":1020,"props":4372,"children":4373},{"class":1022,"line":1112},[4374,4379,4383],{"type":27,"tag":1020,"props":4375,"children":4376},{"style":1670},[4377],{"type":33,"value":4378},"      diff: modern.finalPrice ",{"type":27,"tag":1020,"props":4380,"children":4381},{"style":1650},[4382],{"type":33,"value":3111},{"type":27,"tag":1020,"props":4384,"children":4385},{"style":1670},[4386],{"type":33,"value":4387}," legacy.finalPrice,\n",{"type":27,"tag":1020,"props":4389,"children":4390},{"class":1022,"line":1121},[4391],{"type":27,"tag":1020,"props":4392,"children":4393},{"style":1670},[4394],{"type":33,"value":3472},{"type":27,"tag":1020,"props":4396,"children":4397},{"class":1022,"line":1130},[4398],{"type":27,"tag":1020,"props":4399,"children":4400},{"style":1670},[4401],{"type":33,"value":2341},{"type":27,"tag":1020,"props":4403,"children":4404},{"class":1022,"line":1139},[4405],{"type":27,"tag":1020,"props":4406,"children":4407},{"emptyLinePlaceholder":18},[4408],{"type":33,"value":1718},{"type":27,"tag":1020,"props":4410,"children":4411},{"class":1022,"line":1148},[4412,4416,4421,4426,4431,4436,4440],{"type":27,"tag":1020,"props":4413,"children":4414},{"style":1650},[4415],{"type":33,"value":2235},{"type":27,"tag":1020,"props":4417,"children":4418},{"style":1875},[4419],{"type":33,"value":4420}," shouldExposeModernResult",{"type":27,"tag":1020,"props":4422,"children":4423},{"style":1670},[4424],{"type":33,"value":4425},"(input.userId) ",{"type":27,"tag":1020,"props":4427,"children":4428},{"style":1650},[4429],{"type":33,"value":4430},"?",{"type":27,"tag":1020,"props":4432,"children":4433},{"style":1670},[4434],{"type":33,"value":4435}," modern ",{"type":27,"tag":1020,"props":4437,"children":4438},{"style":1650},[4439],{"type":33,"value":1897},{"type":27,"tag":1020,"props":4441,"children":4442},{"style":1670},[4443],{"type":33,"value":4444}," legacy\n",{"type":27,"tag":1020,"props":4446,"children":4447},{"class":1022,"line":21},[4448],{"type":27,"tag":1020,"props":4449,"children":4450},{"style":1670},[4451],{"type":33,"value":2014},{"type":27,"tag":35,"props":4453,"children":4454},{},[4455],{"type":33,"value":4456},"这套机制帮我们在正式切换前发现了两个隐藏问题：",{"type":27,"tag":153,"props":4458,"children":4459},{},[4460,4465],{"type":27,"tag":87,"props":4461,"children":4462},{},[4463],{"type":33,"value":4464},"某类店铺券在旧系统里有“向下取整”规则，新实现漏了",{"type":27,"tag":87,"props":4466,"children":4467},{},[4468],{"type":33,"value":4469},"某些组合活动的生效顺序不是“平台券后店铺券”，而是相反",{"type":27,"tag":35,"props":4471,"children":4472},{},[4473],{"type":33,"value":4474},"如果没有影子比对，这两个 bug 会直接在真实用户账单里爆炸。",{"type":27,"tag":125,"props":4476,"children":4477},{},[],{"type":27,"tag":129,"props":4479,"children":4481},{"id":4480},"八第四刀团队重组不然好结构也会被旧习惯拖回去",[4482],{"type":33,"value":4483},"八、第四刀：团队重组，不然好结构也会被旧习惯拖回去",{"type":27,"tag":35,"props":4485,"children":4486},{},[4487],{"type":33,"value":4488},"重构的对象不只是代码，还是协作方式。",{"type":27,"tag":141,"props":4490,"children":4492},{"id":4491},"决策点-8从按页面分工改成按领域负责",[4493],{"type":33,"value":4494},"决策点 8：从“按页面分工”改成“按领域负责”",{"type":27,"tag":35,"props":4496,"children":4497},{},[4498],{"type":33,"value":4499},"原来团队分法是：",{"type":27,"tag":83,"props":4501,"children":4502},{},[4503,4508,4513,4518],{"type":27,"tag":87,"props":4504,"children":4505},{},[4506],{"type":33,"value":4507},"A 负责首页",{"type":27,"tag":87,"props":4509,"children":4510},{},[4511],{"type":33,"value":4512},"B 负责详情页",{"type":27,"tag":87,"props":4514,"children":4515},{},[4516],{"type":33,"value":4517},"C 负责购物车",{"type":27,"tag":87,"props":4519,"children":4520},{},[4521],{"type":33,"value":4522},"D 负责结算页",{"type":27,"tag":35,"props":4524,"children":4525},{},[4526],{"type":33,"value":4527},"听上去合理，但问题是：价格、活动、库存这些能力横跨多个页面。于是同一套逻辑会被不同人各写一份。",{"type":27,"tag":35,"props":4529,"children":4530},{},[4531],{"type":33,"value":4532},"我们改成了：",{"type":27,"tag":193,"props":4534,"children":4535},{},[4536,4557],{"type":27,"tag":197,"props":4537,"children":4538},{},[4539],{"type":27,"tag":201,"props":4540,"children":4541},{},[4542,4547,4552],{"type":27,"tag":205,"props":4543,"children":4544},{},[4545],{"type":33,"value":4546},"小组",{"type":27,"tag":205,"props":4548,"children":4549},{},[4550],{"type":33,"value":4551},"负责领域",{"type":27,"tag":205,"props":4553,"children":4554},{},[4555],{"type":33,"value":4556},"典型职责",{"type":27,"tag":221,"props":4558,"children":4559},{},[4560,4578,4596,4613],{"type":27,"tag":201,"props":4561,"children":4562},{},[4563,4568,4573],{"type":27,"tag":228,"props":4564,"children":4565},{},[4566],{"type":33,"value":4567},"Pricing 小组",{"type":27,"tag":228,"props":4569,"children":4570},{},[4571],{"type":33,"value":4572},"定价与优惠",{"type":27,"tag":228,"props":4574,"children":4575},{},[4576],{"type":33,"value":4577},"到手价、会员价、活动叠加",{"type":27,"tag":201,"props":4579,"children":4580},{},[4581,4586,4591],{"type":27,"tag":228,"props":4582,"children":4583},{},[4584],{"type":33,"value":4585},"Promotion 小组",{"type":27,"tag":228,"props":4587,"children":4588},{},[4589],{"type":33,"value":4590},"活动编排",{"type":27,"tag":228,"props":4592,"children":4593},{},[4594],{"type":33,"value":4595},"会场、优惠券、促销标签",{"type":27,"tag":201,"props":4597,"children":4598},{},[4599,4604,4608],{"type":27,"tag":228,"props":4600,"children":4601},{},[4602],{"type":33,"value":4603},"Order 小组",{"type":27,"tag":228,"props":4605,"children":4606},{},[4607],{"type":33,"value":170},{"type":27,"tag":228,"props":4609,"children":4610},{},[4611],{"type":33,"value":4612},"下单链路、订单确认",{"type":27,"tag":201,"props":4614,"children":4615},{},[4616,4621,4626],{"type":27,"tag":228,"props":4617,"children":4618},{},[4619],{"type":33,"value":4620},"Shared 小组",{"type":27,"tag":228,"props":4622,"children":4623},{},[4624],{"type":33,"value":4625},"组件与基础库",{"type":27,"tag":228,"props":4627,"children":4628},{},[4629],{"type":33,"value":4630},"UI、埋点、工具链",{"type":27,"tag":35,"props":4632,"children":4633},{},[4634],{"type":33,"value":4635},"这不是为了“组织设计很先进”，而是为了让代码边界和团队边界尽量一致。",{"type":27,"tag":141,"props":4637,"children":4639},{"id":4638},"决策点-9代码所有权必须明确",[4640],{"type":33,"value":4641},"决策点 9：代码所有权必须明确",{"type":27,"tag":35,"props":4643,"children":4644},{},[4645],{"type":33,"value":4646},"我们加了 CODEOWNERS 风格的责任归属：",{"type":27,"tag":83,"props":4648,"children":4649},{},[4650,4661,4672],{"type":27,"tag":87,"props":4651,"children":4652},{},[4653,4659],{"type":27,"tag":51,"props":4654,"children":4656},{"className":4655},[],[4657],{"type":33,"value":4658},"features/pricing/**",{"type":33,"value":4660},"：Pricing 小组必须 review",{"type":27,"tag":87,"props":4662,"children":4663},{},[4664,4670],{"type":27,"tag":51,"props":4665,"children":4667},{"className":4666},[],[4668],{"type":33,"value":4669},"bff/product/**",{"type":33,"value":4671},"：BFF owner 必须 review",{"type":27,"tag":87,"props":4673,"children":4674},{},[4675,4681],{"type":27,"tag":51,"props":4676,"children":4678},{"className":4677},[],[4679],{"type":33,"value":4680},"shared/ui/**",{"type":33,"value":4682},"：基础组 review",{"type":27,"tag":35,"props":4684,"children":4685},{},[4686],{"type":33,"value":4687},"直接效果是：",{"type":27,"tag":83,"props":4689,"children":4690},{},[4691,4696,4701],{"type":27,"tag":87,"props":4692,"children":4693},{},[4694],{"type":33,"value":4695},"Review 不再“谁有空谁看”",{"type":27,"tag":87,"props":4697,"children":4698},{},[4699],{"type":33,"value":4700},"规则改动不再绕过真正懂上下文的人",{"type":27,"tag":87,"props":4702,"children":4703},{},[4704],{"type":33,"value":4705},"模块演进开始有连续性",{"type":27,"tag":125,"props":4707,"children":4708},{},[],{"type":27,"tag":129,"props":4710,"children":4712},{"id":4711},"九第五刀埋点日志告警先统一不然根本不知道自己有没有成功",[4713],{"type":33,"value":4714},"九、第五刀：埋点、日志、告警先统一，不然根本不知道自己有没有成功",{"type":27,"tag":141,"props":4716,"children":4718},{"id":4717},"决策点-10没有统一观测重构收益无法被证明",[4719],{"type":33,"value":4720},"决策点 10：没有统一观测，重构收益无法被证明",{"type":27,"tag":35,"props":4722,"children":4723},{},[4724],{"type":33,"value":4725},"工程团队很容易掉进一个坑：",{"type":27,"tag":551,"props":4727,"children":4728},{},[4729],{"type":27,"tag":35,"props":4730,"children":4731},{},[4732],{"type":33,"value":4733},"觉得“代码更整洁了”，就等于重构成功了。",{"type":27,"tag":35,"props":4735,"children":4736},{},[4737,4739,4744],{"type":33,"value":4738},"管理层不会为“整洁”买单，只会为",{"type":27,"tag":70,"props":4740,"children":4741},{},[4742],{"type":33,"value":4743},"风险下降、速度提升、收入不受损",{"type":33,"value":4745},"买单。",{"type":27,"tag":35,"props":4747,"children":4748},{},[4749],{"type":33,"value":4750},"所以我们把观测做成了强约束。",{"type":27,"tag":141,"props":4752,"children":4754},{"id":4753},"_91-统一日志字段",[4755],{"type":33,"value":4756},"9.1 统一日志字段",{"type":27,"tag":1011,"props":4758,"children":4760},{"className":1638,"code":4759,"language":1640,"meta":7,"style":7},"// shared/telemetry/logger.ts\nexport function logBffEvent(event: string, payload: Record\u003Cstring, unknown>) {\n  console.log(JSON.stringify({\n    event,\n    ts: Date.now(),\n    service: 'web-bff',\n    traceId: payload.traceId,\n    page: payload.page,\n    userId: payload.userId,\n    skuId: payload.skuId,\n    version: payload.version,\n    ...payload,\n  }))\n}\n",[4761],{"type":27,"tag":51,"props":4762,"children":4763},{"__ignoreMap":7},[4764,4772,4846,4881,4889,4905,4922,4930,4938,4946,4954,4962,4975,4983],{"type":27,"tag":1020,"props":4765,"children":4766},{"class":1022,"line":1023},[4767],{"type":27,"tag":1020,"props":4768,"children":4769},{"style":1861},[4770],{"type":33,"value":4771},"// shared/telemetry/logger.ts\n",{"type":27,"tag":1020,"props":4773,"children":4774},{"class":1022,"line":20},[4775,4779,4783,4788,4792,4797,4801,4805,4809,4814,4818,4823,4827,4832,4836,4841],{"type":27,"tag":1020,"props":4776,"children":4777},{"style":1650},[4778],{"type":33,"value":2029},{"type":27,"tag":1020,"props":4780,"children":4781},{"style":1650},[4782],{"type":33,"value":2039},{"type":27,"tag":1020,"props":4784,"children":4785},{"style":1875},[4786],{"type":33,"value":4787}," logBffEvent",{"type":27,"tag":1020,"props":4789,"children":4790},{"style":1670},[4791],{"type":33,"value":2049},{"type":27,"tag":1020,"props":4793,"children":4794},{"style":1889},[4795],{"type":33,"value":4796},"event",{"type":27,"tag":1020,"props":4798,"children":4799},{"style":1650},[4800],{"type":33,"value":1897},{"type":27,"tag":1020,"props":4802,"children":4803},{"style":1656},[4804],{"type":33,"value":1984},{"type":27,"tag":1020,"props":4806,"children":4807},{"style":1670},[4808],{"type":33,"value":2114},{"type":27,"tag":1020,"props":4810,"children":4811},{"style":1889},[4812],{"type":33,"value":4813},"payload",{"type":27,"tag":1020,"props":4815,"children":4816},{"style":1650},[4817],{"type":33,"value":1897},{"type":27,"tag":1020,"props":4819,"children":4820},{"style":1875},[4821],{"type":33,"value":4822}," Record",{"type":27,"tag":1020,"props":4824,"children":4825},{"style":1670},[4826],{"type":33,"value":2081},{"type":27,"tag":1020,"props":4828,"children":4829},{"style":1656},[4830],{"type":33,"value":4831},"string",{"type":27,"tag":1020,"props":4833,"children":4834},{"style":1670},[4835],{"type":33,"value":2114},{"type":27,"tag":1020,"props":4837,"children":4838},{"style":1656},[4839],{"type":33,"value":4840},"unknown",{"type":27,"tag":1020,"props":4842,"children":4843},{"style":1670},[4844],{"type":33,"value":4845},">) {\n",{"type":27,"tag":1020,"props":4847,"children":4848},{"class":1022,"line":1040},[4849,4854,4859,4863,4868,4872,4877],{"type":27,"tag":1020,"props":4850,"children":4851},{"style":1670},[4852],{"type":33,"value":4853},"  console.",{"type":27,"tag":1020,"props":4855,"children":4856},{"style":1875},[4857],{"type":33,"value":4858},"log",{"type":27,"tag":1020,"props":4860,"children":4861},{"style":1670},[4862],{"type":33,"value":2049},{"type":27,"tag":1020,"props":4864,"children":4865},{"style":1656},[4866],{"type":33,"value":4867},"JSON",{"type":27,"tag":1020,"props":4869,"children":4870},{"style":1670},[4871],{"type":33,"value":2151},{"type":27,"tag":1020,"props":4873,"children":4874},{"style":1875},[4875],{"type":33,"value":4876},"stringify",{"type":27,"tag":1020,"props":4878,"children":4879},{"style":1670},[4880],{"type":33,"value":3394},{"type":27,"tag":1020,"props":4882,"children":4883},{"class":1022,"line":1049},[4884],{"type":27,"tag":1020,"props":4885,"children":4886},{"style":1670},[4887],{"type":33,"value":4888},"    event,\n",{"type":27,"tag":1020,"props":4890,"children":4891},{"class":1022,"line":1058},[4892,4897,4901],{"type":27,"tag":1020,"props":4893,"children":4894},{"style":1670},[4895],{"type":33,"value":4896},"    ts: Date.",{"type":27,"tag":1020,"props":4898,"children":4899},{"style":1875},[4900],{"type":33,"value":3459},{"type":27,"tag":1020,"props":4902,"children":4903},{"style":1670},[4904],{"type":33,"value":3464},{"type":27,"tag":1020,"props":4906,"children":4907},{"class":1022,"line":1067},[4908,4913,4918],{"type":27,"tag":1020,"props":4909,"children":4910},{"style":1670},[4911],{"type":33,"value":4912},"    service: ",{"type":27,"tag":1020,"props":4914,"children":4915},{"style":2860},[4916],{"type":33,"value":4917},"'web-bff'",{"type":27,"tag":1020,"props":4919,"children":4920},{"style":1670},[4921],{"type":33,"value":3412},{"type":27,"tag":1020,"props":4923,"children":4924},{"class":1022,"line":1076},[4925],{"type":27,"tag":1020,"props":4926,"children":4927},{"style":1670},[4928],{"type":33,"value":4929},"    traceId: payload.traceId,\n",{"type":27,"tag":1020,"props":4931,"children":4932},{"class":1022,"line":1085},[4933],{"type":27,"tag":1020,"props":4934,"children":4935},{"style":1670},[4936],{"type":33,"value":4937},"    page: payload.page,\n",{"type":27,"tag":1020,"props":4939,"children":4940},{"class":1022,"line":1094},[4941],{"type":27,"tag":1020,"props":4942,"children":4943},{"style":1670},[4944],{"type":33,"value":4945},"    userId: payload.userId,\n",{"type":27,"tag":1020,"props":4947,"children":4948},{"class":1022,"line":1103},[4949],{"type":27,"tag":1020,"props":4950,"children":4951},{"style":1670},[4952],{"type":33,"value":4953},"    skuId: payload.skuId,\n",{"type":27,"tag":1020,"props":4955,"children":4956},{"class":1022,"line":1112},[4957],{"type":27,"tag":1020,"props":4958,"children":4959},{"style":1670},[4960],{"type":33,"value":4961},"    version: payload.version,\n",{"type":27,"tag":1020,"props":4963,"children":4964},{"class":1022,"line":1121},[4965,4970],{"type":27,"tag":1020,"props":4966,"children":4967},{"style":1650},[4968],{"type":33,"value":4969},"    ...",{"type":27,"tag":1020,"props":4971,"children":4972},{"style":1670},[4973],{"type":33,"value":4974},"payload,\n",{"type":27,"tag":1020,"props":4976,"children":4977},{"class":1022,"line":1130},[4978],{"type":27,"tag":1020,"props":4979,"children":4980},{"style":1670},[4981],{"type":33,"value":4982},"  }))\n",{"type":27,"tag":1020,"props":4984,"children":4985},{"class":1022,"line":1139},[4986],{"type":27,"tag":1020,"props":4987,"children":4988},{"style":1670},[4989],{"type":33,"value":2014},{"type":27,"tag":35,"props":4991,"children":4992},{},[4993],{"type":33,"value":4994},"统一字段后，我们终于能把：",{"type":27,"tag":83,"props":4996,"children":4997},{},[4998,5003,5008,5013],{"type":27,"tag":87,"props":4999,"children":5000},{},[5001],{"type":33,"value":5002},"页面埋点",{"type":27,"tag":87,"props":5004,"children":5005},{},[5006],{"type":33,"value":5007},"BFF 日志",{"type":27,"tag":87,"props":5009,"children":5010},{},[5011],{"type":33,"value":5012},"接口错误",{"type":27,"tag":87,"props":5014,"children":5015},{},[5016],{"type":33,"value":5017},"发布版本",{"type":27,"tag":35,"props":5019,"children":5020},{},[5021],{"type":33,"value":5022},"串成一条链路看。",{"type":27,"tag":141,"props":5024,"children":5026},{"id":5025},"_92-统一核心看板",[5027],{"type":33,"value":5028},"9.2 统一核心看板",{"type":27,"tag":35,"props":5030,"children":5031},{},[5032],{"type":33,"value":5033},"重构期间只盯这 6 个指标：",{"type":27,"tag":193,"props":5035,"children":5036},{},[5037,5057],{"type":27,"tag":197,"props":5038,"children":5039},{},[5040],{"type":27,"tag":201,"props":5041,"children":5042},{},[5043,5047,5052],{"type":27,"tag":205,"props":5044,"children":5045},{},[5046],{"type":33,"value":355},{"type":27,"tag":205,"props":5048,"children":5049},{},[5050],{"type":33,"value":5051},"为什么重要",{"type":27,"tag":205,"props":5053,"children":5054},{},[5055],{"type":33,"value":5056},"阈值",{"type":27,"tag":221,"props":5058,"children":5059},{},[5060,5078,5096,5114,5132,5149],{"type":27,"tag":201,"props":5061,"children":5062},{},[5063,5068,5073],{"type":27,"tag":228,"props":5064,"children":5065},{},[5066],{"type":33,"value":5067},"价格计算差异率",{"type":27,"tag":228,"props":5069,"children":5070},{},[5071],{"type":33,"value":5072},"判断新旧逻辑是否一致",{"type":27,"tag":228,"props":5074,"children":5075},{},[5076],{"type":33,"value":5077},"\u003C 0.05%",{"type":27,"tag":201,"props":5079,"children":5080},{},[5081,5086,5091],{"type":27,"tag":228,"props":5082,"children":5083},{},[5084],{"type":33,"value":5085},"商品详情页 JS 错误率",{"type":27,"tag":228,"props":5087,"children":5088},{},[5089],{"type":33,"value":5090},"判断页面稳定性",{"type":27,"tag":228,"props":5092,"children":5093},{},[5094],{"type":33,"value":5095},"\u003C 0.3%",{"type":27,"tag":201,"props":5097,"children":5098},{},[5099,5104,5109],{"type":27,"tag":228,"props":5100,"children":5101},{},[5102],{"type":33,"value":5103},"结算转化率",{"type":27,"tag":228,"props":5105,"children":5106},{},[5107],{"type":33,"value":5108},"防止重构伤业务",{"type":27,"tag":228,"props":5110,"children":5111},{},[5112],{"type":33,"value":5113},"不得下降 > 1%",{"type":27,"tag":201,"props":5115,"children":5116},{},[5117,5122,5127],{"type":27,"tag":228,"props":5118,"children":5119},{},[5120],{"type":33,"value":5121},"页面首屏耗时 P75",{"type":27,"tag":228,"props":5123,"children":5124},{},[5125],{"type":33,"value":5126},"量化性能收益",{"type":27,"tag":228,"props":5128,"children":5129},{},[5130],{"type":33,"value":5131},"下降 20%+",{"type":27,"tag":201,"props":5133,"children":5134},{},[5135,5139,5144],{"type":27,"tag":228,"props":5136,"children":5137},{},[5138],{"type":33,"value":428},{"type":27,"tag":228,"props":5140,"children":5141},{},[5142],{"type":33,"value":5143},"量化工程收益",{"type":27,"tag":228,"props":5145,"children":5146},{},[5147],{"type":33,"value":5148},"下降 30%+",{"type":27,"tag":201,"props":5150,"children":5151},{},[5152,5157,5162],{"type":27,"tag":228,"props":5153,"children":5154},{},[5155],{"type":33,"value":5156},"回滚次数",{"type":27,"tag":228,"props":5158,"children":5159},{},[5160],{"type":33,"value":5161},"判断切换策略是否稳健",{"type":27,"tag":228,"props":5163,"children":5164},{},[5165],{"type":33,"value":5166},"最好多周为 0",{"type":27,"tag":35,"props":5168,"children":5169},{},[5170],{"type":33,"value":5171},"这让重构从“工程自嗨”变成了一个可被业务接受的项目。",{"type":27,"tag":125,"props":5173,"children":5174},{},[],{"type":27,"tag":129,"props":5176,"children":5178},{"id":5177},"十最关键的一次会议怎么拿到管理层支持",[5179],{"type":33,"value":5180},"十、最关键的一次会议：怎么拿到管理层支持",{"type":27,"tag":141,"props":5182,"children":5184},{"id":5183},"决策点-11重构提案必须用业务语言而不是技术语言",[5185],{"type":33,"value":5186},"决策点 11：重构提案必须用业务语言，而不是技术语言",{"type":27,"tag":35,"props":5188,"children":5189},{},[5190],{"type":33,"value":5191},"如果你去和管理层说：",{"type":27,"tag":83,"props":5193,"children":5194},{},[5195,5200,5205],{"type":27,"tag":87,"props":5196,"children":5197},{},[5198],{"type":33,"value":5199},"Vuex 太重了",{"type":27,"tag":87,"props":5201,"children":5202},{},[5203],{"type":33,"value":5204},"模块边界不清晰",{"type":27,"tag":87,"props":5206,"children":5207},{},[5208],{"type":33,"value":5209},"BFF 缺少防腐层",{"type":27,"tag":35,"props":5211,"children":5212},{},[5213],{"type":33,"value":5214},"大概率没人点头。",{"type":27,"tag":35,"props":5216,"children":5217},{},[5218],{"type":33,"value":5219},"我们最后拿到支持，是因为提案写成了下面这种：",{"type":27,"tag":193,"props":5221,"children":5222},{},[5223,5248],{"type":27,"tag":197,"props":5224,"children":5225},{},[5226],{"type":27,"tag":201,"props":5227,"children":5228},{},[5229,5233,5238,5243],{"type":27,"tag":205,"props":5230,"children":5231},{},[5232],{"type":33,"value":855},{"type":27,"tag":205,"props":5234,"children":5235},{"align":358},[5236],{"type":33,"value":5237},"当前损失",{"type":27,"tag":205,"props":5239,"children":5240},{"align":358},[5241],{"type":33,"value":5242},"重构后预期",{"type":27,"tag":205,"props":5244,"children":5245},{},[5246],{"type":33,"value":5247},"对业务的意义",{"type":27,"tag":221,"props":5249,"children":5250},{},[5251,5274,5297,5320],{"type":27,"tag":201,"props":5252,"children":5253},{},[5254,5259,5264,5269],{"type":27,"tag":228,"props":5255,"children":5256},{},[5257],{"type":33,"value":5258},"需求周期拉长",{"type":27,"tag":228,"props":5260,"children":5261},{"align":358},[5262],{"type":33,"value":5263},"每月少做约 8 个需求点",{"type":27,"tag":228,"props":5265,"children":5266},{"align":358},[5267],{"type":33,"value":5268},"缩回 20%-30%",{"type":27,"tag":228,"props":5270,"children":5271},{},[5272],{"type":33,"value":5273},"提高交付量",{"type":27,"tag":201,"props":5275,"children":5276},{},[5277,5282,5287,5292],{"type":27,"tag":228,"props":5278,"children":5279},{},[5280],{"type":33,"value":5281},"大促冻结过长",{"type":27,"tag":228,"props":5283,"children":5284},{"align":358},[5285],{"type":33,"value":5286},"活动窗口被压缩",{"type":27,"tag":228,"props":5288,"children":5289},{"align":358},[5290],{"type":33,"value":5291},"冻结从 4 天降到 2 天",{"type":27,"tag":228,"props":5293,"children":5294},{},[5295],{"type":33,"value":5296},"增加运营空间",{"type":27,"tag":201,"props":5298,"children":5299},{},[5300,5305,5310,5315],{"type":27,"tag":228,"props":5301,"children":5302},{},[5303],{"type":33,"value":5304},"线上热修复频繁",{"type":27,"tag":228,"props":5306,"children":5307},{"align":358},[5308],{"type":33,"value":5309},"团队被动救火",{"type":27,"tag":228,"props":5311,"children":5312},{"align":358},[5313],{"type":33,"value":5314},"月热修减少 50%",{"type":27,"tag":228,"props":5316,"children":5317},{},[5318],{"type":33,"value":5319},"降低事故成本",{"type":27,"tag":201,"props":5321,"children":5322},{},[5323,5328,5333,5338],{"type":27,"tag":228,"props":5324,"children":5325},{},[5326],{"type":33,"value":5327},"页面性能变差",{"type":27,"tag":228,"props":5329,"children":5330},{"align":358},[5331],{"type":33,"value":5332},"转化率承压",{"type":27,"tag":228,"props":5334,"children":5335},{"align":358},[5336],{"type":33,"value":5337},"首屏 P75 降 25%",{"type":27,"tag":228,"props":5339,"children":5340},{},[5341],{"type":33,"value":5342},"直接影响成交",{"type":27,"tag":35,"props":5344,"children":5345},{},[5346],{"type":33,"value":5347},"同时我们承诺了三件事：",{"type":27,"tag":153,"props":5349,"children":5350},{},[5351,5361,5371],{"type":27,"tag":87,"props":5352,"children":5353},{},[5354,5359],{"type":27,"tag":70,"props":5355,"children":5356},{},[5357],{"type":33,"value":5358},"只做 6 周",{"type":33,"value":5360},"，不是无限期项目",{"type":27,"tag":87,"props":5362,"children":5363},{},[5364,5369],{"type":27,"tag":70,"props":5365,"children":5366},{},[5367],{"type":33,"value":5368},"业务不停",{"type":33,"value":5370},"，不影响正常版本节奏",{"type":27,"tag":87,"props":5372,"children":5373},{},[5374,5379],{"type":27,"tag":70,"props":5375,"children":5376},{},[5377],{"type":33,"value":5378},"每周给数据",{"type":33,"value":5380},"，随时决定是否继续",{"type":27,"tag":35,"props":5382,"children":5383},{},[5384],{"type":33,"value":5385},"这类项目想拿资源，最重要的不是你说得多专业，而是让老板看到：",{"type":27,"tag":551,"props":5387,"children":5388},{},[5389],{"type":27,"tag":35,"props":5390,"children":5391},{},[5392],{"type":33,"value":5393},"这不是“技术想折腾”，而是在买回组织效率。",{"type":27,"tag":125,"props":5395,"children":5396},{},[],{"type":27,"tag":129,"props":5398,"children":5400},{"id":5399},"十一切换那一周真正考验不是代码而是纪律",[5401],{"type":33,"value":5402},"十一、切换那一周：真正考验不是代码，而是纪律",{"type":27,"tag":141,"props":5404,"children":5406},{"id":5405},"决策点-12切换必须有明确的回滚剧本",[5407],{"type":33,"value":5408},"决策点 12：切换必须有明确的回滚剧本",{"type":27,"tag":35,"props":5410,"children":5411},{},[5412],{"type":33,"value":5413},"第 6 周切全量前，我们写了一份回滚 Runbook，只回答 3 个问题：",{"type":27,"tag":153,"props":5415,"children":5416},{},[5417,5422,5427],{"type":27,"tag":87,"props":5418,"children":5419},{},[5420],{"type":33,"value":5421},"什么指标触发回滚？",{"type":27,"tag":87,"props":5423,"children":5424},{},[5425],{"type":33,"value":5426},"谁拍板？",{"type":27,"tag":87,"props":5428,"children":5429},{},[5430],{"type":33,"value":5431},"多久能回去？",{"type":27,"tag":35,"props":5433,"children":5434},{},[5435],{"type":33,"value":5436},"回滚条件很具体：",{"type":27,"tag":83,"props":5438,"children":5439},{},[5440,5445,5450,5455],{"type":27,"tag":87,"props":5441,"children":5442},{},[5443],{"type":33,"value":5444},"价格差异率 > 0.1%",{"type":27,"tag":87,"props":5446,"children":5447},{},[5448],{"type":33,"value":5449},"结算转化率 30 分钟内下降 > 2%",{"type":27,"tag":87,"props":5451,"children":5452},{},[5453],{"type":33,"value":5454},"商品详情页 JS 错误率 > 0.5%",{"type":27,"tag":87,"props":5456,"children":5457},{},[5458],{"type":33,"value":5459},"客服工单 1 小时内异常增长",{"type":27,"tag":141,"props":5461,"children":5463},{"id":5462},"_111-发布剧本",[5464],{"type":33,"value":5465},"11.1 发布剧本",{"type":27,"tag":1011,"props":5467,"children":5469},{"className":1013,"code":5468,"language":33,"meta":7,"style":7},"T-2 天：完成全量回归\nT-1 天：10% -> 30% 灰度\nT 日 10:00：30% -> 60%\nT 日 14:00：观察四小时核心指标\nT 日 18:00：60% -> 100%\nT 日 18:10：冻结非必要发布\nT+1 天：删除旧分支上的应急 patch only 路径\n",[5470],{"type":27,"tag":51,"props":5471,"children":5472},{"__ignoreMap":7},[5473,5481,5489,5497,5505,5513,5521],{"type":27,"tag":1020,"props":5474,"children":5475},{"class":1022,"line":1023},[5476],{"type":27,"tag":1020,"props":5477,"children":5478},{},[5479],{"type":33,"value":5480},"T-2 天：完成全量回归\n",{"type":27,"tag":1020,"props":5482,"children":5483},{"class":1022,"line":20},[5484],{"type":27,"tag":1020,"props":5485,"children":5486},{},[5487],{"type":33,"value":5488},"T-1 天：10% -> 30% 灰度\n",{"type":27,"tag":1020,"props":5490,"children":5491},{"class":1022,"line":1040},[5492],{"type":27,"tag":1020,"props":5493,"children":5494},{},[5495],{"type":33,"value":5496},"T 日 10:00：30% -> 60%\n",{"type":27,"tag":1020,"props":5498,"children":5499},{"class":1022,"line":1049},[5500],{"type":27,"tag":1020,"props":5501,"children":5502},{},[5503],{"type":33,"value":5504},"T 日 14:00：观察四小时核心指标\n",{"type":27,"tag":1020,"props":5506,"children":5507},{"class":1022,"line":1058},[5508],{"type":27,"tag":1020,"props":5509,"children":5510},{},[5511],{"type":33,"value":5512},"T 日 18:00：60% -> 100%\n",{"type":27,"tag":1020,"props":5514,"children":5515},{"class":1022,"line":1067},[5516],{"type":27,"tag":1020,"props":5517,"children":5518},{},[5519],{"type":33,"value":5520},"T 日 18:10：冻结非必要发布\n",{"type":27,"tag":1020,"props":5522,"children":5523},{"class":1022,"line":1076},[5524],{"type":27,"tag":1020,"props":5525,"children":5526},{},[5527],{"type":33,"value":5528},"T+1 天：删除旧分支上的应急 patch only 路径\n",{"type":27,"tag":141,"props":5530,"children":5532},{"id":5531},"_112-真正发生了什么",[5533],{"type":33,"value":5534},"11.2 真正发生了什么",{"type":27,"tag":35,"props":5536,"children":5537},{},[5538],{"type":33,"value":5539},"切 60% 时，确实出了一个问题：",{"type":27,"tag":35,"props":5541,"children":5542},{},[5543],{"type":33,"value":5544},"某类“预售 + 店铺券 + 跨店满减”的组合活动，在购物车页的优惠文案展示顺序错了，价格没错，但文案顺序和老逻辑不一致。",{"type":27,"tag":35,"props":5546,"children":5547},{},[5548],{"type":33,"value":5549},"如果没有预先定义“价格问题”和“展示问题”的处置优先级，现场会很乱。",{"type":27,"tag":35,"props":5551,"children":5552},{},[5553],{"type":33,"value":5554},"最终处理：",{"type":27,"tag":83,"props":5556,"children":5557},{},[5558,5563,5568,5573],{"type":27,"tag":87,"props":5559,"children":5560},{},[5561],{"type":33,"value":5562},"价格逻辑不回滚",{"type":27,"tag":87,"props":5564,"children":5565},{},[5566],{"type":33,"value":5567},"文案映射临时 patch",{"type":27,"tag":87,"props":5569,"children":5570},{},[5571],{"type":33,"value":5572},"继续停在 60% 观察 2 小时",{"type":27,"tag":87,"props":5574,"children":5575},{},[5576],{"type":33,"value":5577},"当晚 21:30 再推进到 100%",{"type":27,"tag":35,"props":5579,"children":5580},{},[5581],{"type":33,"value":5582},"这里的经验很重要：",{"type":27,"tag":551,"props":5584,"children":5585},{},[5586],{"type":27,"tag":35,"props":5587,"children":5588},{},[5589],{"type":33,"value":5590},"灰度不是为了“证明你没问题”，而是为了“让你带着问题也能稳住局面”。",{"type":27,"tag":125,"props":5592,"children":5593},{},[],{"type":27,"tag":129,"props":5595,"children":5597},{"id":5596},"十二六周后我们到底换回了什么",[5598],{"type":33,"value":5599},"十二、六周后，我们到底换回了什么",{"type":27,"tag":35,"props":5601,"children":5602},{},[5603],{"type":33,"value":5604},"重构不是做完 merge request 就算结束。",{"type":27,"tag":35,"props":5606,"children":5607},{},[5608],{"type":33,"value":5609},"最后看的是结果。",{"type":27,"tag":141,"props":5611,"children":5613},{"id":5612},"_121-技术指标变化",[5614],{"type":33,"value":5615},"12.1 技术指标变化",{"type":27,"tag":193,"props":5617,"children":5618},{},[5619,5642],{"type":27,"tag":197,"props":5620,"children":5621},{},[5622],{"type":27,"tag":201,"props":5623,"children":5624},{},[5625,5629,5633,5638],{"type":27,"tag":205,"props":5626,"children":5627},{},[5628],{"type":33,"value":355},{"type":27,"tag":205,"props":5630,"children":5631},{"align":358},[5632],{"type":33,"value":366},{"type":27,"tag":205,"props":5634,"children":5635},{"align":358},[5636],{"type":33,"value":5637},"重构后",{"type":27,"tag":205,"props":5639,"children":5640},{"align":358},[5641],{"type":33,"value":371},{"type":27,"tag":221,"props":5643,"children":5644},{},[5645,5668,5690,5712,5735,5758],{"type":27,"tag":201,"props":5646,"children":5647},{},[5648,5653,5658,5663],{"type":27,"tag":228,"props":5649,"children":5650},{},[5651],{"type":33,"value":5652},"商品详情页核心文件最大行数",{"type":27,"tag":228,"props":5654,"children":5655},{"align":358},[5656],{"type":33,"value":5657},"1430",{"type":27,"tag":228,"props":5659,"children":5660},{"align":358},[5661],{"type":33,"value":5662},"220",{"type":27,"tag":228,"props":5664,"children":5665},{"align":358},[5666],{"type":33,"value":5667},"-84.6%",{"type":27,"tag":201,"props":5669,"children":5670},{},[5671,5676,5680,5685],{"type":27,"tag":228,"props":5672,"children":5673},{},[5674],{"type":33,"value":5675},"价格规则重复实现处数",{"type":27,"tag":228,"props":5677,"children":5678},{"align":358},[5679],{"type":33,"value":456},{"type":27,"tag":228,"props":5681,"children":5682},{"align":358},[5683],{"type":33,"value":5684},"1",{"type":27,"tag":228,"props":5686,"children":5687},{"align":358},[5688],{"type":33,"value":5689},"-66.7%",{"type":27,"tag":201,"props":5691,"children":5692},{},[5693,5698,5702,5707],{"type":27,"tag":228,"props":5694,"children":5695},{},[5696],{"type":33,"value":5697},"首屏 JS 包体积",{"type":27,"tag":228,"props":5699,"children":5700},{"align":358},[5701],{"type":33,"value":392},{"type":27,"tag":228,"props":5703,"children":5704},{"align":358},[5705],{"type":33,"value":5706},"540KB",{"type":27,"tag":228,"props":5708,"children":5709},{"align":358},[5710],{"type":33,"value":5711},"-39.3%",{"type":27,"tag":201,"props":5713,"children":5714},{},[5715,5720,5725,5730],{"type":27,"tag":228,"props":5716,"children":5717},{},[5718],{"type":33,"value":5719},"详情页首屏时间 P75",{"type":27,"tag":228,"props":5721,"children":5722},{"align":358},[5723],{"type":33,"value":5724},"2.8s",{"type":27,"tag":228,"props":5726,"children":5727},{"align":358},[5728],{"type":33,"value":5729},"1.9s",{"type":27,"tag":228,"props":5731,"children":5732},{"align":358},[5733],{"type":33,"value":5734},"-32.1%",{"type":27,"tag":201,"props":5736,"children":5737},{},[5738,5743,5748,5753],{"type":27,"tag":228,"props":5739,"children":5740},{},[5741],{"type":33,"value":5742},"构建时间",{"type":27,"tag":228,"props":5744,"children":5745},{"align":358},[5746],{"type":33,"value":5747},"11m 20s",{"type":27,"tag":228,"props":5749,"children":5750},{"align":358},[5751],{"type":33,"value":5752},"6m 40s",{"type":27,"tag":228,"props":5754,"children":5755},{"align":358},[5756],{"type":33,"value":5757},"-41.2%",{"type":27,"tag":201,"props":5759,"children":5760},{},[5761,5766,5771,5776],{"type":27,"tag":228,"props":5762,"children":5763},{},[5764],{"type":33,"value":5765},"单测覆盖率（关键模块）",{"type":27,"tag":228,"props":5767,"children":5768},{"align":358},[5769],{"type":33,"value":5770},"18%",{"type":27,"tag":228,"props":5772,"children":5773},{"align":358},[5774],{"type":33,"value":5775},"71%",{"type":27,"tag":228,"props":5777,"children":5778},{"align":358},[5779],{"type":33,"value":5780},"+53pt",{"type":27,"tag":141,"props":5782,"children":5784},{"id":5783},"_122-团队效率变化",[5785],{"type":33,"value":5786},"12.2 团队效率变化",{"type":27,"tag":193,"props":5788,"children":5789},{},[5790,5812],{"type":27,"tag":197,"props":5791,"children":5792},{},[5793],{"type":27,"tag":201,"props":5794,"children":5795},{},[5796,5800,5804,5808],{"type":27,"tag":205,"props":5797,"children":5798},{},[5799],{"type":33,"value":355},{"type":27,"tag":205,"props":5801,"children":5802},{"align":358},[5803],{"type":33,"value":366},{"type":27,"tag":205,"props":5805,"children":5806},{"align":358},[5807],{"type":33,"value":5637},{"type":27,"tag":205,"props":5809,"children":5810},{"align":358},[5811],{"type":33,"value":371},{"type":27,"tag":221,"props":5813,"children":5814},{},[5815,5836,5859,5881],{"type":27,"tag":201,"props":5816,"children":5817},{},[5818,5822,5826,5831],{"type":27,"tag":228,"props":5819,"children":5820},{},[5821],{"type":33,"value":428},{"type":27,"tag":228,"props":5823,"children":5824},{"align":358},[5825],{"type":33,"value":438},{"type":27,"tag":228,"props":5827,"children":5828},{"align":358},[5829],{"type":33,"value":5830},"42 分钟",{"type":27,"tag":228,"props":5832,"children":5833},{"align":358},[5834],{"type":33,"value":5835},"-56.7%",{"type":27,"tag":201,"props":5837,"children":5838},{},[5839,5844,5849,5854],{"type":27,"tag":228,"props":5840,"children":5841},{},[5842],{"type":33,"value":5843},"需求平均交付周期",{"type":27,"tag":228,"props":5845,"children":5846},{"align":358},[5847],{"type":33,"value":5848},"11.5 天",{"type":27,"tag":228,"props":5850,"children":5851},{"align":358},[5852],{"type":33,"value":5853},"7.2 天",{"type":27,"tag":228,"props":5855,"children":5856},{"align":358},[5857],{"type":33,"value":5858},"-37.4%",{"type":27,"tag":201,"props":5860,"children":5861},{},[5862,5867,5871,5876],{"type":27,"tag":228,"props":5863,"children":5864},{},[5865],{"type":33,"value":5866},"月热修复次数",{"type":27,"tag":228,"props":5868,"children":5869},{"align":358},[5870],{"type":33,"value":461},{"type":27,"tag":228,"props":5872,"children":5873},{"align":358},[5874],{"type":33,"value":5875},"4",{"type":27,"tag":228,"props":5877,"children":5878},{"align":358},[5879],{"type":33,"value":5880},"-63.6%",{"type":27,"tag":201,"props":5882,"children":5883},{},[5884,5889,5893,5898],{"type":27,"tag":228,"props":5885,"children":5886},{},[5887],{"type":33,"value":5888},"新人独立承担小需求时间",{"type":27,"tag":228,"props":5890,"children":5891},{"align":358},[5892],{"type":33,"value":507},{"type":27,"tag":228,"props":5894,"children":5895},{"align":358},[5896],{"type":33,"value":5897},"6 天",{"type":27,"tag":228,"props":5899,"children":5900},{"align":358},[5901],{"type":33,"value":5902},"-57.1%",{"type":27,"tag":141,"props":5904,"children":5906},{"id":5905},"_123-业务指标变化",[5907],{"type":33,"value":5908},"12.3 业务指标变化",{"type":27,"tag":193,"props":5910,"children":5911},{},[5912,5934],{"type":27,"tag":197,"props":5913,"children":5914},{},[5915],{"type":27,"tag":201,"props":5916,"children":5917},{},[5918,5922,5926,5930],{"type":27,"tag":205,"props":5919,"children":5920},{},[5921],{"type":33,"value":355},{"type":27,"tag":205,"props":5923,"children":5924},{"align":358},[5925],{"type":33,"value":366},{"type":27,"tag":205,"props":5927,"children":5928},{"align":358},[5929],{"type":33,"value":5637},{"type":27,"tag":205,"props":5931,"children":5932},{"align":358},[5933],{"type":33,"value":371},{"type":27,"tag":221,"props":5935,"children":5936},{},[5937,5960,5982],{"type":27,"tag":201,"props":5938,"children":5939},{},[5940,5945,5950,5955],{"type":27,"tag":228,"props":5941,"children":5942},{},[5943],{"type":33,"value":5944},"结算页转化率",{"type":27,"tag":228,"props":5946,"children":5947},{"align":358},[5948],{"type":33,"value":5949},"41.8%",{"type":27,"tag":228,"props":5951,"children":5952},{"align":358},[5953],{"type":33,"value":5954},"43.1%",{"type":27,"tag":228,"props":5956,"children":5957},{"align":358},[5958],{"type":33,"value":5959},"+1.3pt",{"type":27,"tag":201,"props":5961,"children":5962},{},[5963,5968,5972,5977],{"type":27,"tag":228,"props":5964,"children":5965},{},[5966],{"type":33,"value":5967},"大促冻结时长",{"type":27,"tag":228,"props":5969,"children":5970},{"align":358},[5971],{"type":33,"value":484},{"type":27,"tag":228,"props":5973,"children":5974},{"align":358},[5975],{"type":33,"value":5976},"2 天",{"type":27,"tag":228,"props":5978,"children":5979},{"align":358},[5980],{"type":33,"value":5981},"-50%",{"type":27,"tag":201,"props":5983,"children":5984},{},[5985,5990,5995,6000],{"type":27,"tag":228,"props":5986,"children":5987},{},[5988],{"type":33,"value":5989},"价格相关客服工单 / 周",{"type":27,"tag":228,"props":5991,"children":5992},{"align":358},[5993],{"type":33,"value":5994},"128",{"type":27,"tag":228,"props":5996,"children":5997},{"align":358},[5998],{"type":33,"value":5999},"51",{"type":27,"tag":228,"props":6001,"children":6002},{"align":358},[6003],{"type":33,"value":6004},"-60.2%",{"type":27,"tag":35,"props":6006,"children":6007},{},[6008],{"type":33,"value":6009},"这些数字不代表“重构万能”。",{"type":27,"tag":35,"props":6011,"children":6012},{},[6013],{"type":33,"value":6014},"它们只说明一件事：",{"type":27,"tag":551,"props":6016,"children":6017},{},[6018],{"type":27,"tag":35,"props":6019,"children":6020},{},[6021],{"type":33,"value":6022},"当你把结构、职责、切换策略和观测体系一起重做，系统会重新变得可控。",{"type":27,"tag":125,"props":6024,"children":6025},{},[],{"type":27,"tag":129,"props":6027,"children":6029},{"id":6028},"十三这次重构最值钱的-7-个教训",[6030],{"type":33,"value":6031},"十三、这次重构最值钱的 7 个教训",{"type":27,"tag":141,"props":6033,"children":6035},{"id":6034},"教训-1不要从最烂的文件开始从最值得的链路开始",[6036],{"type":33,"value":6037},"教训 1：不要从“最烂的文件”开始，从“最值得的链路”开始",{"type":27,"tag":35,"props":6039,"children":6040},{},[6041],{"type":33,"value":6042},"最烂的地方往往边界最糊，先碰容易把自己拖死。",{"type":27,"tag":141,"props":6044,"children":6046},{"id":6045},"教训-2先做口径统一再做页面拆分",[6047],{"type":33,"value":6048},"教训 2：先做口径统一，再做页面拆分",{"type":27,"tag":35,"props":6050,"children":6051},{},[6052],{"type":33,"value":6053},"接口口径不统一，前端再怎么模块化也只是换地方写脏逻辑。",{"type":27,"tag":141,"props":6055,"children":6057},{"id":6056},"教训-3没有开关和影子比对就不要谈渐进重构",[6058],{"type":33,"value":6059},"教训 3：没有开关和影子比对，就不要谈渐进重构",{"type":27,"tag":35,"props":6061,"children":6062},{},[6063],{"type":33,"value":6064},"你必须允许新旧逻辑并行存在一段时间。",{"type":27,"tag":141,"props":6066,"children":6068},{"id":6067},"教训-4团队边界要和代码边界对齐",[6069],{"type":33,"value":6070},"教训 4：团队边界要和代码边界对齐",{"type":27,"tag":35,"props":6072,"children":6073},{},[6074],{"type":33,"value":6075},"否则新结构只是目录层面的自我安慰。",{"type":27,"tag":141,"props":6077,"children":6079},{"id":6078},"教训-5重构项目必须有硬指标不然永远说不清有没有做成",[6080],{"type":33,"value":6081},"教训 5：重构项目必须有硬指标，不然永远说不清有没有做成",{"type":27,"tag":35,"props":6083,"children":6084},{},[6085],{"type":33,"value":6086},"“感觉更好了”不是复盘结论。",{"type":27,"tag":141,"props":6088,"children":6090},{"id":6089},"教训-6不要顺手把所有技术升级一起做了",[6091],{"type":33,"value":6092},"教训 6：不要顺手把所有技术升级一起做了",{"type":27,"tag":35,"props":6094,"children":6095},{},[6096],{"type":33,"value":6097},"重构最怕“顺便”。",{"type":27,"tag":141,"props":6099,"children":6101},{"id":6100},"教训-7回滚剧本要在发布前写不要在事故中现想",[6102],{"type":33,"value":6103},"教训 7：回滚剧本要在发布前写，不要在事故中现想",{"type":27,"tag":35,"props":6105,"children":6106},{},[6107],{"type":33,"value":6108},"真正稳的团队，不是不会出问题，而是出问题时动作很一致。",{"type":27,"tag":125,"props":6110,"children":6111},{},[],{"type":27,"tag":129,"props":6113,"children":6115},{"id":6114},"十四如果你也准备重构可以直接抄这份检查清单",[6116],{"type":33,"value":6117},"十四、如果你也准备重构，可以直接抄这份检查清单",{"type":27,"tag":141,"props":6119,"children":6121},{"id":6120},"启动前检查",[6122],{"type":33,"value":6120},{"type":27,"tag":83,"props":6124,"children":6127},{"className":6125},[6126],"contains-task-list",[6128,6139,6148,6157,6166],{"type":27,"tag":87,"props":6129,"children":6132},{"className":6130},[6131],"task-list-item",[6133,6137],{"type":27,"tag":4210,"props":6134,"children":6136},{"disabled":18,"type":6135},"checkbox",[],{"type":33,"value":6138}," 有没有量化证据证明“现在不动更贵”",{"type":27,"tag":87,"props":6140,"children":6142},{"className":6141},[6131],[6143,6146],{"type":27,"tag":4210,"props":6144,"children":6145},{"disabled":18,"type":6135},[],{"type":33,"value":6147}," 有没有明确主目标，而不是顺便解决一堆问题",{"type":27,"tag":87,"props":6149,"children":6151},{"className":6150},[6131],[6152,6155],{"type":27,"tag":4210,"props":6153,"children":6154},{"disabled":18,"type":6135},[],{"type":33,"value":6156}," 有没有确定首批迁移链路",{"type":27,"tag":87,"props":6158,"children":6160},{"className":6159},[6131],[6161,6164],{"type":27,"tag":4210,"props":6162,"children":6163},{"disabled":18,"type":6135},[],{"type":33,"value":6165}," 有没有统一的指标面板",{"type":27,"tag":87,"props":6167,"children":6169},{"className":6168},[6131],[6170,6173],{"type":27,"tag":4210,"props":6171,"children":6172},{"disabled":18,"type":6135},[],{"type":33,"value":6174}," 有没有可灰度、可回滚的开关能力",{"type":27,"tag":141,"props":6176,"children":6178},{"id":6177},"实施中检查",[6179],{"type":33,"value":6177},{"type":27,"tag":83,"props":6181,"children":6183},{"className":6182},[6126],[6184,6193,6202,6211,6220],{"type":27,"tag":87,"props":6185,"children":6187},{"className":6186},[6131],[6188,6191],{"type":27,"tag":4210,"props":6189,"children":6190},{"disabled":18,"type":6135},[],{"type":33,"value":6192}," 新旧逻辑是否能并行一段时间",{"type":27,"tag":87,"props":6194,"children":6196},{"className":6195},[6131],[6197,6200],{"type":27,"tag":4210,"props":6198,"children":6199},{"disabled":18,"type":6135},[],{"type":33,"value":6201}," 是否建立了模块 owner",{"type":27,"tag":87,"props":6203,"children":6205},{"className":6204},[6131],[6206,6209],{"type":27,"tag":4210,"props":6207,"children":6208},{"disabled":18,"type":6135},[],{"type":33,"value":6210}," 关键规则是否有单测覆盖",{"type":27,"tag":87,"props":6212,"children":6214},{"className":6213},[6131],[6215,6218],{"type":27,"tag":4210,"props":6216,"children":6217},{"disabled":18,"type":6135},[],{"type":33,"value":6219}," 日志字段是否统一",{"type":27,"tag":87,"props":6221,"children":6223},{"className":6222},[6131],[6224,6227],{"type":27,"tag":4210,"props":6225,"children":6226},{"disabled":18,"type":6135},[],{"type":33,"value":6228}," 每周是否能复盘实际收益",{"type":27,"tag":141,"props":6230,"children":6232},{"id":6231},"切换前检查",[6233],{"type":33,"value":6231},{"type":27,"tag":83,"props":6235,"children":6237},{"className":6236},[6126],[6238,6247,6256,6265],{"type":27,"tag":87,"props":6239,"children":6241},{"className":6240},[6131],[6242,6245],{"type":27,"tag":4210,"props":6243,"children":6244},{"disabled":18,"type":6135},[],{"type":33,"value":6246}," 是否写好回滚 Runbook",{"type":27,"tag":87,"props":6248,"children":6250},{"className":6249},[6131],[6251,6254],{"type":27,"tag":4210,"props":6252,"children":6253},{"disabled":18,"type":6135},[],{"type":33,"value":6255}," 是否定义了触发回滚的阈值",{"type":27,"tag":87,"props":6257,"children":6259},{"className":6258},[6131],[6260,6263],{"type":27,"tag":4210,"props":6261,"children":6262},{"disabled":18,"type":6135},[],{"type":33,"value":6264}," 是否区分“展示错误”和“结算错误”的优先级",{"type":27,"tag":87,"props":6266,"children":6268},{"className":6267},[6131],[6269,6272],{"type":27,"tag":4210,"props":6270,"children":6271},{"disabled":18,"type":6135},[],{"type":33,"value":6273}," 是否验证客服、运营、测试都知道应急路径",{"type":27,"tag":125,"props":6275,"children":6276},{},[],{"type":27,"tag":129,"props":6278,"children":6280},{"id":6279},"总结",[6281],{"type":33,"value":6279},{"type":27,"tag":35,"props":6283,"children":6284},{},[6285],{"type":33,"value":6286},"这次电商系统重构，最让我确定的一件事是：",{"type":27,"tag":35,"props":6288,"children":6289},{},[6290],{"type":27,"tag":70,"props":6291,"children":6292},{},[6293],{"type":33,"value":6294},"真正的重构，不是把旧代码删掉，而是把系统重新变成“人能理解、团队能协作、发布能控制”的状态。",{"type":27,"tag":35,"props":6296,"children":6297},{},[6298],{"type":33,"value":6299},"它不是一次性的大扫除，更像是在高速行驶的车上换掉松动的零件。",{"type":27,"tag":35,"props":6301,"children":6302},{},[6303],{"type":33,"value":6304},"你不能指望完全不冒险。",{"type":27,"tag":35,"props":6306,"children":6307},{},[6308],{"type":33,"value":6309},"但你可以做到：",{"type":27,"tag":83,"props":6311,"children":6312},{},[6313,6318,6323],{"type":27,"tag":87,"props":6314,"children":6315},{},[6316],{"type":33,"value":6317},"每一步都可观察",{"type":27,"tag":87,"props":6319,"children":6320},{},[6321],{"type":33,"value":6322},"每一次切换都可回退",{"type":27,"tag":87,"props":6324,"children":6325},{},[6326],{"type":33,"value":6327},"每一个收益都能量化",{"type":27,"tag":35,"props":6329,"children":6330},{},[6331],{"type":33,"value":6332},"这样，重构就不再是“工程师的信仰之战”，而会变成一笔算得清的工程投资。",{"type":27,"tag":35,"props":6334,"children":6335},{},[6336],{"type":33,"value":6337},"最后送你一句很适合重构现场的话：",{"type":27,"tag":551,"props":6339,"children":6340},{},[6341],{"type":27,"tag":35,"props":6342,"children":6343},{},[6344],{"type":33,"value":6345},"系统最危险的时候，不是它已经很乱，而是所有人都习惯了它很乱。",{"type":27,"tag":35,"props":6347,"children":6348},{},[6349],{"type":33,"value":6350},"等大家都把“发版前先拜一下”当成流程的一部分时，说明真的该动刀了。",{"type":27,"tag":6352,"props":6353,"children":6354},"style",{},[6355],{"type":33,"value":6356},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":1040,"depth":1040,"links":6358},[6359,6364,6377,6382,6387,6392,6398,6403,6407,6412,6415,6420,6425,6434,6439],{"id":131,"depth":20,"text":134,"children":6360},[6361,6362,6363],{"id":143,"depth":1040,"text":146},{"id":183,"depth":1040,"text":186},{"id":317,"depth":1040,"text":320},{"id":541,"depth":20,"text":544,"children":6365},[6366,6372],{"id":564,"depth":1040,"text":567,"children":6367},[6368,6369,6370,6371],{"id":576,"depth":1049,"text":579},{"id":587,"depth":1049,"text":590},{"id":605,"depth":1049,"text":608},{"id":616,"depth":1049,"text":619},{"id":645,"depth":1040,"text":648,"children":6373},[6374,6375,6376],{"id":661,"depth":1049,"text":664},{"id":700,"depth":1049,"text":703},{"id":733,"depth":1049,"text":736},{"id":786,"depth":20,"text":789,"children":6378},[6379,6380,6381],{"id":804,"depth":1040,"text":807},{"id":838,"depth":1040,"text":841},{"id":961,"depth":1040,"text":964},{"id":1238,"depth":20,"text":1241,"children":6383},[6384,6385,6386],{"id":1244,"depth":1040,"text":1247},{"id":1343,"depth":1040,"text":1346},{"id":1530,"depth":1040,"text":1533},{"id":1600,"depth":20,"text":1603,"children":6388},[6389,6390,6391],{"id":1606,"depth":1040,"text":1609},{"id":1627,"depth":1040,"text":1630},{"id":1845,"depth":1040,"text":1848},{"id":2383,"depth":20,"text":2386,"children":6393},[6394,6395,6396,6397],{"id":2389,"depth":1040,"text":2392},{"id":2411,"depth":1040,"text":2414},{"id":2473,"depth":1040,"text":2476},{"id":3239,"depth":1040,"text":3242},{"id":3847,"depth":20,"text":3850,"children":6399},[6400,6401,6402],{"id":3853,"depth":1040,"text":3856},{"id":3896,"depth":1040,"text":3899},{"id":4163,"depth":1040,"text":4166},{"id":4480,"depth":20,"text":4483,"children":6404},[6405,6406],{"id":4491,"depth":1040,"text":4494},{"id":4638,"depth":1040,"text":4641},{"id":4711,"depth":20,"text":4714,"children":6408},[6409,6410,6411],{"id":4717,"depth":1040,"text":4720},{"id":4753,"depth":1040,"text":4756},{"id":5025,"depth":1040,"text":5028},{"id":5177,"depth":20,"text":5180,"children":6413},[6414],{"id":5183,"depth":1040,"text":5186},{"id":5399,"depth":20,"text":5402,"children":6416},[6417,6418,6419],{"id":5405,"depth":1040,"text":5408},{"id":5462,"depth":1040,"text":5465},{"id":5531,"depth":1040,"text":5534},{"id":5596,"depth":20,"text":5599,"children":6421},[6422,6423,6424],{"id":5612,"depth":1040,"text":5615},{"id":5783,"depth":1040,"text":5786},{"id":5905,"depth":1040,"text":5908},{"id":6028,"depth":20,"text":6031,"children":6426},[6427,6428,6429,6430,6431,6432,6433],{"id":6034,"depth":1040,"text":6037},{"id":6045,"depth":1040,"text":6048},{"id":6056,"depth":1040,"text":6059},{"id":6067,"depth":1040,"text":6070},{"id":6078,"depth":1040,"text":6081},{"id":6089,"depth":1040,"text":6092},{"id":6100,"depth":1040,"text":6103},{"id":6114,"depth":20,"text":6117,"children":6435},[6436,6437,6438],{"id":6120,"depth":1040,"text":6120},{"id":6177,"depth":1040,"text":6177},{"id":6231,"depth":1040,"text":6231},{"id":6279,"depth":20,"text":6279},"markdown","content:topics:engineering:ecommerce-system-refactor-log.md","content","topics/engineering/ecommerce-system-refactor-log.md","topics/engineering/ecommerce-system-refactor-log","md",1777109948576]