Skip to content

feat(profile): redesign public profiles for compact usage analysis - #857

Merged
junhoyeo merged 22 commits into
mainfrom
feat/compact-user-profiles
Jul 12, 2026
Merged

feat(profile): redesign public profiles for compact usage analysis#857
junhoyeo merged 22 commits into
mainfrom
feat/compact-user-profiles

Conversation

@junhoyeo

@junhoyeo junhoyeo commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • Rebuild the public profile as a compact, full-width service dashboard with a stronger identity header, emphasized rank, larger avatar, and left-packed headline metrics.
  • Add an explorable stacked area usage chart with token/cost modes, trailing-average display, provider filtering, sorted model/provider tooltips, and model colors aligned with the TUI.
  • Restore a detailed contribution experience with responsive 2D and 3D views, color themes, per-day hover details, click-to-select breakdowns, token categories, and complete client/model totals.
  • Keep Usage details, Token mix, and Devices visible in the main profile flow instead of hiding core context behind separate tabs.
  • Redesign all eight 2D embed templates plus the 3D contribution card around one compact service language, truthful rolling-year data, fitted values, and readable live previews.
  • Add focused tests for contribution aggregation, usage-series construction and geometry, embed options, and SVG template output.

Why

The previous profile constrained analytics to a narrow canvas, split related information across tabs, and provided limited context when exploring chart or contribution data. The embed experience also relied on generic decorative templates and explanatory copy instead of showing the output clearly. This change establishes one compact visual language and keeps related usage context visible together.

User impact

Profiles now use the available desktop width without becoming sparse, while retaining a single-column mobile layout. Users can compare model and provider activity over time, inspect individual contribution days, switch contribution rendering and color themes, and copy more useful embed cards directly from the profile.

Validation

  • bun run test: 60 test files, 563 tests passed
  • NEXT_PUBLIC_URL=http://127.0.0.1:3100 bun run build: production compilation, application TypeScript, and static generation passed
  • Scoped ESLint and Prettier checks passed for every modified frontend file
  • Actual-data smoke checks passed for /u/junhoyeo and /api/users/junhoyeo?period=all
  • Desktop and mobile visual checks passed with no horizontal overflow; profile verdict 99/100 and embed/modal verdict 94/100

Known existing issue

Standalone bunx tsc --noEmit still reports pre-existing mock tuple errors in __tests__/api/groupMemberRoleRoute.test.ts lines 159–160. The production build TypeScript check passes.


Summary by cubic

Redesigned public profiles into a compact, full‑width analytics dashboard with an explorable usage history and a clearer identity header. Unifies embed cards and adds a capability‑driven, preview‑first embed dialog with 2D/3D views.

  • New Features

    • Usage: stacked area chart with tokens/cost modes, trailing‑average, provider filtering, and model colors aligned with the TUI.
    • Contributions: rolling recent year plus calendar years, accessible 2D and inline 3D that share range/selection, nearest‑cell tap targeting, and inert future dates.
    • Embed dialog: capability‑driven controls with a live preview from the current origin; supports view=2d|3d, explicit compact formatting/layout, number formats, and clearer template labels.
    • 2D templates: shared compact card grammar with fitted text; contribution panels match the profile while keeping public template IDs and query options.
  • Bug Fixes

    • Accurate totals: preserve mixed client model attribution, reconcile nested model aggregates, restore token‑linear 3D heights, and use a dark‑surface intensity ramp; keep 2D cells square.
    • Layout/geometry: 1280px responsive canvas with dense sections; active chart markers render in CSS pixel space to avoid SVG stretch distortion.
    • Truthful ranges: exact trailing‑year boundaries including leap day; empty or malformed inputs no longer collapse graphs; future cells remain non‑interactive.
    • Navigation/preview: mobile menu stays inert when closed; protected Vercel previews reuse cached server loaders; preview URLs come from the current origin while copied snippets remain canonical.

