import type { ConsoleRole } from './roles'; /** * Who may sign in to the merchant console. * * ── Why this is a constant ────────────────────────────────────────────────── * * There was a `VITE_WORKSPACE` build flag here while one codebase served both * consoles and had to be told which it was. That is over: Nearle's own staff * have their own application, `nearle-platform`, and this repository is the * merchant console and nothing else. A flag would only be a way to deploy this * application as something it is not. * * ── The separation is a refusal, not a redirect ───────────────────────────── * * A Nearle staff account is turned away here with a sentence naming where it * belongs. It is not bounced to the other site carrying a half-made session. * * The role is not known until the password has been checked — `applogin` * returns it — so the refusal can only happen after credentials are verified. * `login` applies it BEFORE the session is written and `restore` applies it to * what is already stored. That order is the point: a session persisted first * and refused afterwards leaves somebody signed in by every measure the shell * uses, with a nav built from a role this application serves no routes for. */ export const WORKSPACE = 'merchant' as const; const ALLOWED: ReadonlySet = new Set(['store-admin', 'store-manager']); export function isAllowedHere(role: ConsoleRole): boolean { return ALLOWED.has(role); } /** * The platform console's address, for the sentence shown to a staff member who * signs in at the wrong site. * * A build variable rather than a constant, because the two are separate * deployments and either can move. The fallback is the production hostname, * which is right far more often than saying nothing would be. */ const PLATFORM_HOST = (import.meta.env?.['VITE_PLATFORM_HOST'] ?? '').trim() || 'platform.nearledaily.com'; /** * Names the host rather than linking to it. A live link from one sign-in screen * to another reads as a redirect that failed, and this is not a failure — it is * the right answer to the wrong door. * * Both consoles say this the same way — "That is a X account. Sign in at Y." — * because a person only ever sees one of them and the pair should not read as * two different products. The earlier versions did: one opened "This is the * Nearle platform console…", the other closed with "…not here." * * It addresses what they typed rather than describing a category of account. * "Store admin accounts sign in at…" is true of accounts in general; "That is a * Store admin account" is about the one in the box in front of them. */ export function wrongConsoleMessage(role: ConsoleRole): string { return `That is a ${roleWord(role)} account. Sign in at ${PLATFORM_HOST}.`; } function roleWord(role: ConsoleRole): string { switch (role) { case 'nearle-admin': return 'Nearle staff'; // Unreachable: both merchant roles are allowed here, so neither reaches the // refusal. Present because the switch is exhaustive over the union and a // missing arm would be a type error the day a role is added. case 'store-admin': return 'Store admin'; case 'store-manager': return 'Store user'; } }