§01
Обзор
- Что это: монорепозиторий системы доставки еды. Принимает заказы, распределяет их по курьерам в реальном времени (учитывая геолокацию, очереди, смены, «дневной гарант»), интегрируется с Yandex Dostavka как fallback-сервисом, рассчитывает зарплаты/балансы курьеров, рейтинги и отчёты. Семь сабсервисов:
api(бэкенд на Elysia),queue(воркеры BullMQ),crons(задачи по расписанию),duck_api(OLAP-аналитика на DuckDB),transfer_db(миграция данных),admin(панель на Refine),mob(приложение курьера на Flutter). - Тип / статус / роль: web-app (распределённая система + мобилка) · maintained (жил ~1.5 года, активно) · lead — пользователь co-lead с Ilhombek (≈78 против 59 коммитов).
- Окно активности: 2023-11-04 → 2025-03-09. Долгоживущая продакшн-система с эволюцией стека внутри: миграции Prisma→Drizzle и NestJS-подобного слоя→Elysia видны в крупных «перетряхивающих» коммитах (92 файла +2962/−3418, 35 файлов +2386/−2924, 29 файлов +2002/−2341).
§02
Стек
- Языки: TypeScript (бэкенд/админка), Dart (мобилка на Flutter), SQL (Postgres + DuckDB).
- Фреймворки/библиотеки:
- *Бэкенд (
api):* Bun + Elysia (кластеризация черезnode:cluster, 4 воркера в проде), Apollo GraphQL (@elysiajs/apollo) + REST, Drizzle ORM (drizzle-typebox,drizzle-zod), Postgres (postgres/pg), BullMQ + Bull, ioredis,jose(JWT), bcrypt,geolib(гео-математика), dayjs (utc/timezone), lodash/radash,@evan/duckdb+ gRPC-клиент к duck_api. - *Аналитика (
duck_api):* DuckDB (duckdb-async) с подключением к Postgres через расширение (ATTACH … TYPE POSTGRES), pg-logical-replication (CDC), Kafka (kafkajs+node-rdkafka), Hono + Elysia, gRPC-сервер (arryt.proto, сервисTransactions). - *Админка:* Refine (
@refinedev/antd,@refinedev/graphql, kbar) + Ant Design 5, TanStack Query, React 18, Vite, Yandex Maps (react-yandex-maps), экспорт в Excel/PDF, react-hook-form, i18next. - *Мобилка (
mob):* Flutter + flutter_bloc, auto_route, Dio + HTTP/2, Firebase (analytics/crashlytics/messaging/performance/remote_config),flutter_background_service(фоновый трекинг GPS курьера), flutter_local_notifications, chatview (чат), inappwebview. - Инфра/деплой: рантайм Bun (
bun.lockbв каждом пакете), PM2 (queue/pm2.config.js), кластеризованный API. Redis для очередей и кэша. Observability: OpenTelemetry (@opentelemetry/sdk-node, OTLP-экспортёр), Prometheus (prom-client), Pino + pino-loki (логи в Grafana Loki). - Данные: Postgres (OLTP, основная БД через Drizzle), DuckDB (OLAP/аналитика, отдельный сервис), Redis (очереди + кэш). gRPC как транспорт между api и duck_api.
- Заметный тулинг: кастомный Bun-плагин (
proto.ts) для импорта.protoнапрямую как модулей; кастомный слойparseFilterFields/parseSelectFieldsдля динамических Drizzle-запросов из фильтров админки.
§03
Что реализовано
NOTE: сообщения коммитов в этом репозитории в основном мусорные («dddd», «dd», «ddd», «fff», «solved») — выводы сделаны по коду, а не по сообщениям.
- Миграция стека: крупные коммиты с почти равными +/− (92 файла +2962/−3418 и т. п.) — порт бэкенда на Bun/Elysia + Drizzle (в
apiдо сих пор остаётся артефактprisma/и~schema.gql, а@prisma/clientсоседствует с drizzle — переходный период). - Диспетчеризация заказов: построен движок назначения курьеров на BullMQ (~18 очередей/воркеров):
new_order_notify,try_assign_courier,push_courier_to_queue,set_queue_last_courier,change_courier,clear_courier,order_complete,change_status,store_location(GPS курьера),send_notification,order_index(поисковый индекс),try_set_daily_garant. - Интеграция с Yandex Dostavka: воркеры
check_and_send_yandex+yandex_callback— авто-передача внешнему сервису, когда своего курьера нет. - OLAP-аналитика: сервис
duck_api— зеркалирует таблицы Postgres в DuckDB + CDC через логическую репликацию/Kafka, отдаёт агрегаты (отчёты по выводам/транзакциям) через gRPC. - Отчёты и расчёты:
crons/calculate_courier_performance.ts(ежемесячный рейтинг курьеров),balance_report_send.ts,send_courier_withdraws_report.ts;orders/controller.tsна 3054 строки — отчёты по гаранту, ценообразование доставки, сводки. - Мобильное приложение курьера: Flutter с фоновым GPS, пушами, чатом, архитектурой на BLoC.
- Объём: 148 коммитов за ~16 месяцев силами двух основных разработчиков; пользователь — крупнейший контрибьютор (~78 коммитов, с учётом трёх его identity).
§04
Технические челленджи
Всё подтверждено по файлам/диффам:
- OLTP→OLAP через DuckDB + CDC (
duck_api/src/sync_duck.ts,arryt.proto,api/src/lib/duck_grpc.ts): тяжёлые аналитические запросы (история транзакций/выводов курьеров) вынесены из Postgres в DuckDB. Синхронизация использует нативное расширение DuckDB для Postgres (INSTALL postgres; ATTACH '…' AS db (TYPE POSTGRES); CREATE TABLE … AS FROM db.<table>) + стриминг дельты черезpg-logical-replicationи Kafka. Результаты возвращаются в основной API по gRPC (Transactions.getWithdrawTransactions). → Демонстрирует понимание разделения OLTP/OLAP, CDC и межсервисного gRPC — серьёзная data-engineering-работа. - Real-time диспетчеризация на очередях (
queue/index.ts+ 16 процессоров): ~18 пар Queue/Worker BullMQ поверх одного Redis, пайплайн назначения курьеров с очередью «последний курьер на терминал», fallback на Yandex, обновление кэша пользователей, индексация для поиска. → Проектирование event-driven системы с воркерами, разделёнными по ответственности. - Алгоритм ранжирования курьеров (
crons/calculate_courier_performance.ts): разрешает граф «связанных терминалов» (getLinkedTerminalIds), батчем подтягивает все заказы и группирует через lodash, 3 параллельных запроса черезPromise.all(count / avg-score / список для позиции в рейтинге), считает среднее время доставки и ранжирует курьеров (сортировка по числу доставок ↓, затем по среднему времени ↑). Пофакурьерный try/catch сcontinue— частичные сбои не роняют весь крон. → Продакшн-устойчивость + нетривиальная бизнес-логика. - Кластеризованный Elysia с observability (
api/src/index.ts,app.ts, package.json): в проде 4 воркера, форкнутых черезnode:cluster, OpenTelemetry + экспорт по OTLP, метрики Prometheus (prom-client), структурированные логи в Loki (pino-loki). → Зрелый операционный подход. - Слой динамических запросов (
api/src/lib/parseFilterFields.ts,parseSelectFields.ts, сsql.placeholderдля prepared statements): админ-панель (Refine) шлёт фильтры/выборки полей → бэкенд безопасно собирает Drizzle-запросы. → Переиспользуемая абстракция вместо копипасты в каждом контроллере. - Кастомный Bun-плагин для .proto (
proto.ts):Bun.pluginсonLoad-фильтром/\.proto$/, парсит protobuf и возвращает JS-модуль (лоадер"object"). → Нестандартное знание тулинга рантайма Bun. - Тяжёлый Flutter-клиент (
mob/pubspec.yaml): фоновый GPS-сервис (flutter_background_service+disable_battery_optimization), полный стек Firebase, HTTP/2 через Dio, BLoC, auto_route, встроенный чат. → Реальное продакшн-мобильное приложение для курьеров, а не прототип.
§05
AI-разработка
- Найдено сессий: 0 в локальной директории сессий Claude Code для этого проекта. Сессии есть для отдельного проекта
new_arryt(и его мобильного сабдиректория) — это переписывание, покрытое в задаче #37, а не этот проект. - Что было сделано с AI: данных по этому репозиторию нет.
- Паттерны AI-воркфлоу: отсутствуют — проект в основном написан до активного использования Claude Code (2023–2025, до перехода на new_arryt).
§06
Достижения и метрики
- Масштаб: монорепозиторий из 7 сабсервисов, ~25 доменных модулей в
api/src/modules/(orders, couriers/users, terminals, delivery_pricing, daily_garant, order_transactions, manager_withdraw, brands, organizations, roles/permissions, work_schedules, chart, missed_orders, …). - Сложность ядра:
orders/controller.ts— 3054 строки бизнес-логики; ~18 фоновых воркеров; версия api1.0.50. - Реальная нагрузка: продакшн-доставка еды (Restaurant chain (UZ)/Restaurant chain (UZ)), интеграция с Yandex Dostavka, расчёт зарплат/балансов курьеров — система проработала ~1.5 года.
- Полнота: бэкенд + аналитика + админка + мобилка — закрывает весь цикл доставки.