Written for commit 8cc1de7. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tokscale Ready Ready Preview, Comment Jul 12, 2026 1:38pm

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 41 files

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread packages/frontend/__tests__/lib/getUserEmbedStats.test.ts
Comment thread packages/frontend/src/lib/embed/renderBlueprintEmbedSvg.ts Outdated
Comment thread packages/frontend/src/components/profile/embedDialogOptions.ts Outdated
Comment thread packages/frontend/src/components/profile/usageChartGeometry.ts Outdated
Comment thread packages/frontend/src/components/profile/ProfileModels.tsx
Comment thread packages/frontend/src/components/profile/ProfileTabBar.tsx Outdated
Comment thread packages/frontend/src/app/u/[username]/ProfilePageClient.tsx Outdated
Comment thread packages/frontend/src/components/profile/TokenBreakdown.tsx
Comment thread packages/frontend/src/components/profile/ProfileUsageChart.tsx Outdated
Comment thread packages/frontend/src/components/profile/ProfileContributionGraph.tsx Outdated
junhoyeo added a commit that referenced this pull request Jul 12, 2026
Reviewing the public profile and embed flows exposed edge cases where empty contribution arrays collapsed requested graphs, hidden synthetic usage distorted visible model shares, and separate server/client clocks could disagree about the rolling-year range. Normalize those boundaries and add regression coverage so the rendered metrics remain truthful for malformed, empty, and time-sensitive inputs.

Constraint: Preserve canonical embed URLs and existing profile period semantics while making helper inputs safe for non-canonical usernames and non-finite values.

Rejected: Resolve the hydration mismatch in the browser with a client-only guard | that would hide the mismatch instead of making the server and client render the same data.

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep the server-provided chartRange authoritative for any future client-rendered rolling windows.

Tested: 568 frontend Vitest tests; TypeScript check; targeted ESLint; Prettier check; production build.

Not-tested: Live visual review against production data after this follow-up commit.

Related: #857

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 23 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/frontend/src/app/api/users/[username]/route.ts Outdated
junhoyeo added a commit that referenced this pull request Jul 12, 2026
The compact contribution calendar uses very small cells at wide desktop widths, so even a modest border radius reads as a field of dots instead of the familiar square contribution grid. Keep the interactive 2D cells square while retaining the existing focus and selection rings.

Constraint: Preserve the existing grid geometry, colors, keyboard interactions, and isometric view.

Rejected: Increase cell size to hide the rounded corners | that would change the responsive density and still fail at narrower widths.

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep 2D contribution cells square unless the product intentionally changes the contribution-grid language.

Tested: Profile contribution calendar Vitest suite (14 tests); Prettier check.

Not-tested: Live Vercel visual capture.

Related: #857 #859 #860
junhoyeo added a commit that referenced this pull request Jul 12, 2026
Clamp the prior-year rolling range to the last valid day in its month so a Feb 29 request does not silently begin on Mar 1 and omit Feb 28 activity. Add a route regression test covering the leap-day boundary.

Constraint: Rolling profile ranges must remain calendar-date based and deterministic in UTC

Rejected: Rely on Date#setUTCFullYear alone | JavaScript normalizes invalid February 29 targets into March

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep leap-day behavior covered whenever rolling chart range logic changes

Tested: bunx vitest run __tests__/api/usersProfile.test.ts; bunx prettier; git diff --check

Not-tested: Full frontend suite and live preview after this follow-up

Related: #857 #859 #860

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 10 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/frontend/src/lib/publicProfileData.ts
@junhoyeo

Copy link
Copy Markdown
Owner Author

@codex review

Please review the current head after the stack rebase.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

junhoyeo added 10 commits July 12, 2026 22:37
Replace the oversized embed editor with a viewport-contained preview-first workflow, remove promotional filler, use descriptive template labels, and derive visible controls plus URL parameters from the renderer capability matrix.

Constraint: Preserve every public embed query id and API contract without adding dependencies

Rejected: Keep every control visible in every view | several combinations are ignored by the 3D and compact renderers

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Add renderer capabilities to embedDialogOptions before exposing future controls

Tested: 5 embed option tests, 12 embed route tests, scoped ESLint and Prettier

Not-tested: Full production build deferred to the final branch verification
The profile now uses one compact service language for identity, model-level stacked usage, contribution density, token mix, supporting facts, and device history. Daily contribution cells provide viewport-safe hover detail and a pinned client/model breakdown without losing keyboard access.

Constraint: Preserve existing profile API, authentication, and submission contracts while using no new frontend dependency.

