Приложение обкатывается на боевом контуре, поэтому интерфейс надо проверять на живых данных — а живые данные лежат у настоящих водителей. * «Вход для сотрудника» (/dev) — логин учётки CRM, поддержан второй шаг 2FA; дальше поиск водителя по ФИО/телефону/id и просмотр его экранов. * Плашка «Смотрю как …» над всеми экранами: интерфейс в этом режиме неотличим от водительского, и чужой баланс легко принять за свой. * Вкладка «Отладка» (/debug, водителю недоступна): смена водителя, driver_id, режим, срок токена, адрес API, коммит и время сборки, журнал последних 40 ответивших запросов, сброс кэша сервис-воркера. * Пополнение под просмотром идёт в учебный контур: экран /mock-pay/:orderId выбирает, что «ответит» банк, а настоящий экран оплаты разбирает эти статусы своим боевым кодом. Ни рубля, ни чека 54-ФЗ. Заодно доезжает незакоммиченная работа прошлой сессии: дев-прокси в vite.config.ts, его тест и разобранный .env.example. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
3.9 KiB
TypeScript
74 lines
3.9 KiB
TypeScript
import { execSync } from "child_process";
|
||
import { defineConfig, loadEnv } from "vite";
|
||
import react from "@vitejs/plugin-react";
|
||
import { VitePWA } from "vite-plugin-pwa";
|
||
import path from "path";
|
||
|
||
/**
|
||
* Что именно сейчас открыто — видно на вкладке «Отладка».
|
||
*
|
||
* Без этого «правка не приехала» и «приехала, но кэш старый» выглядят
|
||
* одинаково, а проверяются по-разному. Коммит берём из git; вне репозитория
|
||
* (сборка из архива, CI без .git) — честный «unknown», а не падение сборки.
|
||
*/
|
||
function buildCommit(): string {
|
||
try {
|
||
return execSync("git rev-parse --short HEAD", { stdio: ["ignore", "pipe", "ignore"] })
|
||
.toString().trim() || "unknown";
|
||
} catch {
|
||
return "unknown";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Локальная разработка ходит в бэкенд ЧЕРЕЗ ПРОКСИ dev-сервера, а не напрямую.
|
||
*
|
||
* Почему не «разрешить localhost в CORS бэкенда»: через прокси запрос уходит с
|
||
* того же origin, что и страница (http://localhost:5174/api/...), поэтому CORS
|
||
* в разработке не участвует вообще — ни preflight, ни credentials. Боевой
|
||
* список origin'ов на бэкенде остаётся закрытым, и CORS_ALLOW_LOCALHOST ради
|
||
* этого фронта включать не нужно.
|
||
*
|
||
* Дефолтная цель прокси — ЛОКАЛЬНЫЙ бэкенд, а не crm.pptaxi.ru. Контур боевой:
|
||
* «по умолчанию проксировать в прод» означало бы, что первый же тычок в
|
||
* «Пополнить» на машине разработчика создаёт платёж на живом терминале и живой
|
||
* чек 54-ФЗ. Другой адрес задаётся VITE_API_TARGET — тем же именем, что в CRM
|
||
* (crm2/frontend/vite.config.ts), чтобы рецепт был один на оба фронта.
|
||
*/
|
||
export default defineConfig(({ command, mode }) => {
|
||
// База для ky (src/api/client.ts): в dev — свой же origin, дальше прокси.
|
||
// Ставим ТОЛЬКО если разработчик не задал базу сам (.env.local, .env,
|
||
// VITE_API_BASE=... перед командой): loadEnv отдаёт и файлы, и process.env,
|
||
// причём process.env приоритетнее файлов — без этой проверки собственная
|
||
// настройка молча перебивалась бы нашим дефолтом.
|
||
// В сборку (command === "build") не лезем никогда: там база остаётся боевой —
|
||
// из .env, либо из дефолта в client.ts.
|
||
if (command === "serve" && !loadEnv(mode, __dirname, "VITE_").VITE_API_BASE) {
|
||
process.env.VITE_API_BASE = "/api";
|
||
}
|
||
|
||
return {
|
||
define: {
|
||
__BUILD_COMMIT__: JSON.stringify(buildCommit()),
|
||
__BUILD_TIME__: JSON.stringify(new Date().toISOString().slice(0, 16).replace("T", " ")),
|
||
},
|
||
plugins: [
|
||
react(),
|
||
VitePWA({ registerType: "autoUpdate", manifest: false, includeAssets: ["icons/*.png"] }),
|
||
],
|
||
resolve: { alias: { "@": path.resolve(__dirname, "src") } },
|
||
server: {
|
||
port: 5174,
|
||
proxy: {
|
||
"/api": {
|
||
// secure: false нужен только для VITE_API_TARGET на https-цель с
|
||
// самоподписанным сертификатом; на дефолтную http-цель не влияет.
|
||
target: process.env.VITE_API_TARGET || "http://127.0.0.1:8000",
|
||
changeOrigin: true,
|
||
secure: false,
|
||
},
|
||
},
|
||
},
|
||
};
|
||
});
|