Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Пересняты скриншоты публичного сайта в интерфейсе ALL MARKET на витринной организации «Магазин у дома» (200 товаров, ~30 дней продаж, чистые данные без e2e/test-мусора). Светлая тема, 1440×900 @2x, WebP + srcset, alt по-русски. - screenshots.mjs: стенд + витринный владелец, 14 экранов (дашборд/каталог/ карточка/приёмки/остатки/инвентаризация/деньги/отчёты/контрагенты), скрытие баннеров стенда/«что нового»/MoM-дельты, резолв AsyncSelect-подписей - optimize-screenshots.mjs: PNG→WebP (1x 1440w / 2x 2880w) через canvas, все ≤300КБ - pos-mockup/pos-mockup.html: светлая касса ALL MARKET «Магазин у дома» (продажа+оплата) - index.astro: hero-дашборд + каталог + новый блок «Касса»; pos.astro: продажа+оплата - ShowcaseSeeder: стартовый завоз всех товаров (нет отрицательных остатков) - deploy/showcase-seed.sh: RESET=1 пересоздаёт витрину с нуля - исходные PNG не коммитятся (.gitignore), доставка — только WebP Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
106 lines
6.1 KiB
Bash
Executable file
106 lines
6.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
# Витринная организация «Магазин у дома» на стенде + наполнение правдоподобными
|
||
# данными для скриншотов публичного сайта (ShowcaseSeeder). Повторяемый и
|
||
# идемпотентный: при повторном запуске переиспользует организацию и не задваивает
|
||
# данные (сидер проверяет наличие товаров).
|
||
#
|
||
# Требует задеплоенного на стенд API с эндпоинтом POST /api/admin/seed-demo?showcase=1
|
||
# (см. src/food-market.api/Seed/ShowcaseSeeder.cs). Деплой стенда: ~/deploy-stage.sh.
|
||
#
|
||
# Запуск:
|
||
# bash deploy/showcase-seed.sh
|
||
# BASE=https://test.admin.food-market.kz bash deploy/showcase-seed.sh
|
||
#
|
||
# На выходе печатает orgId и e-mail владельца (их же использует scripts/screenshots.mjs
|
||
# через SHOWCASE_EMAIL/SHOWCASE_ORG).
|
||
set -euo pipefail
|
||
|
||
BASE="${BASE:-https://test.admin.food-market.kz}"
|
||
EMAIL="${SHOWCASE_EMAIL:-vladelec@magazin-u-doma.kz}"
|
||
PASSWORD="${SHOWCASE_PASSWORD:-MagazinUDoma2026!}"
|
||
ORGNAME="${SHOWCASE_ORG:-Магазин у дома}"
|
||
PHONE="+77015550102"
|
||
|
||
j() { python3 -c 'import sys,json;d=json.load(sys.stdin);print(d.get(sys.argv[1],""))' "$1"; }
|
||
|
||
echo "→ стенд: $BASE организация: «$ORGNAME» владелец: $EMAIL"
|
||
|
||
# 0. (опц.) RESET=1 — архивировать прежнюю витринную орг. через SuperAdmin, чтобы
|
||
# пересоздать её с нуля (signup реактивирует владельца с новой организацией).
|
||
# Только стенд: мастер-пароль быстрого входа работает лишь при QuickLogin и не-прод Issuer.
|
||
if [[ "${RESET:-0}" == "1" ]]; then
|
||
SA_EMAIL="${SUPERADMIN_EMAIL:-admin@food-market.local}"
|
||
SA_PASS="${SUPERADMIN_PASSWORD:-__QUICK_LOGIN_PWLESS__}"
|
||
echo "→ RESET: архивирую прежнюю «$ORGNAME» (SuperAdmin $SA_EMAIL)…"
|
||
SATOKEN=$(curl -sk -m 30 -X POST "$BASE/connect/token" -H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode grant_type=password --data-urlencode "username=$SA_EMAIL" --data-urlencode "password=$SA_PASS" \
|
||
--data-urlencode client_id=food-market-web --data-urlencode 'scope=openid profile email roles api' | j access_token)
|
||
if [[ -n "$SATOKEN" ]]; then
|
||
# orgId прежнего владельца (если он ещё существует и активен).
|
||
OLDTOKEN=$(curl -sk -m 30 -X POST "$BASE/connect/token" -H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode grant_type=password --data-urlencode "username=$EMAIL" --data-urlencode "password=$PASSWORD" \
|
||
--data-urlencode client_id=food-market-web --data-urlencode 'scope=openid profile email roles api' | j access_token)
|
||
if [[ -n "$OLDTOKEN" ]]; then
|
||
OLDORG=$(curl -sk -m 30 "$BASE/api/me" -H "Authorization: Bearer $OLDTOKEN" | j orgId)
|
||
if [[ -n "$OLDORG" ]]; then
|
||
code=$(curl -sk -m 30 -o /dev/null -w '%{http_code}' -X POST "$BASE/api/super-admin/organizations/$OLDORG/archive" \
|
||
-H "Authorization: Bearer $SATOKEN" -H 'Content-Type: application/json' \
|
||
-d "{\"confirmationName\":\"$ORGNAME\"}")
|
||
echo " archive $OLDORG → HTTP $code"
|
||
fi
|
||
else
|
||
echo " прежний владелец не логинится (орг уже архивна?) — пропускаю."
|
||
fi
|
||
else
|
||
echo " ⚠ не удалось получить SuperAdmin-токен — пропускаю RESET."
|
||
fi
|
||
fi
|
||
|
||
# 1. Регистрация организации (идемпотентно: если e-mail занят — просто логинимся).
|
||
echo "→ signup…"
|
||
signup=$(curl -sk -m 60 -X POST "$BASE/api/auth/signup" \
|
||
-H 'Content-Type: application/json' \
|
||
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"organizationName\":\"$ORGNAME\",\"phone\":\"$PHONE\",\"plan\":\"start\"}" \
|
||
-w '\n%{http_code}')
|
||
code=$(echo "$signup" | tail -1)
|
||
body=$(echo "$signup" | sed '$d')
|
||
if [[ "$code" == "200" ]]; then
|
||
echo " создана новая организация."
|
||
elif echo "$body" | grep -q "уже зарегистрирован"; then
|
||
echo " организация уже существует — переиспользуем."
|
||
elif [[ "$code" == "429" ]]; then
|
||
echo " rate-limit на signup, ждём 15с и повторяем…"
|
||
sleep 15
|
||
curl -sk -m 60 -X POST "$BASE/api/auth/signup" -H 'Content-Type: application/json' \
|
||
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"organizationName\":\"$ORGNAME\",\"phone\":\"$PHONE\",\"plan\":\"start\"}" >/dev/null || true
|
||
else
|
||
echo " signup вернул $code: $body" >&2
|
||
echo " (продолжаем — возможно, организация уже заведена)"
|
||
fi
|
||
|
||
# 2. Токен владельца.
|
||
echo "→ получаем токен…"
|
||
TOKEN=$(curl -sk -m 60 -X POST "$BASE/connect/token" \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'grant_type=password' \
|
||
--data-urlencode "username=$EMAIL" \
|
||
--data-urlencode "password=$PASSWORD" \
|
||
--data-urlencode 'client_id=food-market-web' \
|
||
--data-urlencode 'scope=openid profile email roles api offline_access' \
|
||
| j access_token)
|
||
if [[ -z "$TOKEN" ]]; then echo "✗ не удалось получить токен" >&2; exit 1; fi
|
||
|
||
ORGID=$(curl -sk -m 30 "$BASE/api/me" -H "Authorization: Bearer $TOKEN" | j orgId)
|
||
echo " orgId=$ORGID"
|
||
|
||
# 3. Наполнение витринными данными.
|
||
echo "→ seed showcase (товары/продажи/счета/сотрудники)…"
|
||
resp=$(curl -sk -m 300 -X POST "$BASE/api/admin/seed-demo?showcase=1" \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Length: 0')
|
||
echo "$resp" | python3 -m json.tool 2>/dev/null || echo "$resp"
|
||
|
||
echo
|
||
echo "✓ готово. Для скриншотов:"
|
||
echo " SHOWCASE_EMAIL=$EMAIL SHOWCASE_PASSWORD=*** node src/food-market.public/scripts/screenshots.mjs"
|
||
echo " orgId=$ORGID"
|