Rejected: Reuse the shared local-only chart renderer | it cannot represent model-level stacked history or the profile interaction contract.

Confidence: high

Scope-risk: moderate

Directive: Keep tooltip sorting independent from stable stack order, and keep Token mix immediately below Contributions.

Tested: 35 focused profile unit tests, changed-file ESLint, Prettier, diff check, real-data browser interaction, and visual-verdict score 94/100.

Not-tested: Full frontend suite and production build are deferred to the final branch verification pass.
Model colors now use the same family and version precedence as the terminal UI, so Fable receives the primary source shade before Opus, Sonnet, Haiku, and remaining families. Shade ranking remains independent from area stack order and value-sorted tooltip rows.

Constraint: Preserve each source base color and the existing chart ordering contracts.

Rejected: Rank shades by spend or token volume | this made the same model family change color as the selected metric or range changed.

Confidence: high

Scope-risk: narrow

Directive: Update frontend and TUI family precedence together if a new named Claude tier is introduced.

Tested: 20 focused aggregation/color tests, changed-file ESLint, Prettier, and diff check.

Not-tested: Cross-platform pixel comparison of browser and terminal color rendering.
The desktop profile now uses a 1280px responsive canvas with a full-width usage chart and a compact activity/details split below it. Active chart points render in CSS pixel space, so the intentionally stretched plotting SVG cannot distort circular markers.

Constraint: Token mix must remain directly below Contributions, and tablet/mobile must retain the same single-column reading order.

Rejected: Preserve the 896px content ceiling | it cramped the area chart and wasted wide-screen space.

Rejected: Compensate SVG circle radii with a fixed ratio | the ratio changes with every responsive container size.

Confidence: high

Scope-risk: narrow

Directive: Keep active markers outside the preserveAspectRatio=none SVG unless their geometry is dynamically compensated.

Tested: 33 focused profile tests, changed-file ESLint, Prettier, diff check, zero-overflow checks at 1440px and 390px, wide-layout visual score 97/100, and marker visual score 99/100.

Not-tested: Full frontend suite and production build are deferred to the final branch verification pass.
All eight 2D renderers now share one restrained card grammar while keeping explicit information roles: overview, token focus, command readout, contribution-first, rank-first, activity signals, detailed facts, and compact ledger. Generic template-taxonomy copy, gradients, glows, patterns, metaphor chrome, and novelty decoration are removed.

Constraint: Preserve template IDs, query options, XML safety, light/dark palettes, contribution titles, and the independent 3D renderer.

Rejected: Make every template the same metric card with different labels | it reduced choice to cosmetic duplication.

Rejected: Redesign the 3D renderer into the flat 2D grammar | its contribution geometry is an intentional supported view.

Confidence: high

Scope-risk: moderate

Directive: Keep new templates within the shared surface/header/footer and semantic-color grammar, but give each one a distinct data hierarchy.

Tested: 106 focused renderer/route/3D tests, changed-file ESLint, Prettier, diff check, xmllint on ten actual-data SVGs, and embed gallery visual score 94/100.

Not-tested: GitHub README rendering across every third-party Markdown host.
The modal now loads its preview from the current origin while keeping copied snippets canonical to tokscale.ai, so local iteration shows the renderer actually being edited. Redundant preview chrome is removed, 2D and 3D receive aspect-appropriate stage heights, and 3D continues to expose only controls its renderer consumes.

Constraint: Copied Markdown, HTML, and image URLs must remain canonical production links.

Rejected: Point the entire embed builder at the current origin | that would leak localhost URLs into copied snippets.

Confidence: high

Scope-risk: narrow

Directive: Keep preview URL construction separate from canonical snippet generation.

Tested: 41 focused modal/route/3D tests, changed-file ESLint, Prettier, diff check, actual-data 2D and 3D browser previews, and modal visual score 96/100.

Not-tested: Clipboard APIs in non-Chromium browsers.
Nested model snapshots can carry a stale aggregate alongside newer token components, so the contribution detail now follows the usage chart reconciliation rule and keeps the larger truthful value.

Constraint: Preserve valid reported aggregates when they exceed the component sum.

Rejected: Always replace the aggregate with the component sum | older payloads may include token categories the current schema does not expose.

Confidence: high

