Commit Graph

12 Commits

Author SHA1 Message Date
Davide Scaini 55d59112ad Fix: don't copy 9 GB data dir into dist/ during production builds
BINCIO_DATA_DIR is already set in the build env, so manifest.ts reads
the data root directly at build time without needing public/data.
Moving _link_data() into the serve-only branch prevents Astro from
following the symlink and copying the full data dir into dist/. Any
leftover symlink from a previous dev session is removed before build.
Dev mode is unchanged.
2026-05-08 13:56:31 +02:00
Davide Scaini db7047f210 perf: combined feed index for multi-user global feed
Instead of the browser resolving 20+ user shards recursively (~27 MB),
generate a pre-sorted feed.json at merge time with 50 activities per
page. The global feed loads one ~30 KB file on first paint; "Load more"
fetches subsequent pages (feed-2.json, feed-3.json, etc.).

Per-user profile pages still use year-sharded loadIndexPaged as before.
2026-04-20 15:31:35 +02:00
Davide Scaini 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

  Fixes applied:

  1. bincio/render/cli.py: Added --no-build flag — merges sidecars and updates manifests but skips astro build. This is fast (~1 second).
  2. bincio/serve/server.py _trigger_rebuild: Now passes --no-build. After an upload, _merged/ and root index.json are updated immediately, so the feed reflects the new activity. The static Astro pages are
  only rebuilt on git push.
  3. site/src/components/ActivityDetailLoader.svelte (new): Svelte component that reads the activity ID from the URL, calls loadIndex to resolve the shard tree, then renders ActivityDetail dynamically — no
  pre-built page needed.
  4. site/src/pages/activity/index.astro (new): Generic Astro shell page that renders ActivityDetailLoader. Gets compiled to dist/activity/index.html.
  5. docs/deployment/vps.md: Added location /activity/ { try_files $uri $uri/ /activity/index.html; } to the nginx config. When a request arrives for /activity/2026-04-06T153345Z/ and no pre-built file
  exists, nginx serves the shell, which loads the data dynamically from /data/ (which nginx already serves live from disk).
2026-04-10 17:48:23 +02:00
Davide Scaini cf7c71b8a3 (opus assessment) Fix auth wall flash, broken multi-user write API, and single-user redirect loop
Auth wall (Base.astro): set data-auth-pending on <body> at SSG time and hide
  it with inline CSS before any JS runs; remove the attribute after /api/me
  resolves. Eliminates the flash of protected content on private instances.

  Multi-user write API (serve/server.py): the previous _apply_sidecar_edit and
  strava_sync imports from bincio.edit.server were broken (those names don't
  exist as module-level exports) and the Strava sync mutated a global data_dir,
  making concurrent requests from different users racy. Fix: extract both
  operations into bincio/edit/ops.py as pure functions that take data_dir
  explicitly. Both edit/server.py and serve/server.py now import from there.

  Security: add rate limiting to POST /api/register (5 attempts / 15 min / IP,
  separate bucket from login). Add _check_id() activity ID validation to both
  GET and POST /api/activity/{id} in serve/server.py.

  Single-user mode: _write_root_manifest now forces instance.private=false when
  no instance.db exists, even if a previous run wrote true. Prevents the auth
  wall from firing and redirecting to /login/ when bincio serve isn't running.

  ActivityFeed: skip filterHandle when profileIndexUrl is set (per-user profile
  pages load the right shard directly; activities have no handle tag at that
  point, so the filter was producing an empty feed). Fix handle links to point
  to /u/{handle}/ instead of /{handle}/. Fix <a>-inside-<a> Svelte warning by
  converting the inner handle link to a <button>.
2026-04-09 09:19:48 +02:00
Davide Scaini 98c42dc443 unify single user and multi user behaviour 2026-04-09 08:59:40 +02:00
Davide Scaini f76cc0ce7e towards multi-user 2026-04-08 19:37:10 +02:00
Davide Scaini 81438231b4 fix low level issues 2026-03-31 23:22:12 +02:00
Davide Scaini c58bc8f7d5 fix default config loading 2026-03-30 15:39:58 +02:00
Davide Scaini 7c281a48d7 fix: edit extras install command and render symlink parent dir 2026-03-29 16:52:58 +02:00
Davide Scaini 1d3848f85e feat: activity sidecar edits via bincio edit --serve
- bincio/render/merge.py: parse sidecar .md files (YAML frontmatter +
     markdown body), produce data/_merged/ with symlinks for unmodified
     activities and real merged files for overridden ones; filters private
     activities from index.json; sorts highlighted activities first.
     Keeps extracted data pristine — re-running extract never clobbers edits.

   - bincio/edit/: FastAPI edit server (port 4041) with embedded HTML/JS
     edit UI; GET/POST /api/activity/{id} reads/writes sidecars; multipart
     image upload to edits/images/{id}/; DELETE for image cleanup.

   - bincio render now calls merge_all() before build/serve and symlinks
     public/data → data/_merged/ instead of data/ directly.

   - ActivityDetail.svelte: edit button (links to edit server) when
     PUBLIC_EDIT_URL env var is set; respects custom.hide_stats to suppress
     stat panels; description supports whitespace-preserving rendering.

   - 15 unit tests covering parse_sidecar, apply_sidecar, and merge_all.
2026-03-29 15:06:55 +02:00
Davide Scaini 3441079913 map now working 2026-03-28 19:34:22 +01:00
Davide Scaini 38c5423aeb backend: initial commit 2026-03-28 13:59:36 +01:00