Интерфейс из двух контейнеров для работы со списком из 1 000 000 элементов.
- слева показываются все невыбранные элементы
- справа показываются выбранные элементы с ручной сортировкой
- поддерживаются фильтрация по
ID, infinite scroll, drag-and-drop, сохранение выбора и порядка
- Backend:
Express.js - Frontend:
React + Vite - Database:
PostgreSQL - Drag&Drop:
dnd-kit+ native HTML5 DnD - Data access:
pg
- cursor pagination по
20элементов - versioned API через
/api/v1/... - серверное хранение выбора и сортировки
- добавление новых элементов по ручному
ID - batching и дедупликация запросов на сервере
- targeted reorder без полной перезаписи
selected_items - read batching с короткоживущим read-cache
- виртуализация обоих списков на frontend
- мягкая фоновая синхронизация после
select/deselect
apps/backend— Express API, сервисы, очереди, seedapps/frontend— UI из двух контейнеров, infinite scroll, DnDpackages/shared— общие типы и константыdocs— контракт API, модель данных, поведение очередейinfrastructure— SQL-инициализация и инфраструктурные файлыtests— browser/API/backend regression tests
- Поднять PostgreSQL через
docker compose up -dнаlocalhost:5433. - При необходимости скопировать
.env.exampleв.env. - Установить зависимости через
npm.cmd install. - Выполнить сид через
npm.cmd run seed --workspace @million-items/backend. - Запустить backend через
npm.cmd run dev --workspace @million-items/backend. - Запустить frontend через
npm.cmd run dev --workspace @million-items/frontend.
PORTDATABASE_URLDB_POOL_MAXFRONTEND_URLADD_QUEUE_FLUSH_MSSYNC_QUEUE_FLUSH_MSPAGE_SIZE
GET /api/v1/healthGET /api/v1/itemsGET /api/v1/selected-itemsPOST /api/v1/items/addPOST /api/v1/selected-items/setPOST /api/v1/selected-items/reorder
GET-чтения батчатся раз вSYNC_QUEUE_FLUSH_MS, но повторные одинаковые чтения могут обслуживаться из короткоживущего cache.- После успешных
add/select/reorderread-cache инвалидируется. - Поиск не сохраняется между обновлениями страницы.
- Выбор и порядок общие для всех посетителей.
- Несколько клиентов работают с одним глобальным server state: изменения одного пользователя становятся источником истины для всех.
- Открытые вкладки не получают push-обновления автоматически и сходятся к актуальному состоянию после нового чтения или reload.
- Конкурирующие
setпо одномуitemIdвнутри одного sync-окна схлопываются до последнего состояния, и все ожидающие запросы получают финальный результат.
npm.cmd run test:deep-scrollnpm.cmd run test:browser-scrollnpm.cmd run test:browser-selection-syncnpm.cmd run test:multi-usernpm.cmd run test:multi-user-queuenpm.cmd run test:read-cachenpm.cmd run test:reorder-integritynpm.cmd run test:reorder-queuenpm.cmd run test:edge-cases
Текущий прогресс реализации и remediation-работы ведётся в IMPLEMENTATION_PLAN.md.