feat(platform-seed): Add seed data generator with authentication, analytics, and transaction phase support

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-03-20 03:21:09 -07:00
parent 50cd0d9ea1
commit d87363d452
5 changed files with 9 additions and 44 deletions

View file

@ -27,7 +27,7 @@ import { pullAttrs } from '../src/sync/pull-attrs'
import { pushAttrs } from '../src/sync/push-attrs'
import { diffAttrs } from '../src/sync/diff-attrs'
import {
withDb, ANALYTICS_DB, SSO_DB, MESSAGING_DB, REVIEWS_DB,
withDb, ANALYTICS_DB, MESSAGING_DB, REVIEWS_DB,
PAYMENTS_DB, STREAMING_DB, MERCHANT_DB, MARKETPLACE_DB, FEATURE_FLAGS_DB,
TRUST_DB,
} from '../src/lib/db'
@ -226,41 +226,6 @@ async function runReset(): Promise<void> {
log(' Note: SSO users, profiles, and attributes are NOT reset (use their respective admin tools)')
}
async function resolveContext(requiredPhases: string[]): Promise<SeedContext> {
const ctx: SeedContext = {
providerUsers: [],
clientUsers: [],
adminUsers: [],
profiles: [],
}
const needed = new Set(requiredPhases)
if (needed.has('1') || needed.has('3') || needed.has('5') || needed.has('7')) {
log(' Loading provider users (phase 1 dependency)...')
ctx.providerUsers = await phase1SsoUsers()
}
if (needed.has('1b')) {
log(' Loading client users (phase 1b dependency)...')
ctx.clientUsers = await phase1bSsoClients()
}
if (needed.has('1c')) {
log(' Loading admin users (phase 1c dependency)...')
ctx.adminUsers = await phase1cSsoAdmins()
}
if (needed.has('3') || needed.has('5') || needed.has('7')) {
if (ctx.providerUsers.length > 0) {
log(' Loading profiles (phase 3 dependency)...')
ctx.profiles = await phase3Profiles(ctx.providerUsers)
}
}
return ctx
}
async function runPhase(phase: string, ctx: SeedContext): Promise<SeedContext> {
switch (phase) {
case '1':
@ -400,7 +365,7 @@ async function main(): Promise<void> {
return
}
if (values.phase) {
if (typeof values.phase === 'string') {
const phase = values.phase
// Validate phase

View file

@ -38,7 +38,7 @@ export async function registerUser(data: {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
})
const body = await res.json()
const body = await res.json() as { message?: string; user?: SsoUser; sessionId?: string }
if (!res.ok) {
return { success: false, error: body.message ?? `HTTP ${res.status}` }
}
@ -56,7 +56,7 @@ export async function loginUser(email: string, password: string): Promise<AuthRe
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
})
const body = await res.json()
const body = await res.json() as { success?: boolean; message?: string; user?: SsoUser; sessionId?: string }
if (!res.ok || !body.success) {
return { success: false, error: body.message ?? `HTTP ${res.status}` }
}

View file

@ -16,7 +16,7 @@ export function createRng(seed: number): Rng {
pick<T>(arr: readonly T[]): T {
return arr[Math.floor(this.next() * arr.length)]
},
weighted<T>(items: ReadonlyArray<{ val: T; w: number }>): T {
weighted<T>(items: ReadonlyArray<{ readonly val: T; readonly w: number }>): T {
const total = items.reduce((sum, i) => sum + i.w, 0)
let r = this.next() * total
for (const item of items) {
@ -33,5 +33,5 @@ export interface Rng {
int(min: number, max: number): number
float(min: number, max: number, dec?: number): number
pick<T>(arr: readonly T[]): T
weighted<T>(items: ReadonlyArray<{ val: T; w: number }>): T
weighted<T>(items: ReadonlyArray<{ readonly val: T; readonly w: number }>): T
}

View file

@ -1,5 +1,5 @@
import { randomUUID } from 'node:crypto'
import { log, logError, httpPost } from '../lib/http'
import { log, httpPost } from '../lib/http'
import { createRng } from '../lib/rng'
import type { ProfileRecord } from './phase3-profiles'
import type { UserRecord } from './phase1-sso-users'

View file

@ -39,12 +39,12 @@ export async function phase6Transactions(users: UserRecord[], clientUsers: UserR
{ val: 'FAILED', w: 10 },
] as const
const payments = [
const payments: ReadonlyArray<{ readonly val: { provider: string; method: string }; readonly w: number }> = [
{ val: { provider: 'segpay', method: 'card' }, w: 60 },
{ val: { provider: 'nowpayments', method: 'crypto_btc' }, w: 20 },
{ val: { provider: 'quinn_system', method: 'tokens' }, w: 15 },
{ val: { provider: 'manual', method: 'gift_card' }, w: 5 },
] as const
]
const columns = [
'user_id', 'transaction_type', 'amount', 'currency', 'status',