Scope-risk: narrow

Directive: Reconcile nested token aggregates with Math.max anywhere profile detail consumes both representations.

Tested: Regression reproduced before the fix; 60 frontend test files and 507 tests passed afterward, plus scoped ESLint, Prettier, and diff check.

Not-tested: Historical payload variants that omit both aggregate and components.
…nalytics

The profile now uses independent desktop stacks: a 650px Contributions and full selected-day breakdown column on the left, with a wider usage chart, usage facts, and token mix column on the right. Both 2D and accessible inline 3D views share palette and range-owned selection state, while the standalone breakdown expands without nested scrolling.

Constraint: Preserve actual profile API data, existing period routes, mobile responsiveness, and the supported 3D contribution view without adding dependencies.

Rejected: Stretch Contributions to match the usage chart row | it produced a square card with excessive empty space and a small calendar.

Rejected: Reuse the 3D embed card or local canvas | neither preserves the profile range, detailed selection, or keyboard interaction contract.

Confidence: high

Scope-risk: moderate

Directive: Keep contribution selection owned by the active range so prior dates never revive after period navigation.

Tested: 60 frontend test files and 510 tests, production build and TypeScript, scoped ESLint and Prettier, actual-data profile/API smoke tests, Lifetime-to-7d-to-Lifetime selection, 2D/3D pointer and keyboard interactions, zero nested/page overflow, and visual verdict 98/100.

Not-tested: Screen-reader announcements across every browser and assistive-technology combination.
Give the profile identity a clearer visual anchor while keeping the desktop header compact. Usage details now reads as the same class of service card as the surrounding datasets, and primary totals have an explicit left-aligned scan path.

Constraint: Preserve the compact profile layout and add no dependencies.

Rejected: Oversized promotional rank treatment | It would compete with the usage data and break the restrained service language.

Confidence: high

Scope-risk: narrow

Directive: Keep rank as the only accented identity metadata; do not turn adjacent profile facts into badges.

Tested: 60 frontend test files and 510 tests; production build and TypeScript; scoped ESLint and Prettier; desktop and mobile actual-data screenshots; computed avatar sizes, metric alignment, and card geometry; visual verdict 98/100.

Not-tested: Every third-party avatar aspect ratio.
Limit the desktop summary to four fixed compact tracks so totals scan as one group instead of stretching across the full analytics canvas. Container queries preserve the existing two-column mobile treatment when the card itself is narrow.

Constraint: Preserve the full-width profile card boundary and existing mobile hierarchy.

Rejected: Shrink the entire summary element to fit-content | This leaves an unfinished empty surface under the right side of the profile header.

Confidence: high

Scope-risk: narrow

Directive: Keep headline metric tracks compact even if the outer analytics canvas grows.

Tested: 60 frontend test files and 510 tests; Next production build and application TypeScript; scoped ESLint and Prettier; desktop and mobile actual-data screenshots; 592px desktop used width, 2-column mobile layout, zero horizontal overflow; visual verdict 99/100.

Not-tested: Standalone tsc --noEmit remains blocked by pre-existing mock tuple errors in groupMemberRoleRoute.test.ts lines 159-160.
junhoyeo added 12 commits July 12, 2026 22:37
Map taps on packed 2D and 3D chart whitespace to the nearest rendered day, so mobile users can select dates without hitting four-pixel cells precisely. Coarse-pointer view and palette controls expose 44px effective targets while retaining their compact visual dimensions.

Constraint: Preserve the dense year overview, existing keyboard navigation, and direct cell selection semantics.

Rejected: Enlarge every contribution cell to a standalone touch target | A full year would no longer fit without horizontal scrolling or loss of context.

Confidence: high

Scope-risk: narrow

Directive: Keep chart-level selection limited to the nearest rendered cell within 24px and exclude direct cell targets from the bubbling handler.

Tested: 60 frontend test files and 511 tests; production build and application TypeScript; scoped ESLint and Prettier; real coarse-pointer taps on 2D gaps and 3D whitespace at 320px; keyboard and direct-click regression audit; zero overflow at 320px, 390px, and 430px; visual verdict 99/100.

