选择国家与语言当前国家: 中国
德勤 Virtual Internship / 任务 05
实习猿原创实训 · 任务 05运营异常工作台交付提案
把前四项证据变成有边界、可估算、可验收的交付方案。
先查看已完成的成果,再使用材料完成自己的交付。
先阅读完整成果材料
learner/materials/stakeholder-brief.md 阅读完整文件
下载文件工作台需求访谈纪要
运营负责人:早上先看尚未交付的到期订单,再看站点与线路。已交付迟交订单用于复盘,不应盖过仍在积压的订单。希望按站点、服务等级和履约状态筛选,打开订单看时间线。需要显示复盘截止时间与数据更新时间。
站点负责人:不能拿不同服务结构的总迟交率直接排绩效。南湾 express 数据少,需要补足后再比较。线路备注只是线索,不能让系统自动把延迟归因给某个员工。
安全负责人:operator 只能读取所属站点,导出另需 supervisor 或 service 权限,服务端每次请求都检查权限和 session。身份来自企业现有身份服务,不新增密码库。屏幕上选择站点不等于获得权限。
交付负责人:第一期做只读工作台、订单证据时间线与受控导出设计;不要加入退款、调度写入或客户通知。上线依赖客户提供身份服务、网关和订单接口。需要估算工时、明确验收、失败处理与回退。没有给定预算、合同 SLA、生产并发数或上线日期,方案须提出待确认项,不自行写成客户已确认。
learner/checkpoints/security-findings.csv 阅读完整文件
下载文件| request_id | at | user | session | finding | status | rows | bytes |
|---|---|---|---|---|---|---|---|
| Q0058 | 2026-09-10T09:41:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0059 | 2026-09-10T09:42:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0060 | 2026-09-10T09:43:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0061 | 2026-09-10T09:44:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0062 | 2026-09-10T09:45:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0063 | 2026-09-10T09:46:00Z | op-7 | sus-7 | unauthorised_export;hub_scope_violation | 200 | 1200 | 96000 |
| Q0069 | 2026-09-10T11:15:00Z | op-2 | expired-2 | expired_or_missing_session | 200 | 50 | 10000 |
learner/checkpoints/standardized-comparison.csv 阅读完整文件
下载文件| hub | standardized_late_rate | status |
|---|---|---|
| 东城 | 0.49024 | 可比较 |
| 南湾 | 待补样本 | |
| 海港 | 0.689189 | 可比较 |
| 西岭 | 0.386363 | 可比较 |
learner/checkpoints/order-review.csv 阅读完整文件
下载文件| order_id | hub | service | route | created_at | due_at | cohort | late_minutes | overdue_minutes |
|---|---|---|---|---|---|---|---|---|
| O0001 | 海港 | standard | R11 | 2026-09-01T06:00:00Z | 2026-09-02T06:00:00Z | cancelled | 0 | 0 |
| O0002 | 海港 | standard | R12 | 2026-09-02T07:00:00Z | 2026-09-03T07:00:00Z | delivered_late | 50 | 0 |
| O0003 | 海港 | standard | R11 | 2026-09-03T08:00:00Z | 2026-09-04T08:00:00Z | on_time | 0 | 0 |
| O0004 | 海港 | standard | R12 | 2026-09-04T09:00:00Z | 2026-09-05T09:00:00Z | on_time | 0 | 0 |
| O0005 | 海港 | standard | R11 | 2026-09-05T10:00:00Z | 2026-09-06T10:00:00Z | delivered_late | 50 | 0 |
| O0006 | 海港 | standard | R12 | 2026-09-06T11:00:00Z | 2026-09-07T11:00:00Z | on_time | 0 | 0 |
| O0007 | 海港 | standard | R11 | 2026-09-07T12:00:00Z | 2026-09-08T12:00:00Z | on_time | 0 | 0 |
| O0008 | 海港 | standard | R12 | 2026-09-08T13:00:00Z | 2026-09-09T13:00:00Z | delivered_late | 50 | 0 |
| O0009 | 海港 | standard | R11 | 2026-09-09T06:00:00Z | 2026-09-10T06:00:00Z | on_time | 0 | 0 |
| O0010 | 海港 | standard | R12 | 2026-09-10T07:00:00Z | 2026-09-11T07:00:00Z | on_time | 0 | 0 |
| O0011 | 海港 | standard | R11 | 2026-09-11T08:00:00Z | 2026-09-12T08:00:00Z | delivered_late | 50 | 0 |
| O0012 | 海港 | standard | R12 | 2026-09-12T09:00:00Z | 2026-09-13T09:00:00Z | on_time | 0 | 0 |
| O0013 | 海港 | standard | R11 | 2026-09-13T10:00:00Z | 2026-09-14T10:00:00Z | on_time | 0 | 0 |
| O0014 | 海港 | standard | R12 | 2026-09-01T11:00:00Z | 2026-09-02T11:00:00Z | delivered_late | 50 | 0 |
| O0015 | 海港 | standard | R11 | 2026-09-02T12:00:00Z | 2026-09-03T12:00:00Z | on_time | 0 | 0 |
| O0016 | 海港 | standard | R12 | 2026-09-03T13:00:00Z | 2026-09-04T13:00:00Z | on_time | 0 | 0 |
| O0017 | 海港 | standard | R11 | 2026-09-04T06:00:00Z | 2026-09-05T06:00:00Z | delivered_late | 50 | 0 |
| O0018 | 海港 | standard | R12 | 2026-09-05T07:00:00Z | 2026-09-06T07:00:00Z | overdue_open | 0 | 12540 |
| O0019 | 海港 | standard | R11 | 2026-09-06T08:00:00Z | 2026-09-07T08:00:00Z | on_time | 0 | 0 |
| O0020 | 海港 | standard | R12 | 2026-09-07T09:00:00Z | 2026-09-08T09:00:00Z | delivered_late | 50 | 0 |
| O0021 | 海港 | standard | R11 | 2026-09-08T10:00:00Z | 2026-09-09T10:00:00Z | on_time | 0 | 0 |
| O0022 | 海港 | standard | R12 | 2026-09-09T11:00:00Z | 2026-09-10T11:00:00Z | on_time | 0 | 0 |
| O0023 | 海港 | standard | R11 | 2026-09-10T12:00:00Z | 2026-09-11T12:00:00Z | delivered_late | 50 | 0 |
| O0024 | 海港 | standard | R12 | 2026-09-11T13:00:00Z | 2026-09-12T13:00:00Z | on_time | 0 | 0 |
| O0025 | 海港 | standard | R11 | 2026-09-12T06:00:00Z | 2026-09-13T06:00:00Z | on_time | 0 | 0 |
| O0026 | 海港 | standard | R12 | 2026-09-13T07:00:00Z | 2026-09-14T07:00:00Z | delivered_late | 50 | 0 |
| O0027 | 海港 | standard | R11 | 2026-09-01T08:00:00Z | 2026-09-02T08:00:00Z | on_time | 0 | 0 |
| O0028 | 海港 | standard | R12 | 2026-09-02T09:00:00Z | 2026-09-03T09:00:00Z | on_time | 0 | 0 |
| O0029 | 海港 | standard | R11 | 2026-09-03T10:00:00Z | 2026-09-04T10:00:00Z | delivered_late | 50 | 0 |
| O0030 | 海港 | standard | R12 | 2026-09-04T11:00:00Z | 2026-09-05T11:00:00Z | cancelled | 0 | 0 |
| O0031 | 海港 | standard | R11 | 2026-09-05T12:00:00Z | 2026-09-06T12:00:00Z | on_time | 0 | 0 |
| O0032 | 海港 | standard | R12 | 2026-09-06T13:00:00Z | 2026-09-07T13:00:00Z | delivered_late | 50 | 0 |
| O0033 | 海港 | standard | R11 | 2026-09-07T06:00:00Z | 2026-09-08T06:00:00Z | on_time | 0 | 0 |
| O0034 | 海港 | standard | R12 | 2026-09-08T07:00:00Z | 2026-09-09T07:00:00Z | on_time | 0 | 0 |
| O0035 | 海港 | standard | R11 | 2026-09-09T08:00:00Z | 2026-09-10T08:00:00Z | overdue_open | 0 | 6720 |
| O0036 | 海港 | standard | R12 | 2026-09-10T09:00:00Z | 2026-09-11T09:00:00Z | on_time | 0 | 0 |
| O0037 | 海港 | standard | R11 | 2026-09-11T10:00:00Z | 2026-09-12T10:00:00Z | on_time | 0 | 0 |
| O0038 | 海港 | standard | R12 | 2026-09-12T11:00:00Z | 2026-09-13T11:00:00Z | delivered_late | 50 | 0 |
| O0039 | 海港 | standard | R11 | 2026-09-13T12:00:00Z | 2026-09-14T12:00:00Z | on_time | 0 | 0 |
| O0040 | 海港 | standard | R12 | 2026-09-14T21:00:00Z | 2026-09-15T21:00:00Z | not_mature | 0 | 0 |
| O0041 | 海港 | express | R11 | 2026-09-01T06:00:00Z | 2026-09-01T14:00:00Z | cancelled | 0 | 0 |
| O0042 | 海港 | express | R12 | 2026-09-02T07:00:00Z | 2026-09-02T15:00:00Z | delivered_late | 50 | 0 |
| O0043 | 海港 | express | R11 | 2026-09-03T08:00:00Z | 2026-09-03T16:00:00Z | delivered_late | 50 | 0 |
| O0044 | 海港 | express | R12 | 2026-09-04T09:00:00Z | 2026-09-04T17:00:00Z | delivered_late | 50 | 0 |
| O0045 | 海港 | express | R11 | 2026-09-05T10:00:00Z | 2026-09-05T18:00:00Z | delivered_late | 50 | 0 |
| O0046 | 海港 | express | R12 | 2026-09-06T11:00:00Z | 2026-09-06T19:00:00Z | delivered_late | 50 | 0 |
| O0047 | 海港 | express | R11 | 2026-09-07T12:00:00Z | 2026-09-07T20:00:00Z | delivered_late | 50 | 0 |
| O0048 | 海港 | express | R12 | 2026-09-08T13:00:00Z | 2026-09-08T21:00:00Z | delivered_late | 50 | 0 |
| O0049 | 海港 | express | R11 | 2026-09-09T06:00:00Z | 2026-09-09T14:00:00Z | delivered_late | 50 | 0 |
| O0050 | 海港 | express | R12 | 2026-09-10T07:00:00Z | 2026-09-10T15:00:00Z | delivered_late | 50 | 0 |
| O0051 | 海港 | express | R11 | 2026-09-11T08:00:00Z | 2026-09-11T16:00:00Z | delivered_late | 50 | 0 |
| O0052 | 海港 | express | R12 | 2026-09-12T09:00:00Z | 2026-09-12T17:00:00Z | delivered_late | 50 | 0 |
| O0053 | 海港 | express | R11 | 2026-09-13T10:00:00Z | 2026-09-13T18:00:00Z | delivered_late | 50 | 0 |
| O0054 | 海港 | express | R12 | 2026-09-01T11:00:00Z | 2026-09-01T19:00:00Z | delivered_late | 50 | 0 |
| O0055 | 海港 | express | R11 | 2026-09-02T12:00:00Z | 2026-09-02T20:00:00Z | delivered_late | 50 | 0 |
| O0056 | 海港 | express | R12 | 2026-09-03T13:00:00Z | 2026-09-03T21:00:00Z | delivered_late | 50 | 0 |
| O0057 | 海港 | express | R11 | 2026-09-04T06:00:00Z | 2026-09-04T14:00:00Z | delivered_late | 50 | 0 |
| O0058 | 海港 | express | R12 | 2026-09-05T07:00:00Z | 2026-09-05T15:00:00Z | overdue_open | 0 | 13500 |
| O0059 | 海港 | express | R11 | 2026-09-06T08:00:00Z | 2026-09-06T16:00:00Z | delivered_late | 50 | 0 |
| O0060 | 海港 | express | R12 | 2026-09-14T21:00:00Z | 2026-09-15T05:00:00Z | not_mature | 0 | 0 |
| O0061 | 东城 | standard | R21 | 2026-09-01T06:00:00Z | 2026-09-02T06:00:00Z | cancelled | 0 | 0 |
| O0062 | 东城 | standard | R22 | 2026-09-02T07:00:00Z | 2026-09-03T07:00:00Z | delivered_late | 70 | 0 |
| O0063 | 东城 | standard | R21 | 2026-09-03T08:00:00Z | 2026-09-04T08:00:00Z | on_time | 0 | 0 |
| O0064 | 东城 | standard | R22 | 2026-09-04T09:00:00Z | 2026-09-05T09:00:00Z | on_time | 0 | 0 |
| O0065 | 东城 | standard | R21 | 2026-09-05T10:00:00Z | 2026-09-06T10:00:00Z | on_time | 0 | 0 |
| O0066 | 东城 | standard | R22 | 2026-09-06T11:00:00Z | 2026-09-07T11:00:00Z | delivered_late | 70 | 0 |
| O0067 | 东城 | standard | R21 | 2026-09-07T12:00:00Z | 2026-09-08T12:00:00Z | on_time | 0 | 0 |
| O0068 | 东城 | standard | R22 | 2026-09-08T13:00:00Z | 2026-09-09T13:00:00Z | on_time | 0 | 0 |
| O0069 | 东城 | standard | R21 | 2026-09-09T06:00:00Z | 2026-09-10T06:00:00Z | on_time | 0 | 0 |
| O0070 | 东城 | standard | R22 | 2026-09-10T07:00:00Z | 2026-09-11T07:00:00Z | delivered_late | 70 | 0 |
| O0071 | 东城 | standard | R21 | 2026-09-11T08:00:00Z | 2026-09-12T08:00:00Z | on_time | 0 | 0 |
| O0072 | 东城 | standard | R22 | 2026-09-12T09:00:00Z | 2026-09-13T09:00:00Z | on_time | 0 | 0 |
| O0073 | 东城 | standard | R21 | 2026-09-13T10:00:00Z | 2026-09-14T10:00:00Z | on_time | 0 | 0 |
| O0074 | 东城 | standard | R22 | 2026-09-01T11:00:00Z | 2026-09-02T11:00:00Z | delivered_late | 70 | 0 |
| O0075 | 东城 | standard | R21 | 2026-09-02T12:00:00Z | 2026-09-03T12:00:00Z | on_time | 0 | 0 |
| O0076 | 东城 | standard | R22 | 2026-09-03T13:00:00Z | 2026-09-04T13:00:00Z | on_time | 0 | 0 |
| O0077 | 东城 | standard | R21 | 2026-09-04T06:00:00Z | 2026-09-05T06:00:00Z | on_time | 0 | 0 |
| O0078 | 东城 | standard | R22 | 2026-09-05T07:00:00Z | 2026-09-06T07:00:00Z | overdue_open | 0 | 12540 |
| O0079 | 东城 | standard | R21 | 2026-09-06T08:00:00Z | 2026-09-07T08:00:00Z | on_time | 0 | 0 |
| O0080 | 东城 | standard | R22 | 2026-09-14T21:00:00Z | 2026-09-15T21:00:00Z | not_mature | 0 | 0 |
| O0081 | 东城 | express | R21 | 2026-09-01T06:00:00Z | 2026-09-01T14:00:00Z | cancelled | 0 | 0 |
| O0082 | 东城 | express | R22 | 2026-09-02T07:00:00Z | 2026-09-02T15:00:00Z | delivered_late | 70 | 0 |
| O0083 | 东城 | express | R21 | 2026-09-03T08:00:00Z | 2026-09-03T16:00:00Z | on_time | 0 | 0 |
| O0084 | 东城 | express | R22 | 2026-09-04T09:00:00Z | 2026-09-04T17:00:00Z | delivered_late | 70 | 0 |
| O0085 | 东城 | express | R21 | 2026-09-05T10:00:00Z | 2026-09-05T18:00:00Z | delivered_late | 70 | 0 |
| O0086 | 东城 | express | R22 | 2026-09-06T11:00:00Z | 2026-09-06T19:00:00Z | on_time | 0 | 0 |
| O0087 | 东城 | express | R21 | 2026-09-07T12:00:00Z | 2026-09-07T20:00:00Z | delivered_late | 70 | 0 |
| O0088 | 东城 | express | R22 | 2026-09-08T13:00:00Z | 2026-09-08T21:00:00Z | delivered_late | 70 | 0 |
| O0089 | 东城 | express | R21 | 2026-09-09T06:00:00Z | 2026-09-09T14:00:00Z | on_time | 0 | 0 |
| O0090 | 东城 | express | R22 | 2026-09-10T07:00:00Z | 2026-09-10T15:00:00Z | delivered_late | 70 | 0 |
| O0091 | 东城 | express | R21 | 2026-09-11T08:00:00Z | 2026-09-11T16:00:00Z | delivered_late | 70 | 0 |
| O0092 | 东城 | express | R22 | 2026-09-12T09:00:00Z | 2026-09-12T17:00:00Z | on_time | 0 | 0 |
| O0093 | 东城 | express | R21 | 2026-09-13T10:00:00Z | 2026-09-13T18:00:00Z | delivered_late | 70 | 0 |
| O0094 | 东城 | express | R22 | 2026-09-01T11:00:00Z | 2026-09-01T19:00:00Z | delivered_late | 70 | 0 |
| O0095 | 东城 | express | R21 | 2026-09-02T12:00:00Z | 2026-09-02T20:00:00Z | on_time | 0 | 0 |
| O0096 | 东城 | express | R22 | 2026-09-03T13:00:00Z | 2026-09-03T21:00:00Z | delivered_late | 70 | 0 |
| O0097 | 东城 | express | R21 | 2026-09-04T06:00:00Z | 2026-09-04T14:00:00Z | delivered_late | 70 | 0 |
| O0098 | 东城 | express | R22 | 2026-09-05T07:00:00Z | 2026-09-05T15:00:00Z | overdue_open | 0 | 13500 |
| O0099 | 东城 | express | R21 | 2026-09-06T08:00:00Z | 2026-09-06T16:00:00Z | delivered_late | 70 | 0 |
| O0100 | 东城 | express | R22 | 2026-09-07T09:00:00Z | 2026-09-07T17:00:00Z | delivered_late | 70 | 0 |
| O0101 | 东城 | express | R21 | 2026-09-08T10:00:00Z | 2026-09-08T18:00:00Z | on_time | 0 | 0 |
| O0102 | 东城 | express | R22 | 2026-09-09T11:00:00Z | 2026-09-09T19:00:00Z | delivered_late | 70 | 0 |
| O0103 | 东城 | express | R21 | 2026-09-10T12:00:00Z | 2026-09-10T20:00:00Z | delivered_late | 70 | 0 |
| O0104 | 东城 | express | R22 | 2026-09-11T13:00:00Z | 2026-09-11T21:00:00Z | on_time | 0 | 0 |
| O0105 | 东城 | express | R21 | 2026-09-12T06:00:00Z | 2026-09-12T14:00:00Z | delivered_late | 70 | 0 |
| O0106 | 东城 | express | R22 | 2026-09-13T07:00:00Z | 2026-09-13T15:00:00Z | delivered_late | 70 | 0 |
| O0107 | 东城 | express | R21 | 2026-09-01T08:00:00Z | 2026-09-01T16:00:00Z | on_time | 0 | 0 |
| O0108 | 东城 | express | R22 | 2026-09-02T09:00:00Z | 2026-09-02T17:00:00Z | delivered_late | 70 | 0 |
| O0109 | 东城 | express | R21 | 2026-09-03T10:00:00Z | 2026-09-03T18:00:00Z | delivered_late | 70 | 0 |
| O0110 | 东城 | express | R22 | 2026-09-04T11:00:00Z | 2026-09-04T19:00:00Z | cancelled | 0 | 0 |
| O0111 | 东城 | express | R21 | 2026-09-05T12:00:00Z | 2026-09-05T20:00:00Z | delivered_late | 70 | 0 |
| O0112 | 东城 | express | R22 | 2026-09-06T13:00:00Z | 2026-09-06T21:00:00Z | delivered_late | 70 | 0 |
| O0113 | 东城 | express | R21 | 2026-09-07T06:00:00Z | 2026-09-07T14:00:00Z | on_time | 0 | 0 |
| O0114 | 东城 | express | R22 | 2026-09-08T07:00:00Z | 2026-09-08T15:00:00Z | delivered_late | 70 | 0 |
| O0115 | 东城 | express | R21 | 2026-09-09T08:00:00Z | 2026-09-09T16:00:00Z | overdue_open | 0 | 7680 |
| O0116 | 东城 | express | R22 | 2026-09-10T09:00:00Z | 2026-09-10T17:00:00Z | on_time | 0 | 0 |
| O0117 | 东城 | express | R21 | 2026-09-11T10:00:00Z | 2026-09-11T18:00:00Z | delivered_late | 70 | 0 |
| O0118 | 东城 | express | R22 | 2026-09-12T11:00:00Z | 2026-09-12T19:00:00Z | delivered_late | 70 | 0 |
| O0119 | 东城 | express | R21 | 2026-09-13T12:00:00Z | 2026-09-13T20:00:00Z | on_time | 0 | 0 |
| O0120 | 东城 | express | R22 | 2026-09-14T21:00:00Z | 2026-09-15T05:00:00Z | not_mature | 0 | 0 |
| O0121 | 西岭 | standard | R31 | 2026-09-01T06:00:00Z | 2026-09-02T06:00:00Z | cancelled | 0 | 0 |
| O0122 | 西岭 | standard | R32 | 2026-09-02T07:00:00Z | 2026-09-03T07:00:00Z | delivered_late | 90 | 0 |
| O0123 | 西岭 | standard | R31 | 2026-09-03T08:00:00Z | 2026-09-04T08:00:00Z | on_time | 0 | 0 |
| O0124 | 西岭 | standard | R32 | 2026-09-04T09:00:00Z | 2026-09-05T09:00:00Z | on_time | 0 | 0 |
| O0125 | 西岭 | standard | R31 | 2026-09-05T10:00:00Z | 2026-09-06T10:00:00Z | on_time | 0 | 0 |
| O0126 | 西岭 | standard | R32 | 2026-09-06T11:00:00Z | 2026-09-07T11:00:00Z | on_time | 0 | 0 |
| O0127 | 西岭 | standard | R31 | 2026-09-07T12:00:00Z | 2026-09-08T12:00:00Z | delivered_late | 90 | 0 |
| O0128 | 西岭 | standard | R32 | 2026-09-08T13:00:00Z | 2026-09-09T13:00:00Z | on_time | 0 | 0 |
| O0129 | 西岭 | standard | R31 | 2026-09-09T06:00:00Z | 2026-09-10T06:00:00Z | on_time | 0 | 0 |
| O0130 | 西岭 | standard | R32 | 2026-09-10T07:00:00Z | 2026-09-11T07:00:00Z | on_time | 0 | 0 |
| O0131 | 西岭 | standard | R31 | 2026-09-11T08:00:00Z | 2026-09-12T08:00:00Z | on_time | 0 | 0 |
| O0132 | 西岭 | standard | R32 | 2026-09-12T09:00:00Z | 2026-09-13T09:00:00Z | delivered_late | 90 | 0 |
| O0133 | 西岭 | standard | R31 | 2026-09-13T10:00:00Z | 2026-09-14T10:00:00Z | on_time | 0 | 0 |
| O0134 | 西岭 | standard | R32 | 2026-09-01T11:00:00Z | 2026-09-02T11:00:00Z | on_time | 0 | 0 |
| O0135 | 西岭 | standard | R31 | 2026-09-02T12:00:00Z | 2026-09-03T12:00:00Z | on_time | 0 | 0 |
| O0136 | 西岭 | standard | R32 | 2026-09-03T13:00:00Z | 2026-09-04T13:00:00Z | on_time | 0 | 0 |
| O0137 | 西岭 | standard | R31 | 2026-09-04T06:00:00Z | 2026-09-05T06:00:00Z | delivered_late | 90 | 0 |
| O0138 | 西岭 | standard | R32 | 2026-09-05T07:00:00Z | 2026-09-06T07:00:00Z | overdue_open | 0 | 12540 |
| O0139 | 西岭 | standard | R31 | 2026-09-06T08:00:00Z | 2026-09-07T08:00:00Z | on_time | 0 | 0 |
| O0140 | 西岭 | standard | R32 | 2026-09-07T09:00:00Z | 2026-09-08T09:00:00Z | on_time | 0 | 0 |
| O0141 | 西岭 | standard | R31 | 2026-09-08T10:00:00Z | 2026-09-09T10:00:00Z | on_time | 0 | 0 |
| O0142 | 西岭 | standard | R32 | 2026-09-09T11:00:00Z | 2026-09-10T11:00:00Z | delivered_late | 90 | 0 |
| O0143 | 西岭 | standard | R31 | 2026-09-10T12:00:00Z | 2026-09-11T12:00:00Z | on_time | 0 | 0 |
| O0144 | 西岭 | standard | R32 | 2026-09-11T13:00:00Z | 2026-09-12T13:00:00Z | on_time | 0 | 0 |
| O0145 | 西岭 | standard | R31 | 2026-09-12T06:00:00Z | 2026-09-13T06:00:00Z | on_time | 0 | 0 |
| O0146 | 西岭 | standard | R32 | 2026-09-13T07:00:00Z | 2026-09-14T07:00:00Z | on_time | 0 | 0 |
| O0147 | 西岭 | standard | R31 | 2026-09-01T08:00:00Z | 2026-09-02T08:00:00Z | delivered_late | 90 | 0 |
| O0148 | 西岭 | standard | R32 | 2026-09-02T09:00:00Z | 2026-09-03T09:00:00Z | on_time | 0 | 0 |
| O0149 | 西岭 | standard | R31 | 2026-09-03T10:00:00Z | 2026-09-04T10:00:00Z | on_time | 0 | 0 |
| O0150 | 西岭 | standard | R32 | 2026-09-04T11:00:00Z | 2026-09-05T11:00:00Z | cancelled | 0 | 0 |
| O0151 | 西岭 | standard | R31 | 2026-09-05T12:00:00Z | 2026-09-06T12:00:00Z | on_time | 0 | 0 |
| O0152 | 西岭 | standard | R32 | 2026-09-06T13:00:00Z | 2026-09-07T13:00:00Z | delivered_late | 90 | 0 |
| O0153 | 西岭 | standard | R31 | 2026-09-07T06:00:00Z | 2026-09-08T06:00:00Z | on_time | 0 | 0 |
| O0154 | 西岭 | standard | R32 | 2026-09-08T07:00:00Z | 2026-09-09T07:00:00Z | on_time | 0 | 0 |
| O0155 | 西岭 | standard | R31 | 2026-09-09T08:00:00Z | 2026-09-10T08:00:00Z | overdue_open | 0 | 6720 |
| O0156 | 西岭 | standard | R32 | 2026-09-14T21:00:00Z | 2026-09-15T21:00:00Z | not_mature | 0 | 0 |
| O0157 | 西岭 | express | R31 | 2026-09-01T06:00:00Z | 2026-09-01T14:00:00Z | cancelled | 0 | 0 |
| O0158 | 西岭 | express | R32 | 2026-09-02T07:00:00Z | 2026-09-02T15:00:00Z | delivered_late | 90 | 0 |
| O0159 | 西岭 | express | R31 | 2026-09-03T08:00:00Z | 2026-09-03T16:00:00Z | on_time | 0 | 0 |
| O0160 | 西岭 | express | R32 | 2026-09-04T09:00:00Z | 2026-09-04T17:00:00Z | on_time | 0 | 0 |
| O0161 | 西岭 | express | R31 | 2026-09-05T10:00:00Z | 2026-09-05T18:00:00Z | delivered_late | 90 | 0 |
| O0162 | 西岭 | express | R32 | 2026-09-06T11:00:00Z | 2026-09-06T19:00:00Z | delivered_late | 90 | 0 |
| O0163 | 西岭 | express | R31 | 2026-09-07T12:00:00Z | 2026-09-07T20:00:00Z | on_time | 0 | 0 |
| O0164 | 西岭 | express | R32 | 2026-09-08T13:00:00Z | 2026-09-08T21:00:00Z | on_time | 0 | 0 |
| O0165 | 西岭 | express | R31 | 2026-09-09T06:00:00Z | 2026-09-09T14:00:00Z | delivered_late | 90 | 0 |
| O0166 | 西岭 | express | R32 | 2026-09-10T07:00:00Z | 2026-09-10T15:00:00Z | delivered_late | 90 | 0 |
| O0167 | 西岭 | express | R31 | 2026-09-11T08:00:00Z | 2026-09-11T16:00:00Z | on_time | 0 | 0 |
| O0168 | 西岭 | express | R32 | 2026-09-12T09:00:00Z | 2026-09-12T17:00:00Z | on_time | 0 | 0 |
| O0169 | 西岭 | express | R31 | 2026-09-13T10:00:00Z | 2026-09-13T18:00:00Z | delivered_late | 90 | 0 |
| O0170 | 西岭 | express | R32 | 2026-09-01T11:00:00Z | 2026-09-01T19:00:00Z | delivered_late | 90 | 0 |
| O0171 | 西岭 | express | R31 | 2026-09-02T12:00:00Z | 2026-09-02T20:00:00Z | on_time | 0 | 0 |
| O0172 | 西岭 | express | R32 | 2026-09-03T13:00:00Z | 2026-09-03T21:00:00Z | on_time | 0 | 0 |
| O0173 | 西岭 | express | R31 | 2026-09-04T06:00:00Z | 2026-09-04T14:00:00Z | delivered_late | 90 | 0 |
| O0174 | 西岭 | express | R32 | 2026-09-05T07:00:00Z | 2026-09-05T15:00:00Z | overdue_open | 0 | 13500 |
| O0175 | 西岭 | express | R31 | 2026-09-06T08:00:00Z | 2026-09-06T16:00:00Z | on_time | 0 | 0 |
| O0176 | 西岭 | express | R32 | 2026-09-07T09:00:00Z | 2026-09-07T17:00:00Z | on_time | 0 | 0 |
| O0177 | 西岭 | express | R31 | 2026-09-08T10:00:00Z | 2026-09-08T18:00:00Z | delivered_late | 90 | 0 |
| O0178 | 西岭 | express | R32 | 2026-09-09T11:00:00Z | 2026-09-09T19:00:00Z | delivered_late | 90 | 0 |
| O0179 | 西岭 | express | R31 | 2026-09-10T12:00:00Z | 2026-09-10T20:00:00Z | on_time | 0 | 0 |
| O0180 | 西岭 | express | R32 | 2026-09-14T21:00:00Z | 2026-09-15T05:00:00Z | not_mature | 0 | 0 |
| O0181 | 南湾 | standard | R41 | 2026-09-01T06:00:00Z | 2026-09-02T06:00:00Z | cancelled | 0 | 0 |
| O0182 | 南湾 | standard | R42 | 2026-09-02T07:00:00Z | 2026-09-03T07:00:00Z | delivered_late | 110 | 0 |
| O0183 | 南湾 | standard | R41 | 2026-09-03T08:00:00Z | 2026-09-04T08:00:00Z | on_time | 0 | 0 |
| O0184 | 南湾 | standard | R42 | 2026-09-04T09:00:00Z | 2026-09-05T09:00:00Z | on_time | 0 | 0 |
| O0185 | 南湾 | standard | R41 | 2026-09-05T10:00:00Z | 2026-09-06T10:00:00Z | on_time | 0 | 0 |
| O0186 | 南湾 | standard | R42 | 2026-09-06T11:00:00Z | 2026-09-07T11:00:00Z | on_time | 0 | 0 |
| O0187 | 南湾 | standard | R41 | 2026-09-07T12:00:00Z | 2026-09-08T12:00:00Z | on_time | 0 | 0 |
| O0188 | 南湾 | standard | R42 | 2026-09-08T13:00:00Z | 2026-09-09T13:00:00Z | delivered_late | 110 | 0 |
| O0189 | 南湾 | standard | R41 | 2026-09-09T06:00:00Z | 2026-09-10T06:00:00Z | on_time | 0 | 0 |
| O0190 | 南湾 | standard | R42 | 2026-09-10T07:00:00Z | 2026-09-11T07:00:00Z | on_time | 0 | 0 |
| O0191 | 南湾 | standard | R41 | 2026-09-11T08:00:00Z | 2026-09-12T08:00:00Z | on_time | 0 | 0 |
| O0192 | 南湾 | standard | R42 | 2026-09-12T09:00:00Z | 2026-09-13T09:00:00Z | on_time | 0 | 0 |
| O0193 | 南湾 | standard | R41 | 2026-09-13T10:00:00Z | 2026-09-14T10:00:00Z | on_time | 0 | 0 |
| O0194 | 南湾 | standard | R42 | 2026-09-01T11:00:00Z | 2026-09-02T11:00:00Z | delivered_late | 110 | 0 |
| O0195 | 南湾 | standard | R41 | 2026-09-02T12:00:00Z | 2026-09-03T12:00:00Z | on_time | 0 | 0 |
| O0196 | 南湾 | standard | R42 | 2026-09-03T13:00:00Z | 2026-09-04T13:00:00Z | on_time | 0 | 0 |
| O0197 | 南湾 | standard | R41 | 2026-09-04T06:00:00Z | 2026-09-05T06:00:00Z | on_time | 0 | 0 |
| O0198 | 南湾 | standard | R42 | 2026-09-05T07:00:00Z | 2026-09-06T07:00:00Z | overdue_open | 0 | 12540 |
| O0199 | 南湾 | standard | R41 | 2026-09-06T08:00:00Z | 2026-09-07T08:00:00Z | on_time | 0 | 0 |
| O0200 | 南湾 | standard | R42 | 2026-09-07T09:00:00Z | 2026-09-08T09:00:00Z | delivered_late | 110 | 0 |
| O0201 | 南湾 | standard | R41 | 2026-09-08T10:00:00Z | 2026-09-09T10:00:00Z | on_time | 0 | 0 |
| O0202 | 南湾 | standard | R42 | 2026-09-09T11:00:00Z | 2026-09-10T11:00:00Z | on_time | 0 | 0 |
| O0203 | 南湾 | standard | R41 | 2026-09-10T12:00:00Z | 2026-09-11T12:00:00Z | on_time | 0 | 0 |
| O0204 | 南湾 | standard | R42 | 2026-09-11T13:00:00Z | 2026-09-12T13:00:00Z | on_time | 0 | 0 |
| O0205 | 南湾 | standard | R41 | 2026-09-12T06:00:00Z | 2026-09-13T06:00:00Z | on_time | 0 | 0 |
| O0206 | 南湾 | standard | R42 | 2026-09-13T07:00:00Z | 2026-09-14T07:00:00Z | delivered_late | 110 | 0 |
| O0207 | 南湾 | standard | R41 | 2026-09-01T08:00:00Z | 2026-09-02T08:00:00Z | on_time | 0 | 0 |
| O0208 | 南湾 | standard | R42 | 2026-09-02T09:00:00Z | 2026-09-03T09:00:00Z | on_time | 0 | 0 |
| O0209 | 南湾 | standard | R41 | 2026-09-03T10:00:00Z | 2026-09-04T10:00:00Z | on_time | 0 | 0 |
| O0210 | 南湾 | standard | R42 | 2026-09-14T21:00:00Z | 2026-09-15T21:00:00Z | cancelled | 0 | 0 |
| O0211 | 南湾 | express | R41 | 2026-09-01T06:00:00Z | 2026-09-01T14:00:00Z | cancelled | 0 | 0 |
| O0212 | 南湾 | express | R42 | 2026-09-02T07:00:00Z | 2026-09-02T15:00:00Z | delivered_late | 110 | 0 |
| O0213 | 南湾 | express | R41 | 2026-09-03T08:00:00Z | 2026-09-03T16:00:00Z | on_time | 0 | 0 |
| O0214 | 南湾 | express | R42 | 2026-09-04T09:00:00Z | 2026-09-04T17:00:00Z | on_time | 0 | 0 |
| O0215 | 南湾 | express | R41 | 2026-09-05T10:00:00Z | 2026-09-05T18:00:00Z | on_time | 0 | 0 |
| O0216 | 南湾 | express | R42 | 2026-09-14T21:00:00Z | 2026-09-15T05:00:00Z | not_mature | 0 | 0 |
learner/checkpoints/hub-metrics.csv 阅读完整文件
下载文件| hub | total | eligible | late | late_rate | on_time | delivered_late | overdue_open | cancelled | not_mature | delivered_late_minutes | open_overdue_minutes |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 东城 | 60 | 55 | 31 | 0.563636 | 24 | 28 | 3 | 3 | 2 | 1960 | 33720 |
| 南湾 | 36 | 32 | 7 | 0.21875 | 25 | 6 | 1 | 3 | 1 | 660 | 12540 |
| 海港 | 60 | 55 | 32 | 0.581818 | 23 | 29 | 3 | 3 | 2 | 1450 | 32760 |
| 西岭 | 60 | 55 | 20 | 0.363636 | 35 | 17 | 3 | 3 | 2 | 1530 | 32760 |
learner/checkpoints/service-review.csv 阅读完整文件
下载文件| hub | service | eligible | late | late_rate | target | gap_pp | review |
|---|---|---|---|---|---|---|---|
| 东城 | express | 37 | 26 | 0.702703 | 0.1 | 60.27 | 优先处理 |
| 东城 | standard | 18 | 5 | 0.277778 | 0.1 | 17.778 | 优先处理 |
| 南湾 | express | 4 | 1 | 0.25 | 0.1 | 15.0 | 待补样本 |
| 南湾 | standard | 28 | 6 | 0.214286 | 0.1 | 11.429 | 需要复核 |
| 海港 | express | 18 | 18 | 1.0 | 0.1 | 90.0 | 优先处理 |
| 海港 | standard | 37 | 14 | 0.378378 | 0.1 | 27.838 | 优先处理 |
| 西岭 | express | 22 | 11 | 0.5 | 0.1 | 40.0 | 优先处理 |
| 西岭 | standard | 33 | 9 | 0.272727 | 0.1 | 17.273 | 优先处理 |
learner/materials/access-policy.json 阅读完整文件
下载文件{
"session_ttl_minutes": 30,
"export_roles": [
"supervisor",
"service"
],
"operator_hub": {
"op-1": "海港",
"op-2": "东城",
"op-3": "西岭",
"op-4": "南湾",
"op-7": "海港"
},
"network_note": "经企业 VPN 访问网关;IP 为文档保留地址,不能证明真实地理位置或攻击者身份。",
"service_accounts": [
"svc-archive"
]
}步骤
- 逐条提取访谈需求,并与任务二、三、四发现关联。写出目标用户、主要场景和不在第一期的动作。
- 画信息层级:站点汇总→订单列表→证据时间线。实现站点、服务、状态筛选及空结果状态,让交付对象可操作。
- 编写接口契约:分页、筛选、as_of、数据版本、权限、401/403/503。认证从身份服务接入,前端隐藏按钮不能代替服务端检查。
- 把 R1–R6 需求映射到接口、页面和验收用例;包含取消/未来事件、小样本、空结果、过期 session、数据延迟。
- 分解设计、前后端、集成、测试及交接工时,合计后给出资源与依赖假设。相对周次与实际工时必须一致,不凭空写合同上线日期。
- 写完整 proposal.md:目标范围、架构与数据流、契约、验收、工时、计划、运维和待确认项,附需求追踪 CSV 与可操作成果。
完整成果
冷链履约异常工作台交付提案
1. 目标、用户与范围
运营人员需要先处理未交付逾期订单,并追溯其原始事件。站点负责人需要看分层迟交指标,安全负责人需要可靠的导出与会话控制。第一期交付只读工作台、指标 API、事件时间线和受控导出设计;退款、写回调度、客户通知和员工绩效排名不在范围。
R1:按站点、服务等级与状态筛选订单,优先展示 overdue_open。R2:可打开订单事件及截止点,未来事件不参与历史指标。R3:取消/未到期不入成熟分母。R4:分服务比较和样本量提示。R5:服务端角色、站点及 session 检查。R6:加载、空结果、错误与数据延迟状态明确,保留刷新时间。
2. 信息结构与完整交互
页面先展示截止点、成熟数、迟交数和开放逾期数,再展示站点图与可筛选订单列表。三个筛选使用 AND 关系,结果数量与订单表同步。订单行展开显示 created、picked_up、delivered 或 cancelled 的完整时间线,明确哪些事件晚于复盘截止点。无结果显示“没有符合条件的订单”,可一键恢复全部。
资料包内工作台可直接筛选与展开全部 216 个订单。生产加载期间禁用重复请求,成功后更新时间;503 时保留上次成功快照并显示数据版本与失败原因,身份过期则清除敏感内容并转企业登录。离线工作台没有生产身份服务或真实导出权限,接口验收在下述集成范围内执行。
3. 架构与数据流
来源 A/B → 事件校验与冲突隔离 → 不可变标准事件层 → 按 as_of 聚合的订单视图 → 内网只读 API → 工作台。业务 orders 主表补充 route 和 due_at,事件只决定可见状态。记录 dataset_version、ingested_at 与 source_line,以便对账和重跑。新批次失败时不覆盖上一已核对版本。
企业身份服务颁发受控 session;网关验证 session,API 对每次请求再检查角色与站点范围。浏览器请求的 hub 不是授权依据。operator 仅可访问所属站点;supervisor 与受批次约束的 service 可按授权导出。数据服务不保存用户密码。导出写审计事件,包含 request_id、user、scope、rows、bytes 与 dataset_version,不记录密码和 session 密钥。
4. 接口契约
GET /v1/orders?hub=&service=&cohort=&as_of=&cursor=&limit=50:返回 items、next_cursor、total、as_of、dataset_version、updated_at。limit 为 1–100;cursor 为服务端稳定排序游标,同一次分页使用同一快照,避免刷新导致重复/漏项。未知筛选 400,无匹配 200 加空 items。
GET /v1/orders/{order_id}/events?as_of=:返回有序事件与 visible_at_cutoff。权限检查先于返回数据,不存在 404,无权限 403。GET /v1/metrics:返回成熟分母、迟交分子、分层结果和小样本状态,沿用同一快照。
POST /v1/exports:需 supervisor/service,body 含 scope、as_of、dataset_version;成功创建 202 与 job_id,完成后在授权范围内提供下载;operator 403。客户端提交 request_key 用于重复请求去重,服务端审计导出批次,不能以 UI 隐藏替代权限。
统一错误:400 参数、401 缺失/过期 session、403 无权限、404 不存在、409 快照不匹配、429 限流、503 数据源不可用。响应提供 request_id 与可显示的错误原因,不泄露凭据。
5. 需求到验收
R1:选择海港+express+overdue_open,仅出现匹配订单,恢复全部回到 216。R2:打开订单事件线,与标准事件逐条匹配;未来交付不改变历史状态。R3:216 = 12 取消 + 7 未到期 + 107 准时 + 80 已交付迟交 + 10 未交付逾期。成熟 197、迟交 90。R4:南湾 express n=4 显示待补样本,站点标准化值为空;目标差距 5/15 的边界正确。R5:operator 导出 403,过期 session 401,合法 supervisor 导出 202;operator 选择他站点仍 403。R6:空筛选、503、429、加载、恢复与更新时间逐项验收。
每条需求在 requirements-traceability.csv 映射到接口与用例。离线交互与算法测试能够检查资料成果;R5、生产错误与负载验收必须在后端接入后执行,不把本地页面当成生产权限实现。
6. 工作量与里程碑
| 工作项 | 人时 | 交付门禁 |
|---|---|---|
| 需求、口径与交互设计 | 16 | R1–R6、身份协议、数据契约获确认 |
| 数据接入、聚合与快照 | 28 | 质量对账、未来事件及重跑测试通过 |
| 前端工作台与可访问性 | 24 | 筛选、时间线、空结果及键盘验收 |
| API、权限与导出审计 | 24 | 401/403、站点隔离和批次审计通过 |
| 身份/网关集成与发布准备 | 16 | 客户接入、回退与监控准备完毕 |
| 集成、安全和 UAT 测试 | 24 | R1–R6 全部验收,问题闭环 |
| 运维文档与交接 | 8 | 操作手册、值班和回退演练 |
| 合计 | 140 | 依赖满足后方可排期 |
计划由一位工程师每周投入 35 h,连续四个工作周完成 140 人时。W1:设计 16+数据 19;W2:数据 9+前端 24+API 2;W3:API 22+集成 13;W4:集成 3+测试 24+交接 8。周末与客户审批等待不计入工时;安全审查若排队则调整日历,不能压缩验收。工程能力与 35 h投入是假设,需负责人确认,未给定生产日期或合同金额。
7. 运维、支持与回退
监控新批次隔离率、快照更新时间、API 错误、越权拒绝及导出量。用工单记录影响站点、request_id、版本与复现步骤。严重访问故障由技术值班分诊,运营负责人确认业务影响;支持时段、响应目标、数据保留周期与费用另行确认,不承诺未商定 SLA。
回退先将读取切回上一核对快照,保留源数据与隔离记录;API 版本回退仍须保留新加的访问检查,不能为了恢复导出而开放 operator。恢复后以同口径复算 197/90 并对照版本,通知运营负责人确认。发布前另做备份与恢复演练。
8. 依赖和待确认项
客户需提供身份协议、允许角色/站点映射、网关访问、源接口可用性和留存要求。并发用户、数据到达延迟、刷新频率、导出上限、审计留存及支持时段在 W1 定稿。当前使用记录回放进行验收,不据此声称已处理生产流量或已改善履约指标。
下载文件操作完整工作台参考答案
instructor/answers/api-contract.json 阅读完整文件
下载文件{
"version": "1.0",
"as_of": "2026-09-15T00:00:00Z",
"dataset_version": "coldchain-v1",
"routes": [
{
"method": "GET",
"path": "/v1/orders",
"query": [
"hub",
"service",
"cohort",
"as_of",
"cursor",
"limit"
],
"limit": {
"min": 1,
"max": 100
},
"response": [
"items",
"total",
"next_cursor",
"as_of",
"dataset_version",
"updated_at"
],
"errors": [
400,
401,
403,
409,
429,
503
]
},
{
"method": "GET",
"path": "/v1/orders/{order_id}/events",
"response": [
"events",
"visible_at_cutoff"
],
"errors": [
401,
403,
404,
503
]
},
{
"method": "GET",
"path": "/v1/metrics",
"response": [
"eligible",
"late",
"by_hub",
"by_service",
"sample_status"
],
"errors": [
400,
401,
403,
409,
503
]
},
{
"method": "POST",
"path": "/v1/exports",
"roles": [
"supervisor",
"service"
],
"body": [
"scope",
"as_of",
"dataset_version",
"request_key"
],
"accepted_status": 202,
"errors": [
400,
401,
403,
409,
429,
503
]
}
]
}
instructor/answers/requirements-traceability.csv 阅读完整文件
下载文件| requirement | outcome | endpoint | test | verification |
|---|---|---|---|---|
| R1 | 组合筛选与逾期优先 | GET /v1/orders | 海港+express+overdue_open;恢复216 | 离线交互已实现;生产分页待集成 |
| R2 | 事件追溯与历史截止 | GET /v1/orders/{id}/events | 未来交付不改变截止点状态 | 离线时间线及算法测试 |
| R3 | 履约指标分母 | GET /v1/metrics | 成熟197、迟交90 | 完整复算与独立计数 |
| R4 | 小样本与服务结构 | GET /v1/metrics | 南湾express n4;站点标准化为空 | 公式及边界测试 |
| R5 | 授权与会话 | POST /v1/exports | operator403;过期401;合法202 | 契约与调查测试;无生产后端 |
| R6 | 空结果与错误恢复 | 所有接口 | 无结果恢复;503保留快照;429重试 | 离线空结果可查;网络错误待集成 |
完整参考实现 阅读完整文件
下载文件"""Reference implementation for the Ape Intern cold-chain operations lab."""
import csv,json
from collections import defaultdict,Counter
from datetime import datetime,timezone
from pathlib import Path
from urllib.parse import urlparse,parse_qs
UTC=timezone.utc
KINDS={'OPEN':'created','COLLECT':'picked_up','DROP':'delivered','VOID':'cancelled'}
HUBS={'海港','东城','西岭','南湾'}
def parse_time(value):
t=datetime.fromisoformat(value.replace('Z','+00:00'))
if t.tzinfo is None:raise ValueError('timezone_required')
return t.astimezone(UTC)
def iso(t):return t.isoformat(timespec='seconds').replace('+00:00','Z')
def readcsv(p):
with Path(p).open(encoding='utf-8-sig',newline='') as f:return list(csv.DictReader(f))
def writecsv(p,rows,fields=None):
rows=list(rows)
with Path(p).open('w',encoding='utf-8-sig',newline='') as f:
w=csv.DictWriter(f,fieldnames=fields or list(rows[0]));w.writeheader();w.writerows(rows)
def dump(p,value):Path(p).write_text(json.dumps(value,ensure_ascii=False,indent=2)+'\n')
def _normalize(record,source):
if source=='A':
e=dict(event_id=record['event_id'],order_id=record['order_ref'],hub=record['hub'],service=record['service'],kind=record['event'],happened_at=iso(parse_time(record['event_time'])))
else:
ms=record['at_ms']
if type(ms) is not int:raise ValueError('epoch_must_be_integer')
e=dict(event_id=record['id'],order_id=record['shipment']['number'],hub=record['shipment']['station'],service=record['shipment']['product'],kind=KINDS[record['action']],happened_at=iso(datetime.fromtimestamp(ms/1000,UTC)))
if e['kind'] not in KINDS.values():raise ValueError('unsupported_event')
if e['hub'] not in HUBS or e['service'] not in {'standard','express'}:raise ValueError('unknown_dimension')
if not e['event_id'] or not e['order_id']:raise ValueError('empty_key')
return e
def normalize(record,source):
try:return _normalize(record,source)
except (KeyError,TypeError,OverflowError) as error:raise ValueError(str(error).strip("'")) from error
def ingest(data):
grouped=defaultdict(list);rejected=[];duplicates=[]
for source,name in [('A','dispatch-a.jsonl'),('B','courier-b.jsonl')]:
for line,text in enumerate((data/name).read_text().splitlines(),1):
loc={'source':name,'line':line}
try:
event=normalize(json.loads(text),source);grouped[event['event_id']].append((event,loc))
except (ValueError,KeyError,TypeError,OverflowError) as ex:
rejected.append(dict(loc,reason=str(ex).strip("'")))
accepted=[]
for eid,items in grouped.items():
distinct={json.dumps(e,sort_keys=True,ensure_ascii=False) for e,loc in items}
if len(distinct)>1:
rejected.extend(dict(loc,reason='immutable_id_conflict') for e,loc in items);continue
accepted.append(items[0][0])
duplicates.extend(dict(loc,event_id=eid,reason='exact_replay') for e,loc in items[1:])
accepted.sort(key=lambda e:(e['happened_at'],e['event_id']))
return accepted,rejected,duplicates
def classify_order(order,events,cutoff):
# Only facts available at cutoff can influence a retrospective result.
visible=[e for e in events if parse_time(e['happened_at'])<=cutoff]
visible.sort(key=lambda e:parse_time(e['happened_at']))
delivered=[parse_time(e['happened_at']) for e in visible if e['kind']=='delivered']
cancelled=any(e['kind']=='cancelled' for e in visible)
due=parse_time(order['due_at'])
if cancelled:state='cancelled'
elif due>cutoff:state='not_mature'
elif not delivered:state='overdue_open'
elif min(delivered)>due:state='delivered_late'
else:state='on_time'
delay=round((min(delivered)-due).total_seconds()/60) if state=='delivered_late' else 0
overdue=round((cutoff-due).total_seconds()/60) if state=='overdue_open' else 0
return dict(order,cohort=state,late_minutes=delay,overdue_minutes=overdue)
def aggregate(rows,keys):
groups=defaultdict(list)
for row in rows:groups[tuple(row[k] for k in keys)].append(row)
result=[]
for dims,records in sorted(groups.items()):
counts=Counter(r['cohort'] for r in records)
eligible=sum(counts[x] for x in ['on_time','delivered_late','overdue_open'])
late=counts['delivered_late']+counts['overdue_open']
result.append(dict(zip(keys,dims),total=len(records),eligible=eligible,late=late,late_rate=round(late/eligible,6) if eligible else None,on_time=counts['on_time'],delivered_late=counts['delivered_late'],overdue_open=counts['overdue_open'],cancelled=counts['cancelled'],not_mature=counts['not_mature'],delivered_late_minutes=sum(r['late_minutes'] for r in records),open_overdue_minutes=sum(r['overdue_minutes'] for r in records)))
return result
def service_band(rate,n,rules):
if n<rules['min_sample']:return '待补样本'
gap=(rate-rules['late_target'])*100
if gap>rules['priority_gap_pp']:return '优先处理'
if gap>rules['review_gap_pp']:return '需要复核'
return '达到阈值'
def fairness(hub_tiers,rules):
rows=[]
for x in hub_tiers:
rate=x['late_rate'];rows.append(dict(hub=x['hub'],service=x['service'],eligible=x['eligible'],late=x['late'],late_rate=rate,target=rules['late_target'],gap_pp=round((rate-rules['late_target'])*100,3) if rate is not None else None,review=service_band(rate,x['eligible'],rules)))
standardized=[]
for hub in sorted(HUBS):
parts=[r for r in rows if r['hub']==hub]
enough=len(parts)==2 and all(r['eligible']>=rules['min_sample'] for r in parts)
value=sum(r['late_rate']*rules[r['service']+'_weight'] for r in parts) if enough else None
standardized.append(dict(hub=hub,standardized_late_rate=round(value,6) if value is not None else None,status='可比较' if enough else '待补样本'))
return rows,standardized
def investigate(logs,policy):
logins={};findings=[]
for row in sorted(logs,key=lambda r:(r['at'],r['request_id'])):
t=parse_time(row['at']);status=int(row['status']);route=urlparse(row['path']);query=parse_qs(route.query)
if route.path=='/login' and status==200:logins[(row['user'],row['session'])]=t;continue
if status!=200:continue
types=[]
if route.path=='/export' and row['role'] not in policy['export_roles']:types.append('unauthorised_export')
hub=query.get('hub',[''])[0]
if row['role']=='operator' and hub and hub!=policy['operator_hub'].get(row['user']):types.append('hub_scope_violation')
login=logins.get((row['user'],row['session']))
if login is None or (t-login).total_seconds()>policy['session_ttl_minutes']*60:types.append('expired_or_missing_session')
if types:findings.append(dict(request_id=row['request_id'],at=row['at'],user=row['user'],session=row['session'],finding=';'.join(types),status=status,rows=int(row['rows']),bytes=int(row['bytes'])))
return findings
def solve(data,out):
data=Path(data);out=Path(out);out.mkdir(parents=True,exist_ok=True)
events,rejects,dups=ingest(data)
(out/'canonical-events.jsonl').write_text(''.join(json.dumps(e,ensure_ascii=False)+'\n' for e in events))
writecsv(out/'rejected.csv',rejects);writecsv(out/'duplicates.csv',dups)
rules=json.loads((data/'rules.json').read_text());cutoff=parse_time(rules['cutoff'])
by_order=defaultdict(list)
for e in events:by_order[e['order_id']].append(e)
orders=readcsv(data/'orders.csv')
records=[classify_order(o,by_order[o['order_id']],cutoff) for o in orders]
writecsv(out/'order-review.csv',records)
hubs=aggregate(records,['hub']);tiers=aggregate(records,['hub','service']);routes=aggregate(records,['route'])
writecsv(out/'hub-metrics.csv',hubs);writecsv(out/'route-metrics.csv',routes)
bands,std=fairness(tiers,rules)
writecsv(out/'service-review.csv',bands);writecsv(out/'standardized-comparison.csv',std)
findings=investigate(readcsv(data/'access-log.csv'),json.loads((data/'access-policy.json').read_text()))
writecsv(out/'security-findings.csv',findings)
summary=dict(orders=len(orders),accepted_events=len(events),rejected=len(rejects),duplicates=len(dups),cohorts=dict(Counter(r['cohort'] for r in records)),hubs=hubs,service_review=bands,standardized=std,security=dict(flagged_requests=len(findings),potential_export_rows=sum(f['rows'] for f in findings if 'unauthorised_export' in f['finding']),potential_export_bytes=sum(f['bytes'] for f in findings if 'unauthorised_export' in f['finding']),findings=findings))
dump(out/'results.json',summary)
return summary
if __name__=='__main__':
import sys
print(json.dumps(solve(sys.argv[1],sys.argv[2]),ensure_ascii=False,indent=2))
把“后端会校验”写进提案不等于后端已经实现;离线工作台用于检查阅读与筛选体验,生产集成仍按验收契约交付。
每项 20 分,14 分及以上且没有关键口径错误再进入下一次 Review。原始数据被改写、静默丢记录、分母含未到期、把 401 算成泄露、用小样本硬排站点或把前端筛选当授权,均须修正后再验收。
- 证据到需求闭环 5 分
- 架构与权限边界 5 分
- 估算与依赖一致 5 分
- 完整提案与可操作成果 5 分