Despite the filename, that workbook is the 投手 roster (no Date or 花费
columns), and is a strict superset of the previous one: 30 Adpingids
added, none removed or reassigned. Spend is unchanged because no new
consumption data arrived; only the 负责 counts move.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every roster the user sends arrives under a different filename, which
forced a code change each time. The roster now lives at a fixed
roster.xlsx; the three superseded copies are removed (git history keeps
them, and each was a strict subset of this one).
This roster claims all 14 previously unattributed Adpingids, so the
report has no unattributed spend. It also moves 5617321 from 周梓君 to
詹涵粤; that id has never spent, so only the 负责 counts shift.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
投手List.xlsx is a strict superset of the previous roster (19 added,
none removed or reassigned) and claims every previously unmatched
Adpingid, so the report has no unattributed spend.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
build_data.py now also computes each buyer's total for the preceding
3-day window under identical rules (exclusions, attribution), exposed as
prev_total plus meta.prev_range. index.html renders it as the first
panel, with green/red deltas and a total row; the panel stays hidden if
no prior period exists.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
New roster is a strict superset of 投手.xlsx (14 added, none removed, no
reassignments). build_data.py now picks the roster by an explicit
precedence list, so the old 投手.xlsx stays as a fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
New roster_extra.json fills in Adpingids missing from 投手.xlsx. It only
applies when the roster has no entry for that id, so a future roster
always wins.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The 2609 file carries only 8/31 and has no 投手 sheet, so build_data.py
now globs every *每日数据-武汉萌奇熊.xlsx, merges 平台消耗统计 per date
(newer filename wins for a repeated date), and takes the roster from the
newest file that still has a 投手 sheet. Future month rollovers need no
code change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adping-level only; com.vuclip.viu stays out of the package exclusion list
per request, so its other Adpingids remain in the report.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
exclude.json gains an "adpings" map (18 ids, value = package for
reference) alongside the existing package list. build_data.py drops those
Adpingids from both the 投手 ownership counts and the spend rows.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Package now renders as pkg_GEO, where GEO is the region with the highest
total spend for that package. The new Adpingid column shows the
top-spending Adping within that region, so label and id stay consistent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
build_data.py now emits active_ids (Adpingids with spend in the window)
and owned_ids (Adpingids assigned to the buyer, exclusions removed).
active_ids sums to the 覆盖 Adpingid 数 card.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add exclude.json (12 package names, permanent) and build_data.py so the
report is reproducible. Exclusion is exact-match on package name, applied
both to 平台消耗统计 rows and to Adpingids whose 投手 pkg is excluded.
Exact match avoids false positives (e.g. in.swiggy.android vs "igg").
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refresh xlsx source and regenerate data.json from
平台消耗统计 (Date/Adpingid/花费) x 投手 (Adpingid/Media Buyer).
@某某 merged with 某某; Adpingid without a buyer excluded.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>