Files
tapir/internal/adapters/store/report_test.go
T
mathiasandClaude Opus 4.8 36dd182fb5
CI / Build & Import (push) Successful in 11s
CI / Lint / Test / Vet (push) Successful in 10s
feat(report): Stage-0 usage gate counts from a baseline date (default 2026-06-11)
The return-usage gate (ADR-016) counted distinct active weeks over ALL history,
so pre-launch noise — testing churn and the period the pilot sat blocked on zero
summaries — would inflate the signal. Add a baseline: ActiveWeeks(ctx, since)
filters login_events + summary_actions to seen_at/acted_at >= since. The report
command sets it to TAPIR_USAGE_GATE_START (YYYY-MM-DD, default 2026-06-11 — the
morning the pilot was unblocked) and prints the baseline. The gate now measures
whether users RETURN once it genuinely works.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 22:52:15 +02:00

106 lines
3.8 KiB
Go

package store_test
import (
"context"
"testing"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/stretchr/testify/require"
)
// seedReportUser inserts a user + its identity mapping (the enumeration source
// ActiveWeeks reads). display_name is optional.
func seedReportUser(t *testing.T, p *pgxpool.Pool, userID, subject, name string) {
t.Helper()
ctx := context.Background()
_, err := p.Exec(ctx,
`INSERT INTO users (id, display_name) VALUES ($1, NULLIF($2, ''))`, userID, name)
require.NoError(t, err)
_, err = p.Exec(ctx,
`INSERT INTO user_identities (dex_subject, user_id) VALUES ($1, $2)`, subject, userID)
require.NoError(t, err)
}
// TestActiveWeeksCountsDistinctWeeksAcrossReadsAndActs is the gate-query proof.
// It seeds, with fixed timestamps in known ISO weeks:
// - user A: reads in week of Jan 5 and Jan 12, acts in week of Jan 12 (dup) and
// Jan 19 → the UNION across both tables collapses the shared week → 3 distinct.
// - user B: a single read in the week of Jan 5 → 1 distinct (below the gate).
//
// It verifies the count is correct, dedups the cross-table shared week, and orders
// most-active first.
func TestActiveWeeksCountsDistinctWeeksAcrossReadsAndActs(t *testing.T) {
ctx := context.Background()
s := newStore(t)
p := rawPool(t)
resetDB(t, p) // TRUNCATE ... users CASCADE also clears user_identities
seedReportUser(t, p, userA, "subject-a", "Ada")
seedReportUser(t, p, userB, "subject-b", "")
// Reads (login_events) — fixed dates in distinct ISO weeks.
_, err := p.Exec(ctx,
`INSERT INTO login_events (user_id, seen_at) VALUES
($1, '2026-01-05T09:00:00Z'),
($1, '2026-01-12T09:00:00Z'),
($2, '2026-01-05T09:00:00Z')`, userA, userB)
require.NoError(t, err)
// Acts (summary_actions) — one in A's week-of-Jan-12 (shared with a read, must
// dedup) and one in a new week (Jan 19).
_, err = p.Exec(ctx,
`INSERT INTO summary_actions (user_id, video_id, action, acted_at) VALUES
($1, 'vid-1', 'watched', '2026-01-12T18:00:00Z'),
($1, 'vid-2', 'saved', '2026-01-19T18:00:00Z')`, userA)
require.NoError(t, err)
got, err := s.ActiveWeeks(ctx, time.Time{}) // zero since = no lower bound
require.NoError(t, err)
require.Len(t, got, 2, "both identity users must appear")
require.Equal(t, userA, got[0].UserID, "most-active user first")
require.Equal(t, "Ada", got[0].DisplayName)
require.Equal(t, 3, got[0].ActiveWeeks, "3 distinct weeks across reads+acts, shared week deduped")
require.Equal(t, userB, got[1].UserID)
require.Equal(t, 1, got[1].ActiveWeeks, "single read = 1 distinct week (below gate)")
}
// TestActiveWeeksEmptyWhenNoUsers: no identities → no rows (not an error).
func TestActiveWeeksEmptyWhenNoUsers(t *testing.T) {
ctx := context.Background()
s := newStore(t)
resetDB(t, rawPool(t))
got, err := s.ActiveWeeks(ctx, time.Time{})
require.NoError(t, err)
require.Empty(t, got)
}
// TestActiveWeeksExcludesBeforeGateStart proves the baseline cutoff: activity
// before `since` does not count, so pre-launch noise (testing, the pilot's blocked
// period) is excluded from the Stage-0 return-usage gate (ADR-016).
func TestActiveWeeksExcludesBeforeGateStart(t *testing.T) {
ctx := context.Background()
s := newStore(t)
p := rawPool(t)
resetDB(t, p)
seedReportUser(t, p, userA, "subject-a", "Ada")
// One read well before the baseline, two reads in distinct weeks after it.
_, err := p.Exec(ctx,
`INSERT INTO login_events (user_id, seen_at) VALUES
($1, '2026-05-01T09:00:00Z'),
($1, '2026-06-12T09:00:00Z'),
($1, '2026-06-19T09:00:00Z')`, userA)
require.NoError(t, err)
since := time.Date(2026, 6, 11, 0, 0, 0, 0, time.UTC)
got, err := s.ActiveWeeks(ctx, since)
require.NoError(t, err)
require.Len(t, got, 1)
require.Equal(t, 2, got[0].ActiveWeeks, "only the two post-baseline weeks count; the May read is excluded")
}