Not-tested: Physical Mobile Safari touch-event behavior.
Connect the hamburger to its controlled menu state and mark the collapsed dropdown inert, preventing invisible links from appearing in the accessibility tree or keyboard order. The compact icon retains its visual size while exposing a 44px coarse-pointer target.

Constraint: Preserve the existing dropdown animation and mobile navigation appearance.

Rejected: Conditionally unmount the dropdown | It removes the current close animation and adds unnecessary state-transition churn.

Confidence: high

Scope-risk: narrow

Directive: Keep aria-expanded, aria-hidden, and inert synchronized when changing mobile navigation state.

Tested: Production build and application TypeScript; scoped ESLint; closed/open accessibility snapshots; hidden-link Tab-order check; 390px menu visual check; zero horizontal overflow.

Not-tested: Physical screen-reader announcement phrasing.
The profile now derives a monotonic dark-surface ramp from the existing graph palettes, restores the token-linear 3D height range, persists palette choice through shared settings, and aligns preview swatches with the square legend.

Constraint: Contribution cards remain fixed to the compact dark service surface.
Rejected: Reuse light-canvas grades directly | high-intensity grades lose contrast on the dark contribution surface
Rejected: Quantile or logarithmic intensity scaling | would diverge from main’s max-relative token semantics
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep #191f2b synchronized with --service-surface-muted when changing the profile surface theme.
Tested: Frontend test suite (511 passed); focused contribution tests after final assertions (13 passed); scoped ESLint and Prettier; Next.js production build; desktop, 390px, and 320px actual-data browser QA
Not-tested: Repository-wide ESLint remains blocked by existing errors in ViewSelector and Footer; Safari before 16.2 side-face color-mix fallback
The public cards now share a restrained surface, identity hierarchy, fitted typography, and the profile contribution palette while each template keeps one distinct data job. The 3D card uses the same token-derived calendar semantics and stable public dimensions.

Constraint: Preserve public template IDs, query parameters, XML escaping, and intrinsic card dimensions

Rejected: Template-specific decorative themes | gradients, fake chrome, and metaphor styling made the widgets feel unrelated to the profile service

Confidence: high

Scope-risk: moderate

Directive: Keep future templates within the shared shell and derive contribution color and height from scoped tokens

Tested: 563 frontend tests, changed-file ESLint, Quick Look renders for all templates, desktop/mobile browser captures, production build

Not-tested: Pixel output in every third-party README renderer
Contribution facts now use the exact trailing UTC year, inclusive profile thresholds, and token-derived intensity. Required contribution views return an uncached error card when their source is unavailable instead of publishing believable zero activity, while optional facts can still degrade safely.

Constraint: The database query keeps an alignment buffer so the renderer must exclude off-window rows from every visible fact

Rejected: Treat fetch failures as empty arrays | it converts an outage into false zero-usage data and allows stale caching

Confidence: high

Scope-risk: narrow

Directive: Preserve the distinction between a successful empty contribution result and an unavailable contribution source

Tested: Route failure/cache contracts, exact threshold boundaries, off-window spike regressions, full 563-test frontend suite, production build
The configurator now gives the live card the primary pane, keeps settings dense on desktop, uses one document scroll on mobile, and shows only controls that map to the selected renderer. Accent previews match rendered output and 2D layout state no longer leaks into 3D number formatting.

Constraint: Preserve keyboard focus trapping, existing URL generation, and coarse-pointer target sizes

Rejected: Separate template gallery and setup prose | duplicated the preview and pushed the actionable controls below the fold

Confidence: high

Scope-risk: narrow

Directive: Add a capability entry before exposing any new renderer option in the dialog

Tested: Desktop 1440x1100 and mobile 390x844 actual-data captures, keyboard accessibility snapshot, 563 frontend tests, changed-file ESLint, production build
Reviewing the public profile and embed flows exposed edge cases where empty contribution arrays collapsed requested graphs, hidden synthetic usage distorted visible model shares, and separate server/client clocks could disagree about the rolling-year range. Normalize those boundaries and add regression coverage so the rendered metrics remain truthful for malformed, empty, and time-sensitive inputs.

Constraint: Preserve canonical embed URLs and existing profile period semantics while making helper inputs safe for non-canonical usernames and non-finite values.

