Back in Time
Техническая Архитектура

Иммерсивная платформа для изучения истории через реконструкцию повседневной жизни. Open-source архитектура с токен-экономикой верификации.

12 месяцев разработки
MVP готовность

Ключевые инновации

  • No-code конструктор исторических событий
  • Алгоритмы синхронных связей между регионами
  • Токен-экономика для верификации контента
  • Иммерсивная визуализация без VR/AR

География и Время

Интерактивные карты и временные шкалы

Обзор платформы Back in Time

Концепция

Back in Time (BIT) — это иммерсивная веб-платформа для изучения мировой истории через реконструкцию повседневной жизни. Пользователи перемещаются по карте и временной шкале, просматривая события с деталями быта, погоды, запахов, звуков и технологий.

Модель контента

Платформа построена на краудсорсинге: пользователи создают контент с помощью no-code «Конструктора событий». Встроена токен-экономика для верификации — пользователи получают токены за подтверждение достоверности чужих материалов.

Важные ограничения

  • • Платформа работает только через веб-браузер (без VR/AR)
  • • Используется open-source стек с PostgreSQL и Redis
  • • AI-агенты применяются только для автоматизации разработки
  • • Срок разработки MVP: 12 месяцев (грантовый период)

Общая архитектура системы

Компонентная архитектура

Диаграмма компонентов системы Back in Time
graph TB subgraph frontend ["Frontend (React PWA)"] A1["React Router"] A2["Redux Toolkit"] A3["Material-UI"] A4["Leaflet Maps"] A5["Vis.js Timeline"] A6["PWA Service Worker"] end subgraph backend ["Backend API (Node.js)"] B1["Express/Fastify"] B2["JWT Middleware"] B3["Rate Limiting"] B4["Bull Queue"] B5["Redis Cache"] end subgraph database ["Database Layer"] C1["PostgreSQL + PostGIS"] C2["Redis Sessions"] C3["Redis Cache"] C4["Redis Queues"] end subgraph external ["External Services"] D1["OpenStreetMap/Nominatim"] D2["VK OAuth"] D3["Telegram Login"] D4["Yandex.GPT (Dev Only)"] end A1 --> B1 A2 --> B1 A4 --> D1 B1 --> C1 B1 --> C2 B1 --> C3 B2 --> C2 B4 --> C4 B1 --> D1 B1 --> D2 B1 --> D3 B1 -.-> D4 style frontend fill:#f0fdf4 style backend fill:#f3f4f6 style database fill:#fef3c7 style external fill:#e0e7ff

Клиентский уровень

  • • React 18+ с Concurrent Features
  • • Redux Toolkit для состояния
  • • Material-UI 5.x
  • • Leaflet для карт
  • • Vis.js для временных шкал
  • • PWA с офлайн-поддержкой

Серверный уровень

  • • Node.js + Express/Fastify
  • • JWT-аутентификация
  • • Rate limiting и валидация
  • • Bull Queue для задач
  • • Layered Architecture
  • • Stateless сервисы

Уровень данных

  • • PostgreSQL 15+ с PostGIS
  • • Master-Replica репликация
  • • Redis для кэша и сессий
  • • JSONB для гибкой схемы
  • • Полнотекстовый поиск
  • • Пространственные индексы

Потоки данных

Процессы системы: аутентификация, создание событий и верификация
flowchart TD subgraph auth ["Аутентификация"] A1["User"] --> A2["Email/Password"] A1 --> A3["OAuth VK/Telegram"] A2 --> A4["JWT Tokens"] A3 --> A4 A4 --> A5["Access Token"] A4 --> A6["Refresh Token Cookie"] end subgraph event_creation ["Создание события"] B1["Author"] --> B2["Create Draft"] B2 --> B3["Add Blocks"] B3 --> B4["Save Draft"] B4 --> B5["Submit for Verification"] B5 --> B6["Lock Stake 10 tokens"] B6 --> B7["Status: pending"] end subgraph verification ["Процесс верификации"] C1["Community"] --> C2["Review Event"] C2 --> C3["Vote Confirm/Reject"] C3 --> C4["Vote Count +1"] C4 --> C5{"Threshold 5 votes?"} C5 -->|Yes| C6["Publish Event"] C5 -->|No| C7["Wait for more votes"] C6 --> C8["Return Stake + Bonus"] C8 --> C9["Reward Verifiers"] C7 --> C10["Timeout 14 days"] C10 --> C11["Reject Event"] C11 --> C12["Burn Stake"] end A5 --> B1 A5 --> C1

Схема базы данных

Основные таблицы

users (пользователи)

id              UUID PRIMARY KEY
email           VARCHAR(255) UNIQUE
password_hash   VARCHAR(255)
username        VARCHAR(50) UNIQUE
role            ENUM('user', 'moderator', 'admin')
is_active       BOOLEAN
created_at      TIMESTAMPTZ
                        

events (события)

id              UUID PRIMARY KEY
title           VARCHAR(500)
description     TEXT
date_start      DATE
date_end        DATE
date_precision  ENUM('year', 'month', 'day', 'hour')
location        GEOGRAPHY(POINT, 4326)
author_id       UUID REFERENCES users
status          ENUM('draft', 'pending', 'published', 'rejected')
vote_count      INTEGER DEFAULT 0
                        

event_blocks (нулевые блоки)

id              UUID PRIMARY KEY
event_id        UUID REFERENCES events
block_type      VARCHAR(50)
sort_order      INTEGER
data            JSONB
created_at      TIMESTAMPTZ
                        

Токен-экономика

token_balances (балансы)

user_id         UUID PRIMARY KEY
amount          INTEGER CHECK (amount >= 0)
frozen_amount   INTEGER CHECK (frozen_amount >= 0)
version         INTEGER
                        

token_transactions (транзакции)

id              UUID PRIMARY KEY
user_id         UUID REFERENCES users
type            ENUM('grant', 'earn', 'spend', 'stake_lock', 'bonus')
amount          INTEGER
balance_after   INTEGER
related_event_id UUID REFERENCES events
                        

event_stakes (залоги)

id              UUID PRIMARY KEY
event_id        UUID UNIQUE REFERENCES events
user_id         UUID REFERENCES users
amount          INTEGER
status          ENUM('active', 'returned', 'burned')
expires_at      TIMESTAMPTZ
                        

Индексы и оптимизация

Пространственные индексы (PostGIS)

CREATE INDEX idx_events_location 
ON events USING GIST(location) 
WHERE status = 'published';
                        

GiST-индекс для эффективного поиска событий в географическом окне. Используется для запросов типа "события в прямоугольнике".

Временные индексы

CREATE INDEX idx_events_published_timeline 
ON events(date_start, date_end, id)
WHERE status = 'published';
                        

Частичный индекс для временных диапазонов. Исключает черновики, уменьшая размер индекса и улучшая производительность.

Полнотекстовый поиск

CREATE INDEX idx_events_fts_weighted ON events USING GIN (
    setweight(to_tsvector('russian', coalesce(title, '')), 'A') ||
    setweight(to_tsvector('russian', coalesce(description, '')), 'B') ||
    setweight(to_tsvector('russian', coalesce(location_name, '')), 'C')
);
                    

Взвешенный поиск с разной важностью полей: заголовок (A), описание (B), место (C).

Спецификация API

Аутентификация

POST /auth/register

Регистрация нового пользователя

{
  "email": "user@example.com",
  "password": "secure_password",
  "username": "historian_2024"
}
                            
POST /auth/login

Вход в систему

{
  "email": "user@example.com",
  "password": "secure_password"
}
                            
POST /auth/oauth/vk

OAuth аутентификация через VK

{
  "code": "oauth_code_from_vk",
  "state": "csrf_protection_state",
  "redirectUri": "https://app.backintime.io/auth/callback"
}
                            

События и контент

GET /events

Поиск и фильтрация событий

?dateFrom=1800-01-01
&dateTo=1900-12-31
&bbox=2.2,48.8,2.5,49.0
&status=published
&page=1&limit=20
                            
POST /events

Создание нового события (черновик)

{
  "title": "Взятие Бастилии",
  "description": "Начало Великой французской революции",
  "date": "1789-07-14",
  "location": {"lat": 48.8530, "lng": 2.3691},
  "blocks": [
    {"type": "politics", "data": {"actor": "Парижские sans-culottes"}}
  ]
}
                            
POST /events/:id/submit

Отправка на верификацию

{
  "stakeRequired": 10,
  "expiresAt": "2024-02-15T10:30:00Z"
}
                            

Форматы ответов и обработка ошибок

Стандартный ответ (200 OK)

{
  "data": [...],  // массив результатов
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1543,
    "hasMore": true
  },
  "meta": {
    "cacheHit": false,
    "queryTimeMs": 45
  }
}
                        

Ошибка (RFC 7807)

{
  "type": "https://api.backintime.io/errors/insufficient-funds",
  "title": "Insufficient funds for stake",
  "status": 402,
  "detail": "Your balance (5 tokens) is less than required stake (10 tokens)",
  "context": {
    "currentBalance": 5,
    "requiredAmount": 10
  }
}
                        

Ключевые алгоритмы

Алгоритм построения синхронных связей

Определение временной близости

Алгоритм учитывает разную точность датирования через нормализацию к временным интервалам с допустимыми толерантностями.

Толерантности по точности:
  • • Час: ±1 час
  • • День: ±7 дней
  • • Месяц: ±3 месяца
  • • Год: ±1 год
  • • Десятилетие: ±5 лет
  • • Век: ±25 лет

Географическая кластеризация

Глобальный уровень: по континентам (>2000 км)
Региональный уровень: по государствам (>500 км)
Локальный уровень: по городам (>50 км)
Детальный уровень: точечные события (>5 км)

Ранжирование связей

35%
Временная близость
25%
Географическая контрастность
20%
Тематическая близость
15%
Достоверность
5%
Популярность

Алгоритм токен-экономики

Блокировка залога

Адаптивный залог на основе истории пользователя:

  • • Новые пользователи: 150% базового залога
  • • 10+ успешных публикаций: 75%
  • • История отклонений: до 200%
  • • Базовый залог: 10 токенов
Распределение при публикации
Автор (возврат + бонус): 12 токенов
Верификаторы (по 1 токену): 5 токенов
Ранние верификаторы (бонус): +1 токен
Общая эмиссия: 18 токенов

Процесс верификации

1
Создание черновика

Пользователь заполняет блоки, сохраняет без залога

2
Отправка на проверку

Блокировка залога, статус 'pending'

3
Голосование сообщества

Пользователи голосуют, тратя токены

4
Достижение порога

При 5 голосах - публикация и вознаграждения

5
Таймаут

Через 14 дней - отклонение, залог сгорает

Алгоритм генерации иммерсивного представления

Процесс рендеринга

1. Сбор данных
  • • Загрузка основного события
  • • Группировка блоков по типам
  • • Поиск параллельных событий
  • • Определение временного контекста
2. Агрегация
  • • Объединение сенсорных данных
  • • Интерполяция отсутствующих данных
  • • Формирование нарративной структуры
  • • Компиляция источников
3. Рендеринг
  • • Генерация заголовка
  • • Создание сенсорных панелей
  • • Формирование временной ленты
  • • Адаптация под устройство

Пример иммерсивного описания

"Утро 14 июля 1789 года в Париже. [погода: прохладно, 15°C, лёгкий дождь]. На улицах [быт: толпы ремесленников и торговок, напряжённое ожидание]. В воздухе висит [сенсорный: запах пороха и мокрого камня, отдалённые крики]. [технологии: факелы и кремнёвые пистолеты — передовые технологии протеста]. [персоналии: Камиль Демулен поднимает толпу у Пале-Рояля]..."

Структура нулевых блоков (JSON-схемы)

Политика и власть

Основные поля
  • • actor_type: monarch, government, parliament, revolutionary_body
  • • actor_name: строка (макс. 200 символов)
  • • event_category: accession, abdication, war_declaration, revolution
  • • territorial_scope: массив регионов с координатами
Зависимости

При actor_type: "monarch" требуются дополнительные поля: dynasty, reign_start, reign_end

Повседневность и быт

Основные поля
  • • social_group: peasantry, urban_commoners, merchant_class, nobility
  • • life_sphere: housing, nutrition, clothing, hygiene, leisure
  • • housing_conditions: тип жилья, количество комнат, отопление
  • • nutrition: калории, основные продукты, частота приемов пищи
Условные поля

При life_sphere: "housing" требуется housing_conditions, при "nutrition" - nutrition и т.д.

Технологии и изобретения

Основные поля
  • • tech_domain: agriculture, manufacturing, transport, communication
  • • innovation_type: invention, improvement, diffusion, obsolescence
  • • technology: name, description, inventor, year_of_invention
  • • technical_parameters: характеристики с единицами измерения
Диффузия и влияние
  • • adoption_curve: instant, rapid, gradual, slow, resisted
  • • geographic_spread: регионы и годы распространения
  • • economic_impact: изменение производительности, затронутые отрасли
  • • environmental_impact: потребление ресурсов, загрязнение

Погода и климат

Основные поля
  • • record_type: observation, reconstruction, anomaly, extreme_event
  • • data_source: instrumental, proxy_data, historical_document
  • • data_quality: high, medium, low, uncertain
  • • temperature: value_celsius, is_anomaly, anomaly_magnitude
Экстремальные события
  • • event_type: drought, flood, storm, hurricane, heat_wave
  • • severity: minor, moderate, severe, catastrophic
  • • human_impact: deaths_estimate, displaced_people, economic_damage
  • • return_period_years: частота события в годах

