Files
beardrive/internal/webapp/static/index.html
T
826d13795f fix(webapp): show how many times a public link has been opened (BEA-76) (#125)
Every /s/<token> hit was already recorded as a share-kind read, carrying
both a count and a timestamp — and then thrown away at the UI layer. The
Public links table showed only who shared a file and when, six inches
below a file header that already said "1 shared". Two personas filed it
independently on the same tour.

The number now rides the shares list:

  * ReadLedger.ShareOpens(project) aggregates share-kind buckets per path,
    all-time. Share-kind only is what makes Last mean *last opened* —
    HeatEntry.LastRead is cross-kind, so a member viewing the file in the
    hub would otherwise move the date.
  * shareJSON takes the project's opens map, built ONCE per project by the
    caller and indexed per row. Both callers — the project list and the
    org-wide audit — hoist it above their loops; a per-share call would be
    a full byKey scan per row.
  * Counts, never openers. The share actor is token+"/"+IP, a public
    credential joined to an IP, and it stays in the ledger. There is no
    distinct-openers field, deliberately.
  * Reads off means the keys are ABSENT, not zero: `0` would claim nobody
    has opened a link on a hub that never looked.

shareDetail() is the leverage — the settings table, the org-wide audit and
the file page's share banner all render through it, so one string function
covers three surfaces. Once the row carried the receipt it truncated to
"3 op…", so the detail cell wraps instead of ellipsizing; the path keeps
its ellipsis, since it is a link with a tooltip and the column that can be
arbitrarily long.

Counted per FILE, not per link: heat is keyed by path, so two tokens on one
file report the same number. Worded that way in the section copy, alongside
the other honesty — opens are debounced visits, not requests.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 00:38:44 +09:00

15 lines
632 B
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BearDrive</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%23f5a623'><rect x='4' y='4' width='5.6' height='24'/><rect x='11.2' y='4' width='14.4' height='11.2'/><rect x='11.2' y='16.8' width='16.8' height='11.2'/></svg>">
<script type="module" crossorigin src="/assets/index-CM4CrIy-.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C62PcDae.css">
</head>
<body>
<div id="root"></div>
</body>
</html>