Skip to content

feat(buckets): use server-side CSV export endpoint - #997

Merged
ErikBjare merged 4 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/csv-export-server-side
Sep 23, 2026
Merged

ErikBjare merged 4 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/csv-export-server-side

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Summary

Replace the client-side PapaParse CSV export with a direct call to the new server-side streaming endpoint GET /api/0/buckets/{id}/export/csv (ActivityWatch/aw-server-rust#722).

The problem: The existing export_csv method fetches all events as JSON, builds a PapaParse CSV in JavaScript, and creates a Blob. For buckets with 500k+ events on Android WebView this causes OOM or a connection that looks hung — there's no response at all until the full payload is ready.

The fix:

  • Browser / Android WebView: direct anchor navigation to the server endpoint. The server sends 200 OK headers immediately (before serialization begins), so the WebView sees a live response right away. Events never enter JS memory.
  • Tauri desktop (<a download> is unsupported): fetch the CSV text via the existing API client, then save via the native file dialog — same as today but with server-side CSV generation.

Also removes the import Papa from 'papaparse' that is no longer needed.

Related

Replace the client-side PapaParse approach with a direct request to the
new server endpoint GET /api/0/buckets/{id}/export/csv.

In a regular browser (including Android WebView), an anchor navigation
is used so the browser handles the download natively — no events ever
enter JS memory and headers arrive immediately, fixing the apparent hung
connection on large buckets.

In Tauri (where <a download> is not supported), the CSV text is fetched
via the API client and saved through the native file dialog.

Removes the papaparse import from this file.

Git-Session-Id: cdc6
@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The runtime change appears sound, but the repository’s required performance-measurement step must be documented or completed before merging.

Findings

  1. P2 Performance Measurement Missing ▶

Summary

The PR replaces browser-side CSV generation with the server’s CSV export endpoint while selecting a download mechanism appropriate to each runtime.

  • Regular unauthenticated browsers use direct navigation to preserve streaming.
  • Authenticated browsers and Tauri use the API client and a Blob.
  • Android delegates the URL to its native export bridge.
  • The PapaParse dependency is removed from this view, and source-level tests cover the selected branches.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Export CSV requested] --> B{Android bridge available?}
    B -->|Yes| C[Native URL export]
    B -->|No| D{Browser without stored token?}
    D -->|Yes| E[Direct anchor download]
    D -->|No| F[Authenticated API request]
    F --> G[Download returned Blob]
Loading

Reviews (3) · Last reviewed commit: "fix(buckets): stream unauthenticated bro..."

Comment thread src/views/Buckets.vue
Comment thread src/views/Buckets.vue
timeout: 0 was added for the Tauri fallback path but the existing test
(added in ActivityWatch#993) explicitly verifies no timeout: 0 remains. The server-side
CSV streaming endpoint is fast to start (headers sent before serialization),
so 5 minutes matches the large-event-JSON path and is sufficient.

Git-Session-Id: 70d5
@codecov

codecov Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.66%. Comparing base (7eac81a) to head (c585a3d).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #997   +/-   ##
=======================================
  Coverage   57.66%   57.66%           
=======================================
  Files          51       51           
  Lines        3231     3231           
  Branches      794      794           
=======================================
  Hits         1863     1863           
- Misses       1291     1352   +61     
+ Partials       77       16   -61     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The browser path used a bare <a> navigation, which drops Authorization
and cannot report 4xx/network failures. Use the same path as JSON
export: Android native URL download, then an authenticated blob GET
with the 5-minute timeout. downloadBlob still handles Tauri.

Git-Session-Id: d11ab6e2-235d-55ab-8e68-e80e65a02e47
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Pushed 3eba796 to address the Greptile 4/5 findings:

  • P1 auth: browser CSV export no longer uses a bare <a> navigation. Same path as JSON export — Android native exportFromUrl, otherwise $aw.req blob so Authorization: Bearer is sent.
  • P2 hidden failures: axios errors now populate the existing export alert. downloadBlob still handles Tauri.

The earlier CI failure (timeout: 0 vs the #993 source-scan) was already fixed on this branch (aa8c501). Local Buckets.test.js is green.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread src/views/Buckets.vue
Restore <a> navigation for local installs so the server-side CSV
endpoint can stream. Keep the authenticated blob path for Tauri and
Bearer-token deployments, which cannot attach Authorization to a
navigation download.

Git-Session-Id: 92d2be57-41cd-59e0-8f80-fc2b1a31d6af
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread src/views/Buckets.vue
@ErikBjare
ErikBjare merged commit f5391fe into ActivityWatch:master Sep 23, 2026
9 checks passed
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Merged by Erik (f5391fe). Remaining half is ActivityWatch/aw-server-rust#722 — still open, CI green, waiting on review.

Leaving #995 open until that endpoint lands. Master webui now calls GET /api/0/buckets/{id}/export/csv.

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.

2 participants