Rejected: Resolve the hydration mismatch in the browser with a client-only guard | that would hide the mismatch instead of making the server and client render the same data.

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep the server-provided chartRange authoritative for any future client-rendered rolling windows.

Tested: 568 frontend Vitest tests; TypeScript check; targeted ESLint; Prettier check; production build.

Not-tested: Live visual review against production data after this follow-up commit.

Related: #857
The compact contribution calendar uses very small cells at wide desktop widths, so even a modest border radius reads as a field of dots instead of the familiar square contribution grid. Keep the interactive 2D cells square while retaining the existing focus and selection rings.

Constraint: Preserve the existing grid geometry, colors, keyboard interactions, and isometric view.

Rejected: Increase cell size to hide the rounded corners | that would change the responsive density and still fail at narrower widths.

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep 2D contribution cells square unless the product intentionally changes the contribution-grid language.

Tested: Profile contribution calendar Vitest suite (14 tests); Prettier check.

Not-tested: Live Vercel visual capture.

Related: #857 #859 #860
Clamp the prior-year rolling range to the last valid day in its month so a Feb 29 request does not silently begin on Mar 1 and omit Feb 28 activity. Add a route regression test covering the leap-day boundary.

Constraint: Rolling profile ranges must remain calendar-date based and deterministic in UTC

Rejected: Rely on Date#setUTCFullYear alone | JavaScript normalizes invalid February 29 targets into March

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep leap-day behavior covered whenever rolling chart range logic changes

Tested: bunx vitest run __tests__/api/usersProfile.test.ts; bunx prettier; git diff --check

Not-tested: Full frontend suite and live preview after this follow-up

Related: #857 #859 #860
Public profiles now offer a rolling recent-year contribution graph alongside complete calendar-year views, with compact rounded cells, accessible range controls, inert future dates, and selected-day scrolling on narrow screens. The page now reuses cached server-side profile and device loaders so protected Vercel previews render their own deployment data without an anonymous self-fetch being redirected to the login page.

Constraint: Vercel Deployment Protection returns an HTML login page to anonymous server self-fetches, even when the final response status is 200
Rejected: Forward request cookies to the preview fetch | request-dependent caching remains fragile and cannot serve non-interactive render paths
Confidence: high
Scope-risk: moderate
Directive: Keep profile and device page loaders on the shared server path; do not restore server-side HTTP self-fetches without validating protected previews
Tested: bun run test (575 tests); targeted ESLint; next build; contribution range browser interaction checks; git diff --check
Not-tested: Authenticated Vercel preview browser smoke test; lifetime daily-detail payload growth under unusually long profile histories
Same-day submissions can mix legacy modelId records with nested model breakdowns for the same client. Materialize the legacy totals before merging the next record so nested client models retain every source attribution in contribution detail and usage views.

Constraint: Daily rows are ordered only by date, so legacy/current submission order is not stable
Rejected: Keep a single client modelId fallback | it cannot represent multiple models after same-day aggregation
Confidence: high
Scope-risk: narrow
Directive: Materialize legacy client totals before adding incoming totals whenever nested model attribution is introduced
Tested: usersProfile API regression test; targeted ESLint; git diff --check
Not-tested: Live mixed-version production submission corpus
Future dates remain visible in a current-year graph but are intentionally disabled. Their 3D cubes now retain a noninteractive hit marker, preventing the SVG's forgiving nearest-cell gesture from selecting an adjacent past date.

Constraint: Current-year calendars visibly include future dates while input must stop at the authoritative today cutoff
Rejected: Remove the SVG nearest-cell fallback | it would regress forgiving touch selection in the 3D graph
Confidence: high
Scope-risk: narrow
Directive: Any visually rendered but inert graph cell must intercept its own hit target before a nearest-cell fallback runs
Tested: profile contribution graph data tests; targeted ESLint; git diff --check
Not-tested: Authenticated browser click on a protected Vercel preview
@junhoyeo
junhoyeo force-pushed the feat/compact-user-profiles branch from 2c491b4 to 8cc1de7 Compare July 12, 2026 13:37
@junhoyeo
junhoyeo merged commit b1e5b57 into main Jul 12, 2026
6 checks passed
@junhoyeo
junhoyeo deleted the feat/compact-user-profiles branch July 13, 2026 02:16
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.

1 participant