Commit Graph

  • f376b24106 fix: handle absolute detail_url paths in loadActivity and loadTimeseries Davide Scaini 2026-04-15 14:44:34 +02:00
  • 290eef6c72 metrics: guard against corrupted time streams causing OOM Davide Scaini 2026-04-15 14:06:20 +02:00
  • 25d80c8132 reextract: process in batches of 100 to bound subprocess memory Davide Scaini 2026-04-15 10:08:55 +02:00
  • a67b237161 reextract: reclaim RSS with malloc_trim + gc.collect every 50 activities Davide Scaini 2026-04-15 09:58:16 +02:00
  • 062ade28d3 reextract: use venv bincio script, not uv, to spawn subprocess Davide Scaini 2026-04-15 09:50:50 +02:00
  • 1a563012e2 reextract-originals: run as subprocess to avoid OOM Davide Scaini 2026-04-15 09:42:31 +02:00
  • 6890892654 trying to fix building of activities that fails because of OOM Davide Scaini 2026-04-15 09:30:22 +02:00
  • b01b00698c rewrite reextract with queue-based thread/async bridge Davide Scaini 2026-04-15 09:14:18 +02:00
  • 10dd1185b9 fix reextract: async generator + run_in_executor, imports at endpoint level Davide Scaini 2026-04-15 09:05:29 +02:00
  • 378cba85ad fix re-extract: add heartbeat yield, batch index writes, handle HTTP errors in UI Davide Scaini 2026-04-15 08:57:21 +02:00
  • 89b92397cf add re-extract from Strava originals endpoint and improve diag Davide Scaini 2026-04-15 08:08:57 +02:00
  • 1e30f85bdc add structured logging and admin diagnostics to serve Davide Scaini 2026-04-14 22:53:31 +02:00
  • fcc70a8d90 fix graph.html: set explicit pixel height for vis.js container Davide Scaini 2026-04-14 22:48:37 +02:00
  • a14cee8710 add architecture graph generator and docs Davide Scaini 2026-04-14 22:45:03 +02:00
  • 9419bd0c20 document password reset flow in CLAUDE.md and reset-password page Davide Scaini 2026-04-14 22:34:15 +02:00
  • 8fbd9a95e8 stop pre-building activity pages to fix OOM build failure Davide Scaini 2026-04-14 22:22:34 +02:00
  • 13643479ef add password reset via admin-generated one-time code Davide Scaini 2026-04-14 21:58:50 +02:00
  • d2ba96c26a fix admin delete to wipe originals/edits/geojson; rename button to Reset data Davide Scaini 2026-04-13 20:10:15 +02:00
  • a75dfa160b F14: add per-activity delete (DELETE /api/activity/{id} + drawer button) Davide Scaini 2026-04-13 19:35:40 +02:00
  • e6bb6e61a2 fix elevation_gain_m null for modern Garmin FIT files; fix map flash Davide Scaini 2026-04-13 19:18:37 +02:00
  • e7eefa345e F17: replace merge_all with merge_one in upload_image and delete_image Davide Scaini 2026-04-13 19:03:46 +02:00
  • 57fb7acd3d remove accidentally tracked local files; update .gitignore Davide Scaini 2026-04-13 18:50:20 +02:00
  • 5ad3aee8f6 rename privacy "private" → "unlisted"; enable GPS for unlisted Davide Scaini 2026-04-13 18:49:20 +02:00
  • 2ebfc7046d fix: fallback to direct file fetch in ActivityDetailLoader Davide Scaini 2026-04-13 13:04:46 +02:00
  • 1587d1cdf3 - brut: _merged/index.json has 586 activities — the count when merge_all last ran. The SSE rebuild bug (already fixed) meant it never re-ran after the full Strava sync added 3256 more. - danilo: _merged/ is 8 KB — basically empty. merge_all likely ran concurrently (multiple file uploads trigger multiple rebuilds without a lock in --no-build mode), causing a race where shutil.rmtree(merged_acts) from one run wiped what another run was writing. Davide Scaini 2026-04-13 12:35:05 +02:00
  • 7b37f45180 Bug fixed — temp ZIPs now go to /tmp/ (system temp) and are always deleted in a finally block, so they can't leak. A startup hook also auto-cleans any leftovers on next server restart. Davide Scaini 2026-04-13 12:24:59 +02:00
  • 7e526c14e1 fix commit d659b90cd9 Davide Scaini 2026-04-12 19:55:13 +02:00
  • 79e428ff0f script to rebuild pages Davide Scaini 2026-04-12 19:48:13 +02:00
  • d659b90cd9 - DELETE /api/admin/users/{handle}/activities — deletes all activities/*.json, wipes _merged/ and index.json, then triggers a rebuild. Admin-only. - /admin/ page — lists all users, each with a "Delete activities" button. Clicking asks for confirmation in a <dialog> before firing the request. Button shows "Deleted (N)" or an error inline. - "Admin" nav link — appears in the top-right for admins only, hidden for everyone else. Davide Scaini 2026-04-12 17:46:28 +02:00
  • 2774f436d8 login payoff Davide Scaini 2026-04-12 15:47:27 +02:00
  • 6d702ed454 modify post hook to install garmin packages Davide Scaini 2026-04-12 15:47:09 +02:00
  • f003fdd89f garmin sync first attempt Davide Scaini 2026-04-12 15:36:21 +02:00
  • 6c431e8821 Here's what was built and why each decision was made: Davide Scaini 2026-04-12 15:12:20 +02:00
  • e80231b442 fix strava sync rebuild: trigger before yielding done event, not after Davide Scaini 2026-04-12 14:55:33 +02:00
  • 78581d5487 redesign community page as sortable table Davide Scaini 2026-04-11 14:50:54 +02:00
  • 4d743412e1 Merge remote-tracking branch 'vps/main' Davide Scaini 2026-04-11 14:41:20 +02:00
  • 705e00f852 adding community tab Davide Scaini 2026-04-11 14:39:19 +02:00
  • 0b569b727c trigger site rebuild after new user registration so profile pages exist immediately Davide Scaini 2026-04-11 14:17:42 +02:00
  • 9015d97b18 trigger site rebuild after new user registration so profile pages exist immediately Davide Scaini 2026-04-11 14:17:42 +02:00
  • 5de9967127 fix upload 500: add missing _file_suffix to serve server; fix iOS file picker accept types Davide Scaini 2026-04-11 14:12:54 +02:00
  • f4008c0f51 pin @observablehq/plot to 0.6.17 Davide Scaini 2026-04-11 10:56:16 +02:00
  • ff8981b3a1 fix power curve y-axis: use zero:true instead of domain:[0,null] Davide Scaini 2026-04-11 10:54:13 +02:00
  • 087ef1b776 fix power chart ranges Davide Scaini 2026-04-11 09:02:58 +02:00
  • 8219db7bfa shorten bincioactivity to ba on mobile Davide Scaini 2026-04-11 09:01:47 +02:00
  • 18551f9f36 document where feedback is saved Davide Scaini 2026-04-11 09:01:34 +02:00
  • ef5b06c5b3 trigger rebuild after activities upload Davide Scaini 2026-04-11 08:47:27 +02:00
  • 82830222ba For users uploading: - POST /api/upload now returns text/event-stream instead of JSON - Per-file progress events stream back as each file is processed: ↓ 3/47 (6%) — morning_ride.fit - Final done event shows the summary: "12 added, 35 duplicates" - The Vite proxy is configured to stream this properly (no buffering) Davide Scaini 2026-04-11 08:33:21 +02:00
  • 01db4eb9ae ingest activities.csv Davide Scaini 2026-04-11 08:13:27 +02:00
  • cbd5a98cd3 - merge.py: keep private activities in _merged/index.json instead of stripping them; privacy filtering is now done client-side - ActivityFeed: detect logged-in user via bincio:me event; show private activities only when viewing your own profile; private cards get a lock badge Davide Scaini 2026-04-10 23:16:38 +02:00
  • c99b755382 The culprit is in renderChart(): it calls chart?.remove() which empties the container div, causing the layout to collapse to zero height for a moment. The browser then scrolls to keep the viewport anchored, but since the page got shorter it jumps to the top. When the new SVG is appended, the page is taller again but the scroll position was already reset. Davide Scaini 2026-04-10 22:58:34 +02:00
  • bc30e0a2fc option to keep all activities private from strava zip, fix copy of register link Davide Scaini 2026-04-10 22:51:29 +02:00
  • da622131fd upload zip archive from strava Davide Scaini 2026-04-10 22:26:11 +02:00
  • fc6c00c6eb fix: mobile nav scrolls horizontally without spilling to page width Davide Scaini 2026-04-10 22:05:42 +02:00
  • 3b8bc159c5 upload strava zip Davide Scaini 2026-04-10 22:01:44 +02:00
  • e5eadc69f2 fix: remove double px-4 on user profile page headers Davide Scaini 2026-04-10 19:20:00 +02:00
  • 9fd088c693 - "Last sync: never": The old blocking sync was killed by nginx at 120s before save_token was reached. The activities made it to disk (ingestion happens per-activity as it goes), but the token's last_sync_at timestamp was never written. After deploying, do a soft reset — it'll set last_sync_at to your most recent activity's timestamp so the next sync only fetches newer ones. - Reset 404: Added POST /api/strava/reset to serve/server.py. The soft reset now looks in _merged/index.json first (multi-user path), falling back to index.json. Davide Scaini 2026-04-10 18:34:53 +02:00
  • 816f103b4c fix: write empty index.json for new users at registration so shard resolves immediately Davide Scaini 2026-04-10 18:20:35 +02:00
  • 3e4ff4019b limit number of workers Davide Scaini 2026-04-10 18:13:49 +02:00
  • cf414a08ad fix strava import? Davide Scaini 2026-04-10 18:13:32 +02:00
  • e2765ea012 fix for strava auth Davide Scaini 2026-04-10 18:01:32 +02:00
  • f67e7552fd fix to strava sync Davide Scaini 2026-04-10 17:55:24 +02:00
  • eeed3fe3b2 Root cause of the 404: _trigger_rebuild was firing bincio render (= full astro build), but: 1. The build took minutes → 404 during that window 2. Even after the build, the output lands in site/dist/ — nginx serves from /var/www/bincio/ which is only updated by the rsync in the post-receive hook, not by the server process Davide Scaini 2026-04-10 17:48:23 +02:00
  • 61349e6292 fix: resize map before fitBounds and defer with rAF to avoid layout-timing glitch Davide Scaini 2026-04-10 17:44:52 +02:00
  • a20df6bd57 fix: hide community stats/tree on about page for non-logged-in users Davide Scaini 2026-04-10 17:40:16 +02:00
  • 96a3deee5d fix: serve data/ from disk via nginx alias; return full athlete data from API Davide Scaini 2026-04-10 15:57:23 +02:00
  • ae883a7dba fix: rebuild athlete.json on every ingest; remove bincio-extract references from UI Davide Scaini 2026-04-10 15:47:50 +02:00
  • f8e02f3da2 fix: athlete page falls back to /api/athlete when static file not yet rebuilt Davide Scaini 2026-04-10 15:43:01 +02:00
  • 6a8ef984cb fix: GET/POST /api/athlete work without a pre-existing athlete.json Davide Scaini 2026-04-10 15:37:05 +02:00
  • f790deb54f fix: athlete page shows empty state instead of error when athlete.json missing Davide Scaini 2026-04-10 15:35:41 +02:00
  • 8d8b009a78 fix: use shutil.which to find uv in _trigger_rebuild; never 500 on rebuild failure Davide Scaini 2026-04-10 15:33:06 +02:00
  • 7088b94a87 fix: bincio init always sets private:true even if index.json already exists Davide Scaini 2026-04-10 15:26:11 +02:00
  • 27f94cf581 fix: respect instancePrivate when determining single-user mode in Base.astro Davide Scaini 2026-04-10 15:19:41 +02:00
  • 2481093a0a trigger rebuild Davide Scaini 2026-04-10 15:15:54 +02:00
  • 5371c77c8f update vps instructions Davide Scaini 2026-04-10 15:14:44 +02:00
  • e006175285 fix: don't redirect to /u/{handle}/ on private (multi-user) instances Davide Scaini 2026-04-10 15:06:45 +02:00
  • ceb8e28b74 update deployment instructions Davide Scaini 2026-04-10 15:06:31 +02:00
  • 4593478863 feedback page Davide Scaini 2026-04-10 13:58:12 +02:00
  • 6d3673b2f7 1. Image upload size limit — _MAX_IMAGE_BYTES = 10 MB in both serve/server.py and edit/server.py 2. Image MIME type whitelist — _ALLOWED_IMAGE_TYPES blocks SVG XSS in both servers 3. Filename collision safety — _unique_image_name() helper in both servers 4. OAuth CSRF — state token generated in edit/server.py auth-url, stored in _oauth_states, validated and discarded in callback; strava_api.auth_url() accepts optional state param 5. Error message leak — upload processing errors now return generic "Processing failed" instead of exception type/message 6. Handle injection in subprocess — _trigger_rebuild now asserts handle matches _VALID_HANDLE before passing to subprocess Davide Scaini 2026-04-10 13:54:50 +02:00
  • 8b7cdd9ed1 explain invitation system Davide Scaini 2026-04-10 13:42:00 +02:00
  • 053da10ab9 some basic statistics and invite tree, plus watch new data Davide Scaini 2026-04-10 13:21:31 +02:00
  • 6b2d31a44a test server imports Davide Scaini 2026-04-10 13:06:00 +02:00
  • f37e898eb5 about page Davide Scaini 2026-04-10 13:05:51 +02:00
  • 469a5954cc "keep data on the server" opt-in/out Davide Scaini 2026-04-10 13:01:21 +02:00
  • 5170afa9e8 vps instructions Davide Scaini 2026-04-10 12:53:35 +02:00
  • 8ceb714765 bulk upload Davide Scaini 2026-04-10 12:50:38 +02:00
  • ce00a63d43 Merge branch 'vps' into mobile_app Davide Scaini 2026-04-10 12:38:40 +02:00
  • 683b7d9c1b limit max number of users Davide Scaini 2026-04-10 12:35:34 +02:00
  • b4acf8c1a6 populate pages when a new user joins Davide Scaini 2026-04-10 12:35:34 +02:00
  • cbac82a2ba Fix 1 — new user pages 404 (server.py:228): After registration creates the user's directories, it now calls _write_root_manifest(dd). This rewrites index.json to include the new handle's shard immediately. Since Astro dev re-evaluates getStaticPaths() on every request (reading that file), /u/pres/, /u/pres/stats/, and /u/pres/athlete/ will resolve correctly as soon as the new user navigates there. Davide Scaini 2026-04-09 21:44:38 +02:00
  • 084c652fdd fixing stuff after splitting jsons Davide Scaini 2026-04-09 15:27:00 +02:00
  • 8118f6f316 1 — Timeseries split Davide Scaini 2026-04-09 14:01:02 +02:00
  • 76b7b9ac7e swapping activities for a more diverse set Davide Scaini 2026-04-09 13:44:59 +02:00
  • bf95097d75 fix image Davide Scaini 2026-04-09 13:39:44 +02:00
  • 5a29259259 fix edit profile Davide Scaini 2026-04-09 13:21:47 +02:00
  • fb202b4edf Record / Convert tabs — now gated behind PUBLIC_MOBILE_APP=true. Hidden by default in VPS/dev mode; only show when explicitly opted into the mobile app build. Davide Scaini 2026-04-09 13:16:00 +02:00
  • 2501c9e0f6 added some data to facilitate debugging... to be decided wether to publish this data or not in github Davide Scaini 2026-04-09 13:03:19 +02:00
  • 50cdeb3b6e ActivityFeed — replaced the <button> inside <a> (invalid HTML, unreliable) with the stretched-link pattern: the card is now a <div>, the title <a> carries a ::before pseudo-element that covers the whole card making it clickable, and @handle is a proper <a> with z-index: 10 sitting above the stretched link. Clicking the handle navigates to /u/{handle}/; clicking anywhere else navigates to the activity. Davide Scaini 2026-04-09 12:32:22 +02:00
  • 7dcb1e6dd0 refactor: extract/ingest facade, merge_one, deduplicate ops constants Davide Scaini 2026-04-09 12:03:06 +02:00
  • 0223d468c9 add tests: test_metrics.py (31 tests) — _haversine_m correctness and symmetry; compute() end-to-end for GPS distance, device distance preference, moving-time stop exclusion, elevation gain/loss, HR, power, bbox, endpoints; MMP sliding-window constant and peak cases; _fastest_time_for_distance and compute_best_efforts for running targets; _best_climb including gap-reset behaviour. Davide Scaini 2026-04-09 10:36:52 +02:00
  • e662bb6426 missing file Davide Scaini 2026-04-09 10:36:28 +02:00