open-design/packages
lefarcen fab172b782
feat(analytics): emit file_upload_result from all three upload entries (#2459)
* feat(analytics): emit file_upload_result from all three upload entries

`file_upload_result` was wired only on the Design Files Upload button in
FileWorkspace. The chat composer paperclip (project page) and the home
hero composer paperclip uploaded files silently — PostHog dashboards
saw upload activity from one of three real entry points, so per-surface
funnels were invisible and totals undercounted.

Three problems are fixed together:

1. `FileUploadResultProps` hard-coded `page_name: 'file_manager' /
   area: 'file_manager'`, which prevented the other two surfaces from
   type-checking. Widened to a discriminated union over the three v2
   doc surfaces (`file_manager` / `chat_panel` chat_composer /
   `home` chat_composer).

2. `HomeChatComposerClickProps.element` was missing `'attachment'`, so
   the home composer paperclip had no usable click value even if we
   wanted to instrument it. Added the literal, mirroring the
   chat_panel composer.

3. Three call sites for `file_upload_result` would duplicate the
   per-file mime + total-bytes cohort math. Extracted to
   `apps/web/src/analytics/upload-tracking.ts#deriveUploadCohort` so
   FileWorkspace, ChatComposer, and the App.tsx Home submit path all
   compute the same `file_count` / `file_type` / `file_size_bucket`
   triplet. FileWorkspace's inline math is replaced with the shared
   helper to prevent drift.

Call-site wiring:

- HomeHero attach button: `ui_click` (`element='attachment'`) at
  click time. The actual upload is deferred to submit, so the
  `file_upload_result` for this surface fires from App.tsx after
  `uploadProjectFiles` resolves.
- ChatComposer.uploadFiles: `file_upload_result` on success / failed /
  throw branches; existing `ui_click` (`element='attachment'`) at the
  paperclip stays as-is.
- FileWorkspace.uploadFiles: refactored to use `deriveUploadCohort`;
  behavior unchanged.

* test(analytics): cover deriveUploadCohort matrix

Reviewer flagged that deriveUploadCohort silently fans out to three
upload entry points (file_manager / chat_panel / home) but has no
focused coverage, so a regression in zip detection, mixed-type
collapsing, or the 1/10/100 MB thresholds would skew analytics
without breaking any visible UI behavior.

Adds homogeneous-image, zip-by-mime, zip-by-extension, mixed-type,
empty-batch, bucket-boundary (1/10/100 MB), and defensive
empty-mime cases.
2026-05-21 18:28:56 +08:00
..
agui-adapter chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
contracts feat(analytics): emit file_upload_result from all three upload entries (#2459) 2026-05-21 18:28:56 +08:00
diagnostics feat(diagnostics): add one-click log export from Settings → About (#798) 2026-05-20 09:10:51 +08:00
host feat(desktop): follow OS language in packaged builds (cherry-pick of #2544 into release/v0.8.0) (#2560) 2026-05-21 18:23:20 +08:00
platform release: Open Design 0.8.0 2026-05-20 21:22:17 +08:00
plugin-runtime chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
registry-protocol chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
sidecar release: Open Design 0.8.0 2026-05-20 21:22:17 +08:00
sidecar-proto release: Open Design 0.8.0 2026-05-20 21:22:17 +08:00
AGENTS.md refactor desktop host bridge (#2246) 2026-05-19 18:27:05 +08:00