Merge S10 (a1): public ledger profiles v1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> # Conflicts: # BUILD-STATE.md # CLAUDE.md
This commit is contained in:
@@ -386,6 +386,11 @@ async function countRowsForDate(gameDate, opts = {}) {
|
||||
* 30-day aggregate over the PUBLIC model record (user_id NULL): hit rate,
|
||||
* beat-the-close rate, pending count. Percentages are null below
|
||||
* MIN_AGG_SAMPLE — the UI must show "record building" instead.
|
||||
*
|
||||
* A1 Session 10 — `opts.userId` swaps the public `.is('user_id', null)`
|
||||
* scoping for `.eq('user_id', uid)`: the SAME aggregate (same window, same
|
||||
* n≥20 gate) over one user's own ledger, powering public profiles. The
|
||||
* public default is untouched.
|
||||
*/
|
||||
async function getModelAggregate(opts = {}) {
|
||||
const empty = {
|
||||
@@ -400,8 +405,9 @@ async function getModelAggregate(opts = {}) {
|
||||
const since = new Date(nowMs - AGG_WINDOW_DAYS * 24 * 3600 * 1000).toISOString().slice(0, 10);
|
||||
|
||||
let settledQ = sb.from('ledger_entries')
|
||||
.select('outcome, clv_result, player_key, grade')
|
||||
.is('user_id', null)
|
||||
.select('outcome, clv_result, player_key, grade');
|
||||
settledQ = opts.userId ? settledQ.eq('user_id', opts.userId) : settledQ.is('user_id', null);
|
||||
settledQ = settledQ
|
||||
.not('outcome', 'is', null)
|
||||
.gte('game_date', since)
|
||||
.limit(AGG_FETCH_LIMIT);
|
||||
@@ -412,9 +418,9 @@ async function getModelAggregate(opts = {}) {
|
||||
if (error) return { ...empty, error: error.message };
|
||||
|
||||
let pendingQ = sb.from('ledger_entries')
|
||||
.select('id', { count: 'exact', head: true })
|
||||
.is('user_id', null)
|
||||
.is('outcome', null);
|
||||
.select('id', { count: 'exact', head: true });
|
||||
pendingQ = opts.userId ? pendingQ.eq('user_id', opts.userId) : pendingQ.is('user_id', null);
|
||||
pendingQ = pendingQ.is('outcome', null);
|
||||
if (opts.sport) pendingQ = pendingQ.eq('sport', String(opts.sport).toLowerCase());
|
||||
if (opts.playerKey) pendingQ = pendingQ.eq('player_key', opts.playerKey);
|
||||
if (opts.team) pendingQ = pendingQ.eq('team', opts.team);
|
||||
|
||||
Reference in New Issue
Block a user