feat(website): build prompt library discovery hub - #1130
Open
ppapsmoken wants to merge 67 commits into
Open
ppapsmoken wants to merge 67 commits into
ppapsmoken wants to merge 67 commits into
Conversation
Constraint: staging branch is divergent and must trigger the staging workflow Rejected: force-update/cherry-pick | Both would bypass or distort the staged merge boundary Confidence: high Scope-risk: moderate Directive: Do not merge staging-only commits back into main Tested: Merge conflict check and static Git status Not-tested: Runtime staging validation pending # Conflicts: # website/src/app/sitemap.ts
…0907 # Conflicts: # website/src/components/site-header.tsx
…tions # Conflicts: # website/src/app/sitemap.ts
New '用量报表' admin view, separate from the existing ops daily report: - route /usage-report (admin-guarded) + sidebar item + i18n labels - funnel first screen: daily KPI cards, daily detail table with totals, dual-axis bars (registered/activated key/first paid) + paid-amount line, 7d-rolling conversion trend, per-model stacked tokens area - CSV export for the daily funnel and the date x model usage slices - feeds from GET /api/data/usage_report (backend commit 2bad669)
Why the old number could reach 400%: '近7日滚动 Σ激活/Σ注册' divides two independent rolling windows while first-key events lag registrations; after the campaign, daily registrations collapsed while backlog users kept creating first keys, so Σactivated(7d) > Σregistered(7d). Fix (cohort, people-counted): - usage_report_daily gains activated_c7 (注册队列 7 日内建 Key 人数) and paid_c14 (建 Key 队列 14 日内首付人数); both are subsets of their denominators (registered / activated_key), so cohort rates never exceed 100%. Activation stays deduped per user (1 人多 Key = 1 人). - One-time recompute of stored rows via SchemaV bump. - Frontend drops the rolling formula; charts reg->key(7d cohort) and key->pay(14d cohort), hiding the most recent 7/14 days (cohort pending) and noting units are people.
Single long scrolling page with anchor sub-nav, funnel first: - ① funnel: people KPI row, daily detail table, dual-axis bars (registered/activated key/first paid) + paid-amount line, cohort conversion trend, range funnel summary (auxiliary) - ② usage overview: calls/tokens + funnel KPIs, daily calls&tokens combo, today model share donut, range top models - ③ model usage: stacked area with calls/tokens switch, range model summary table, top models daily trend, CSV export buttons
The funnel table previously showed activation/first-paid by event day, so backlogged first-key creations (users registered earlier, verified later) made Activated(Key) > Registered for a row. All funnel people columns now use the SAME day's registration cohort (人) and are nested subsets: - Registered = users registered that day (enabled+verified) - Activated (7d cohort) = activated_c7 (⊆ Registered) - First Paid (14d cohort)= paid_reg_c14 (⊆ Registered, new field) Money/calls/tokens stay calendar-day figures. Pending recent cohorts show ⏳. SchemaV bumped to 2 so stored rows are recomputed once.
漏斗以当天为准(快进快出 C 端): - usage_report_daily 新增 activated_day / paid_day:该日注册的人中 当天首次建 Key / 当天首次付费的人数(⊆ Registered,人) - 主表/明细表/KPI/双轴柱图/当天转化率柱图/区间汇总全部切到当天口径 - 转化率= 当天激活÷注册、当天首付÷注册,恒 ≤100%;今日为进行中数据 - SchemaV=3 自动重算存量行;7/14 日窗口字段保留仅作辅助 - docs 口径同步当天为准
Registered is counted through GORM (auto deleted_at IS NULL scope), but the native-SQL activation/payment subqueries missed the soft-delete filter, so soft-deleted (banned farm) accounts still counted as activated/paid and could make Activated > Registered for a day. Add 'u.deleted_at IS NULL' to every user subquery (same-day activated/paid, cohort c7/reg-pay). SchemaV=4 forces recompute of stored rows.
Backend: - CSV written with c.String() treated content as a format string; use c.Data(..., buf.Bytes()) (content with '%' would corrupt the file). - controller fetched both daily and model rows before branching to CSV; CSV now fetches only the requested dimension. - EnsureUsageReportRange now computes the trailing window in UTC (non-UTC server clocks no longer shift the day range). - Per-date locks instead of one global mutex across all report reads. - Backfill NULL legacy rows (AutoMigrate adds nullable columns without defaults -> Go int scan would fail) before each row read; numeric columns now carry not null;default:0. - First-paid semantics fixed everywhere: compare MIN(first successful top-up per user) to first-key/registration instead of EXISTS any top-up, so repeat payments can no longer inflate first-pay cohorts. Frontend: - registered==0 conversion days return null (no fake 0% bars). - Model names no longer used directly as Recharts dataKeys; mapped to safe keys (s0.. / t0..), display names kept separate. - Model stacking pre-aggregated in one pass per date.
…per read Follow-ups to review: - Remove event/long-window aggregates (activated_key, first_paid, c7/c14, reg-pay) from the daily compute: the UI only shows same-day metrics, and those MIN(...) GROUP BY queries forced full-history scans of tokens/top_ups on every date recompute. - Same-day paid uses EXISTS(settled same day) + NOT EXISTS(paid before registration) so it stays first-payment semantics without grouping the whole top_ups table per date. - NULL backfill runs once per process (only touches rows containing NULL) instead of an UPDATE on every Ensure() call.
Production first open of /api/data/usage_report ran a synchronous 30-day backfill and could take a long time on large log tables. - GET JSON: kicks off the trailing-window fill in the background (single in-process runner), serves already-persisted rows immediately and returns filling=true until the window is complete. - Front-end polls every 4s (max ~2min) and shows a '回填中' banner; rows appear progressively as each day lands. - CSV export stays synchronous (rare, admin-only, needs the full window). - Schema version untouched: new prod tables fill lazily on first open.
- Remove the leftover synchronous EnsureUsageReportRange on the JSON path; only CSV fills synchronously (the interactive view was still blocked). - filling flag now reflects the real background-runner state (service.UsageReportFillRunning) instead of inferring from row count, so pages can't get stuck 'filling' forever on partial/failed backfills. - Front-end polling has no hard 2-minute cap: it keeps refetching every 4s until the server reports filling=false. - NULL column backfill no longer caches the first failure via sync.Once (retries until success), and runs at the start of the single-date ensure path too so single-date reads self-heal.
…state Cover the race where the background fill finishes between the row query and the response: filling is now (rows < days) || runner-running, and the front-end keeps polling while either holds, so it cannot stop early on a half-filled window.
Constraint: Retired plans must remain unavailable for quotes and purchases. Rejected: Re-add retired plans to the public catalog | would reopen legacy products for sale. Confidence: high Scope-risk: narrow Directive: Current-plan display must fall back only to the matching entitlement snapshot. Tested: 125 focused tests, frontend production build, local preview HTTP 200. Not-tested: Full main typecheck is blocked by pre-existing ops-report type errors.
Constraint: Retired plans must be unavailable to new buyers without changing existing wallet-renewal prices or benefits. Rejected: Reading mutable retired plan fields | could silently alter legacy billing and limits. Confidence: high Scope-risk: moderate Directive: Keep disabled-plan renewal gated by the current entitlement and its exact successful source-order snapshot. Tested: Focused wallet-renewal regression suite and go vet ./service. Not-tested: Full repository suite; an unrelated cache invalidation test is already failing on main.
Constraint: Wallet renewal must reproduce the successful source order even when a snapshot contains sub-minor-unit precision. Rejected: Charging the raw snapshot price | minor-unit comparison alone can hide a larger wallet quota debit. Confidence: high Scope-risk: narrow Directive: Treat the successful order UnitPrice as billing authority after validating its snapshot and currency. Tested: Focused retired-plan wallet renewal regression suite. Not-tested: Full repository suite.
|
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
The website prompt routes needed a usable discovery hub with localized metadata, model/topic collections, real artifact previews, and direct Playground handoff.
Evidence / reproduction
Prompt routes previously exposed sparse listings and did not provide a clear way to evaluate examples before generation. The updated directory now renders image/video collections, search/filter states, localized display copy, and selected artifact previews.
Scope / design
Impact and risks
Website-only Next.js changes. No Go router, relay, billing, auth, database, or infrastructure runtime paths are changed. The branch includes the complete prompt-library feature series so the routes and shared data stay consistent.
Validation / acceptance criteria
git diff --checkpasses.bunx next build --webpackpasses (Next.js 16.2.9; 1,064 static pages generated).smbreakpoint.