Skip to content

fix(export): prefix CSV data keys that collide with id/timestamp/duration - #184

Open
TimeToBuildBob wants to merge 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/csv-export-reserved-column-collision
Open

TimeToBuildBob wants to merge 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/csv-export-reserved-column-collision

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Follow-up to the Greptile note on #178: the bucket CSV export (#179) writes id,timestamp,duration followed by the union of event data keys, so a data key named id, timestamp or duration produced a duplicate header name.

A data key that would repeat an earlier header name now gets a data. prefix, repeated until unique (duration → data.duration; id next to a literal data.id → data.data.id). Only the header changes; values are still read by the original key. Non-colliding keys and the >32-key single data column are unchanged. Same scheme as ActivityWatch/aw-server-rust#795, so both servers keep emitting the same header.

Tests: test_export_bucket_csv_prefixes_colliding_data_keys (API round-trip) and test_csv_header_prefix_repeats_until_unique; tests/test_server.py 15 passed, ruff and mypy clean.

@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Changes how CSV export column names handle collisions.

This PR appears safe to merge; no actionable issues were found.

What we checked:

  • Renamed columns keep their values: _header_names returns a separate list. Rows still use the original data_keys, so each renamed column keeps its matching value.
  • Wide exports keep their format: Wide exports pass only data to _header_names. That name does not collide with the fixed columns, and rows still contain one JSON value.

Summary

CSV exports now prefix colliding event-data headers with data., repeating the prefix until the name is unique.

  • Values still come from the original data keys.
  • The single JSON column for exports with more than 32 keys stays unchanged.
  • New tests cover reserved names and repeated prefixes.

Reviews (1) · Last reviewed commit: "fix(export): prefix CSV data keys that c..."

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Status check: Greptile reviewed at 5/5 (no actionable issues). CI: ubuntu, windows, lint, format, and typecheck all pass. macOS runner has been queued/running for ~1.5h — appears slow on GitHub's side, not a test failure. Ready for maintainer review and merge when macOS finishes.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@TimeToBuildBob

TimeToBuildBob commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 AI code review

This PR changes the CSV export header generation in aw_server/csv_export.py by adding a _header_names() function that prefixes data keys colliding with the fixed id/timestamp/duration columns (or with earlier data keys) with a repeated 'data.' prefix until unique. The events_to_csv() function now uses this for the header row, while values are still read by the original data key. Two tests are added: an API round-trip test for colliding keys and a unit test for the prefix-repeats-until-unique behavior.

Safe to merge — no P0/P1 findings

Confidence 5/5

✅ No findings. The diff looks correct to me on this pass.

Files changed (2) — the diff as I read it
  • aw_server/csv_export.py — Adds _header_names() to generate unique CSV header names by prefixing colliding data keys with 'data.' repeatedly, and uses it in events_to_csv().
  • tests/test_server.py — Adds test_export_bucket_csv_prefixes_colliding_data_keys and test_csv_header_prefix_repeats_until_unique to cover the new header naming.
Previous review passes
commit score findings engine when
12213131270e 5/5 0 llm 2026-10-07 09:43 UTC
1d2e92699b28 5/5 0 subscription 2026-10-10 12:08 UTC

Reviewed 1d2e92699b28 · openrouter/deepseek/deepseek-v4-flash-0731 · llm engine · 107s · about this reviewer

Maintainer commands

@TimeToBuildBob review (own line) — fresh review · @TimeToBuildBob fix — a worker acts on the findings. Once per comment; 👀 = received.

@TimeToBuildBob
TimeToBuildBob force-pushed the fix/csv-export-reserved-column-collision branch from 1221313 to 1d2e926 Compare October 10, 2026 10:24
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

The conflict is already resolved in 1d2e926: the earlier rebase preserved both the heartbeat-cache tests from master and the CSV collision tests. Verified the current head is mergeable and all six CI checks pass. No further rebase or force-push needed; awaiting maintainer merge.

…tion

A data key named id, timestamp or duration produced a duplicate header
name. Prefix such keys with "data." (repeated until unique), matching
ActivityWatch/aw-server-rust#795. Values are still read by the original key.

Git-Session-Id: 838c
@TimeToBuildBob
TimeToBuildBob force-pushed the fix/csv-export-reserved-column-collision branch from 1d2e926 to 4f031cd Compare October 14, 2026 11:37
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Rebased onto current master and pushed 4f031cd. Resolved the overlap in tests/test_server.py by retaining both master's bulk-delete/heartbeat-cache regressions and this PR's CSV collision tests; CSV behavior is unchanged.

Verification: the five test modules used by make test pass (94 tests), Ruff 0.15.22 (matching CI) and Black pass on both PR files, and the range-diff shows only the test insertion context changed. GitHub now reports the head mergeable; fresh CI is pending.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant