- FastAPI backend: PostGIS estimator + 3 scrapers (Avito/Cian/Yandex)
- Next.js 15 frontend: tradein.html mockup design, basePath=/trade-in
- WeasyPrint PDF (Брусника-style 4-page report)
- Address autocomplete с typo-tolerance + 6 EKB presets
- Изолированный docker stack gendesign-tradein (отдельная postgres БД)
- Caddy inline routes: gendsgn.ru/trade-in/* и /trade-in/api/v1/*
- Forgejo Actions: .forgejo/workflows/deploy-tradein.yml (shell-based GHCR login)
- Триггер только по paths: tradein-mvp/** (не пересекается с deploy.yml)
- Образы: ghcr.io/lekss361/gendesign-tradein-{backend,frontend}:latest
Первый запуск на сервере (вручную, один раз):
- создать /opt/gendesign/tradein-mvp/.env.runtime (postgres pwd, contact email)
- docker network create gendesign_shared (если нет)
- docker compose -p gendesign-tradein up -d
- docker compose -p gendesign exec caddy caddy reload
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
/**
|
||
* Session ID utility for custom POI auth.
|
||
* Stored in localStorage under "session_id" key.
|
||
* Returns empty string during SSR (window not available).
|
||
*
|
||
* ВАЖНО: `crypto.randomUUID()` доступен только в secure context (HTTPS / localhost).
|
||
* На HTTP-страницах (например, http://94.228.121.73:8091) он undefined → fallback на ручную генерацию.
|
||
*/
|
||
function generateUUID(): string {
|
||
// Native — если есть и работает (HTTPS / localhost / file://)
|
||
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
||
try {
|
||
return crypto.randomUUID();
|
||
} catch {
|
||
// редкие браузеры могут бросить SecurityError — падаем в ручной fallback
|
||
}
|
||
}
|
||
// Fallback: v4 UUID через Math.random (НЕ криптостойко, но для session_id хватает)
|
||
// Шаблон: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx где y ∈ {8,9,a,b}
|
||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
||
const r = (Math.random() * 16) | 0;
|
||
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
||
return v.toString(16);
|
||
});
|
||
}
|
||
|
||
export function getOrCreateSessionId(): string {
|
||
if (typeof window === "undefined") return "";
|
||
let id = localStorage.getItem("session_id");
|
||
if (!id) {
|
||
id = generateUUID();
|
||
localStorage.setItem("session_id", id);
|
||
}
|
||
return id;
|
||
}
|