slice 3 COMPLETE: onboarding wizard (complexity/risk/drawdown + starter watchlist + demand subscribe)

starter.ts by ornith (9 symbols w/ ticker-kind + ADR-0007 reasons, defaults, 12 tests).
onboarding.complete + onboarding.starter + me().onboarded by orchestrator; schema
+drawdown_tolerance. Wizard UI (complexity picker, starter list, disclaimer, finish).
onboarding subscribes starter symbols to the demand set (adapter fetches them). 87/87
backend + 2/2 lint green. Slice 3 done; slices 1-3 complete.
This commit is contained in:
Investor Flow Build
2026-06-29 21:31:59 -04:00
parent 4816b19976
commit 965f8d3b1c
8 changed files with 352 additions and 28 deletions
@@ -172,3 +172,21 @@ test('oauth: oauthStart returns a redirect URL + CSRF state cookie; oauthCallbac
delete process.env.GITHUB_CLIENT_ID; delete process.env.GITHUB_CLIENT_SECRET;
}
});
// --- Slice 3: onboarding ---
test('onboarding.complete writes complexity/risk/drawdown + starter watchlist + subscribes demand', async () => {
const { db, cache, freshCtx } = setup();
const signupCtx = freshCtx();
const { userId } = await appRouter.createCaller(signupCtx).auth.signup({ email: 'a@b.co', password: 'password123' });
const oCtx = { db, cache, resHeaders: new Headers(), userId, cookies: {} as Record<string, string> };
const res = await appRouter.createCaller(oCtx).onboarding.complete({ complexity: 'beginner' });
assert.ok(res.watchlistId);
const u = db.prepare('SELECT complexity, risk_tolerance, drawdown_tolerance FROM users WHERE id=?').get(userId) as { complexity: string; risk_tolerance: string; drawdown_tolerance: number };
assert.equal(u.complexity, 'beginner');
assert.equal(u.risk_tolerance, 'moderate');
assert.equal(u.drawdown_tolerance, -20);
const wl = db.prepare('SELECT symbols FROM watchlists WHERE owner_id=?').get(userId) as { symbols: string };
assert.equal(JSON.parse(wl.symbols).length, 9);
const demand = await cache.demandSet();
assert.ok(demand.includes('NVDA') && demand.includes('BTC'), 'starter symbols subscribed to demand set');
});