Принципы JSON-схем

  • JSON Schema Draft-07 - стандарт валидации
  • Зависимые поля - условная валидация по типу блока
  • Мультиязычные строки - поддержка i18n
  • Гибкая структура - дополнительные поля через additionalProperties
  • Версионирование - поддержка миграций через поле version

Вопросы безопасности

Аутентификация и авторизация

  • JWT с двумя токенами: access (15-30 мин) + refresh (7-30 дней)
  • HttpOnly cookies: для refresh токенов, защита от XSS
  • OAuth 2.0: VK, Telegram с проверкой возраста аккаунта
  • Роли и политики: user, moderator, admin с разграничением доступа

Защита от атак

  • Rate limiting: 100 запросов/мин с клиента, Nginx rate limit
  • CSRF protection: SameSite=Strict, CSRF токены для форм
  • SQL injection: подготовленные запросы, ORM, валидация
  • XSS protection: экранирование, Content-Security-Policy

Анти-Sybil механизмы

  • Обязательная привязка соцсети: VK/Telegram, возраст >90 дней
  • Поведенческий анализ: флаги при >10 голосов/час или 100% согласии
  • Граф доверия: понижение веса голосов с общими IP/UA
  • Экономический барьер: стоимость голоса растет с массовостью

Обработка чувствительных данных

  • • Пароли: Argon2id с настраиваемым cost factor
  • • Токены OAuth: AES-256-GCM шифрование в БД
  • • Личные данные: псевдонимизация, доступ по необходимости
  • • Логи: без sensitive data, ротация 30 дней

Мониторинг и инциденты

  • • Логирование: Winston + структурированные логи (JSON)
  • • Метрики: Prometheus + Grafana для мониторинга
  • • Алерты: Telegram/Email для критических событий
  • • План реакции: процедуры для утечек, DDoS, компрометации

Развертывание и DevOps

Контейнеризация

  • Backend API: Node.js + Express в alpine образе
  • Frontend: Nginx для статики + React build
  • PostgreSQL: официальный образ с PostGIS
  • Redis: alpine образ с persistence

CI/CD Pipeline

  • GitHub Actions: автоматический запуск на push/pull request
  • Тестирование: unit, integration, API тесты
  • Статический анализ: ESLint, SonarCloud
  • Сборка образов: Docker Hub / GitHub Container Registry

Инфраструктура

  • VPS: Timeweb, Selectel, AWS (по мере роста)
  • Балансировка: Nginx upstream, health checks
  • Репликация: PostgreSQL master-replica, Redis Sentinel
  • Бэкапы: ежедневные, хранение 30 дней, off-site

Масштабируемость и отказоустойчивость

Горизонтальное масштабирование

Backend API

Stateless сервисы, можно запускать множество инстансов за балансировщиком. Конфигурация Nginx upstream с health checks и failover.

База данных

PostgreSQL master-replica: write на primary, read на replicas. Чтение масштабируется добавлением реплик.

Отказоустойчивость

PostgreSQL

Репликация с автоматическим failover через Patroni или ручную процедуру. RTO ≈ 30 секунд, RPO ≈ 0 (с synchronous commit).

Redis

Sentinel mode: 1 master + 2 replica с автоматическим failover. Для очередей Bull - отдельный инстанс с persistence.

Мониторинг и метрики

Системные метрики
  • • CPU, RAM, Disk usage
  • • Network I/O, connections
  • • PostgreSQL stats, slow queries
  • • Redis memory, hit ratio
Приложение
  • • HTTP requests, response time
  • • Error rates, 5xx errors
  • • API endpoints performance
  • • Queue lengths, processing time
Бизнес-метрики
  • • Active users, sessions
  • • Events created, published
  • • Votes per day
  • • Token circulation

Заключение

Техническая архитектура платформы Back in Time представляет собой масштабируемое, отказоустойчивое решение, сочетающее современные подходы к разработке с уникальной токен-экономической моделью верификации контента.

Ключевые преимущества

  • Открытый исходный код, прозрачность алгоритмов
  • Децентрализованная верификация через сообщество
  • Иммерсивный опыт без сложных технологий VR/AR
  • Гибкая система нулевых блоков для разных типов контента

Дальнейшие шаги

  • Разработка MVP в течение 12 месяцев
  • Тестирование токен-экономики на пилотной аудитории
  • Интеграция с музеями и образовательными учреждениями
  • Масштабирование инфраструктуры под растущую нагрузку

Техническая документация подготовлена для команды разработки и представляет собой основу для реализации платформы Back in Time. Архитектура гибко масштабируется и позволяет встраивать новые функциональные возможности без фундаментальных изменений.