test(apps): customer-flow smoke test for both apps + 4-digit master-code guard
smoke-apps.cjs walks login (master OTP), catalogue, cart cap, order placement and order history, with the empty-order and unauthenticated negatives: 43/43. The cart rules are executed from BOTH apps' own source so the result cannot be carried by v1 alone. No behavioural divergence found: all 9 stores are byte-identical, and the router, API client and composables match except v1's protected variant-image picker. APP-01: both apps' OTP box is exactly 4 inputs and only submits at 4, so a longer OTP_MASTER_CODE cannot be typed into them. The login UI was left alone; main.ts now warns at boot when the code is not 4 digits and .env.example states the rule. APP-02 logged, not fixed: user-app-v2 has no getHomeSlider, so admin-configured home slides show in v1 only. Changing v2's hero during a delivery is not worth the risk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0983c42788
commit
8b7da90f51
+15
-1
@@ -8,7 +8,7 @@ import { AppModule } from './app.module';
|
||||
import { prepareDatabase } from './prisma/bootstrap';
|
||||
import { PrismaExceptionFilter } from './prisma/prisma-exception.filter';
|
||||
import { assertSmsConfigured } from './modules/sms/sms.service';
|
||||
import { masterOtpEnabled } from './modules/customer-auth/customer-auth.service';
|
||||
import { masterOtpCode, masterOtpEnabled } from './modules/customer-auth/customer-auth.service';
|
||||
|
||||
// serve-static's bundled `mime` version predates .avif, so it falls back to
|
||||
// application/octet-stream — browsers still render the image (they sniff
|
||||
@@ -25,6 +25,14 @@ async function bootstrap() {
|
||||
// D20 — a loud, unmissable banner whenever the delivery bypass is armed, so
|
||||
// it cannot reach the real release unnoticed.
|
||||
if (masterOtpEnabled()) {
|
||||
const code = masterOtpCode() ?? '';
|
||||
// Both apps render the login OTP as FOUR single-character boxes and only
|
||||
// submit on @on-complete, i.e. at exactly 4 digits
|
||||
// (LoginView.vue:43 in each app, OtpInput.vue:43). The API itself accepts
|
||||
// any length, so a longer master code works over HTTP but can never be
|
||||
// typed into the apps. Warn rather than reject: an operator may be using it
|
||||
// for API testing only.
|
||||
const typable = /^\d{4}$/.test(code);
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'\n' +
|
||||
@@ -32,6 +40,12 @@ async function bootstrap() {
|
||||
'\n ⚠ OTP_MASTER_CODE فعال است — قبل از انتشار اصلی حذف شود\n' +
|
||||
' ⚠ OTP_MASTER_CODE IS ACTIVE: any active customer can sign in with\n' +
|
||||
' ⚠ this fixed code. Remove it from the environment before release.\n' +
|
||||
(typable
|
||||
? ''
|
||||
: ' ⚠\n' +
|
||||
' ⚠ NOTE: this code is not 4 digits, so it CANNOT be entered in the\n' +
|
||||
' ⚠ customer apps — their OTP box has exactly 4 boxes. Use a\n' +
|
||||
' ⚠ 4-digit code for the apps; this one works over the API only.\n') +
|
||||
'='.repeat(72) +
|
||||
'\n',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user