2026 07 14 growth report filter plan
本地来源:关键词/ahrefs-top-worldwide-2026-07-all/ahrefs-top-websites-worldwide-2026-07/docs/superpowers/plans/2026-07-14-growth-report-filter-plan.md
Positive Traffic Growth Filters Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Subagents are intentionally not used because the active session forbids delegation unless explicitly requested.
Goal: Add K/M traffic-scale, K/M-aware minimum/maximum 28-day traffic, and keyword word-count filters to the standalone positive-growth report.
Architecture: Keep growth_template.html as the UI/behavior source and build_catalog.py as the existing standalone-report generator. Add small pure JavaScript helpers inside the current report IIFE, combine the new conditions in filteredRows(), then regenerate the embedded-data HTML. Preserve full-result sorting and progressive rendering.
Tech Stack: Python unittest, static HTML/CSS, browser-native JavaScript, existing Python catalog generator, Chromium browser verification.
Repository note: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07 is not a Git repository, so worktree and commit steps cannot be performed.
Task 1: Add a failing template contract test
Files:
- Modify: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/test_build_catalog.py
- Test: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/test_build_catalog.py
- [ ] Step 1: Define the growth template path and assert the new contract
Add:
GROWTH_TEMPLATE = Path(__file__).with_name("growth_template.html")
Add a test that reads GROWTH_TEMPLATE and requires all four control IDs, state fields, parsing/counting helpers, combined filter predicates, invalid-input accessibility, and listeners:
def test_growth_template_supports_traffic_and_word_count_filters(self):
text = GROWTH_TEMPLATE.read_text(encoding="utf-8")
for control_id in (
"keyword-word-count",
"traffic-scale",
"traffic-min",
"traffic-max",
):
self.assertIn(f'id="{control_id}"', text)
self.assertIn("const keywordWordCount", text)
self.assertIn("const parseTrafficBound", text)
self.assertIn("const matchesWordCount", text)
self.assertIn("const matchesTraffic", text)
self.assertIn("aria-invalid", text)
self.assertIn("state.wordCount", text)
self.assertIn("state.trafficScale", text)
self.assertIn("state.trafficMin", text)
self.assertIn("state.trafficMax", text)
- [ ] Step 2: Run the focused test and verify RED
Run:
python3 -m unittest test_build_catalog.BuildCatalogTests.test_growth_template_supports_traffic_and_word_count_filters -v
Expected: FAIL because keyword-word-count and the remaining controls/helpers do not exist.
Task 2: Implement the filter controls and behavior
Files:
- Modify: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/growth_template.html
- Test: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/test_build_catalog.py
- [ ] Step 1: Add controls and responsive layout
Extend .controls to fit seven fields on wide screens while retaining the existing two-column and one-column breakpoints. Add:
<div class="field">
<label for="keyword-word-count">关键词词数</label>
<select id="keyword-word-count">
<option value="">全部词数</option>
<option value="1">1 词</option>
<option value="2">2 词</option>
<option value="3">3 词</option>
<option value="4+">4 词以上</option>
</select>
</div>
<div class="field">
<label for="traffic-scale">28 天流量级别</label>
<select id="traffic-scale">
<option value="">全部级别</option>
<option value="k">K 级(1K–不足 1M)</option>
<option value="m">M 级(1M 以上)</option>
</select>
</div>
<div class="field"><label for="traffic-min">最小 28 天流量</label><input id="traffic-min" inputmode="decimal" placeholder="例如 10K"></div>
<div class="field"><label for="traffic-max">最大 28 天流量</label><input id="traffic-max" inputmode="decimal" placeholder="例如 1.5M"></div>
Add an invalid style keyed by aria-invalid="true".
- [ ] Step 2: Add minimal state, element references, and pure helpers
Add state fields wordCount, trafficScale, trafficMin, and trafficMax plus matching element references. Implement:
const keywordWordCount = value => {
const normalized = String(value ?? '').trim().replace(/\s+/gu, ' ');
return normalized ? normalized.split(' ').length : 0;
};
const parseTrafficBound = value => {
const text = String(value ?? '').trim().replaceAll(',', '').toUpperCase();
if (!text) return { active: false, valid: true, value: null };
if (!/^(?:\d+(?:\.\d+)?|\.\d+)[KMB]?$/.test(text)) {
return { active: true, valid: false, value: null };
}
return { active: true, valid: true, value: parseMetric(text) };
};
const matchesWordCount = (keyword, filter) => {
if (!filter) return true;
const count = keywordWordCount(keyword);
return filter === '4+' ? count >= 4 : count === Number(filter);
};
const matchesTraffic = (value, scale, minimum, maximum) => {
const traffic = parseMetric(value);
const active = Boolean(scale) || (minimum.active && minimum.valid) || (maximum.active && maximum.valid);
if (!active) return true;
if (traffic === null) return false;
if (scale === 'k' && (traffic < 1e3 || traffic >= 1e6)) return false;
if (scale === 'm' && traffic < 1e6) return false;
if (minimum.active && minimum.valid && traffic < minimum.value) return false;
if (maximum.active && maximum.valid && traffic > maximum.value) return false;
return true;
};
- [ ] Step 3: Combine filters and wire listeners
In filteredRows(), parse both bounds once, update each input's aria-invalid, and add matchesWordCount and matchesTraffic to the existing AND predicate. Add change listeners for selectors and input listeners for bounds, each updating state and calling render().
- [ ] Step 4: Run the focused and full unit suites and verify GREEN
Run:
python3 -m unittest test_build_catalog.BuildCatalogTests.test_growth_template_supports_traffic_and_word_count_filters -v
python3 -m unittest test_build_catalog.py -v
Expected: the focused test passes and all catalog tests pass with zero failures.
Task 3: Rebuild the standalone report
Files:
- Generate: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/05_positive_traffic_growth.html
- [ ] Step 1: Rebuild only the growth report through the existing generator function
Run:
python3 - <<'PY'
from pathlib import Path
from build_catalog import read_csv, write_growth_index
output_dir = Path('/Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07')
write_growth_index(
output_dir,
'Ahrefs Worldwide 正流量增长榜 · 2026-07',
read_csv(output_dir / '04_category_summary.csv'),
read_csv(output_dir / '02_all_categories_site_keywords.csv'),
)
PY
Expected: exit code 0 and only 05_positive_traffic_growth.html is regenerated. This avoids unrelated catalog writes.
- [ ] Step 2: Verify the generated file contract and embedded row count
Run a read-only Python check that requires the four new IDs, extracts window.AHREFS_CATALOG, confirms every embedded row still has positive traffic_change, and confirms the report remains standalone with no index_data.js reference.
Task 4: Verify the real browser interaction
Files:
- Verify: /Users/project/1B/sites/关键词/ahrefs-top-websites-worldwide-2026-07/05_positive_traffic_growth.html
- [ ] Step 1: Open the report through
file://in Chromium
Confirm the initial full positive-growth count and that the first progressive batch renders without a console error.
- [ ] Step 2: Verify traffic filters
Select K level and assert every displayed 28 天流量 parses into [1,000, 1,000,000). Select M level and assert every displayed value is at least 1,000,000. Enter 10K minimum and 1.5M maximum, clear the scale, and assert every filtered row lies inclusively within the range.
- [ ] Step 3: Verify word counts and combined filters
Select 1, 2, 3, and 4+ in turn and inspect all filtered rows via page JavaScript, not only the first 200 rendered rows. Combine a word-count selection with keyword search and verify both predicates hold.
- [ ] Step 4: Verify reset and console state
Clear all new and existing filters, confirm the current-result count returns to the initial total, and confirm the browser console contains no errors.
Task 5: Run completion verification
Files: - Verify: all modified/generated files above
- [ ] Step 1: Re-run the complete relevant unit suite
python3 -m unittest test_build_catalog.py -v
Expected: zero failures and zero errors.
- [ ] Step 2: Inspect the final changed files
Because there is no Git repository, compare template/generated timestamps and use targeted rg/Python checks to confirm only the growth template, generated growth report, tests, and approved documentation were changed.
本文档为站内渲染。原始文件本地路径:saas/source/keywords/关键词-ahrefs-top-worldwide-2026-07-all-ahrefs-top-websites-wor-176bf2.md(仅本地保留,不入库不部署)