Revert "Demo page: the running product beside the case for it"

This reverts commit 7567aa4e75.
This commit is contained in:
serfa
2026-08-21 07:32:41 -04:00
parent 7567aa4e75
commit 5086a238ea
6 changed files with 59 additions and 438 deletions
+13 -58
View File
@@ -1,74 +1,31 @@
import { inArray } from 'drizzle-orm';
import { eq } from 'drizzle-orm';
import { db, schema } from '@linkder/db';
/**
* Fixed sign-in for local development and for demonstrating the product.
* A fixed test account for local development.
*
* Signing in normally needs a real handset to receive a real SMS, which makes
* the whole app untestable without a phone in your hand and Twilio credits — and
* makes it impossible to show somebody both sides of a two-sided marketplace in
* a meeting. These accounts pin known numbers to one known code.
* the whole app untestable without a phone in your hand and Twilio credits. This
* pins one number to one known code so `pnpm dev` is usable.
*
* THREE independent guards, unchanged by adding more accounts, because a login
* bypass reaching production is the worst bug this codebase could ship:
* THREE independent guards, because a login bypass reaching production is the
* worst bug this codebase could ship:
*
* 1. NODE_ENV must not be 'production'.
* 2. ALLOW_DEV_LOGIN must be explicitly 'true' — being in dev is not enough.
* 3. The phone number must be one of the accounts listed below.
* 3. The phone number must match exactly.
*
* Any one of them failing falls straight back to the real OTP path. That is why
* `/demo` says out loud that it only works off production: the honest fix for
* demoing against a live deployment is a real account and a real SMS, not a
* fourth flag that unlocks a bypass in production.
* Any one of them failing falls straight back to the real OTP path.
*/
const DEV_PHONE = '+34600000000';
const DEV_CODE = '000000';
export interface DemoAccount {
phone: string;
code: string;
/** Which side of the marketplace this account shows. */
role: 'client' | 'pro';
name: string;
/** What the person presenting should point at once they are in. */
blurb: string;
}
/**
* Both sides of the market.
*
* A one-sided demo of a two-sided marketplace shows half a product: the
* customer's deck is only interesting because a real tradesperson is on the
* other end of it. These map to seeded accounts (`pnpm db:seed`) that already
* own jobs, conversations and a completed booking, so the screens have something
* in them rather than five empty states.
*/
export const DEMO_ACCOUNTS: readonly DemoAccount[] = [
{
phone: '+34600000000',
code: DEV_CODE,
role: 'client',
name: 'Sofia Grau',
blurb:
'The customer. Has jobs in flight, a live conversation with a plumber, and one finished job waiting on a review.',
},
{
phone: '+34610000001',
code: DEV_CODE,
role: 'pro',
name: 'Marc Oliveras',
blurb:
'The tradesperson. Verified plumber — shows the card customers swipe, the verification state and the job side of chat.',
},
];
const DEMO_PHONES = DEMO_ACCOUNTS.map((a) => a.phone);
export function isDevLoginEnabled(): boolean {
return process.env.NODE_ENV !== 'production' && process.env.ALLOW_DEV_LOGIN === 'true';
}
export function isDevLoginPhone(phone: string): boolean {
return isDevLoginEnabled() && DEMO_PHONES.includes(phone);
return isDevLoginEnabled() && phone === DEV_PHONE;
}
/**
@@ -86,11 +43,9 @@ export async function pinDevLoginCode(phone: string): Promise<void> {
await db
.update(schema.verifications)
.set({ value: `${DEV_CODE}:0` })
.where(inArray(schema.verifications.identifier, [phone]))
.catch(() => {});
.where(eq(schema.verifications.identifier, phone));
console.info(`\n [dev login] ${phone} → code ${DEV_CODE}\n`);
console.info(`\n [dev login] ${DEV_PHONE} → code ${DEV_CODE}\n`);
}
/** Kept for callers that only ever wanted the customer account. */
export const DEV_LOGIN = { phone: DEMO_ACCOUNTS[0]!.phone, code: DEV_CODE } as const;
export const DEV_LOGIN = { phone: DEV_PHONE, code: DEV_CODE } as const;