Skip to content

About

PostgreSQL data importer and Next.js company catalogue

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Company Data Explorer

Серверный каталог компаний с поиском по названию, фильтром по городу и пагинацией. Данные поступают в PostgreSQL через проверяемый импорт JSON/CSV: записи валидируются, дубли не создаются, а проблемные CSV-строки сохраняются отдельно для разбора.

Проект реализован в рамках тестового задания Polza Agency.

Каталог компаний: первая страница таблицы с поиском по названию и фильтром города

Возможности

  • Каталог /companies: поиск без учёта регистра, фильтр города и серверная пагинация по 50 компаний; параметры сохраняются в URL.
  • Проверка структуры JSON-страниц и значений полей; дедупликация по идентификатору источника.
  • Повторяемый импорт: повторная загрузка одинаковых записей не создаёт новые компании.
  • Обнаружение конфликтов: JSON-импорт откатывается целиком; конфликтующие CSV-строки изолируются без перезаписи существующих компаний.
  • Staging/quarantine для CSV: исходные строки, ошибки и причины отклонения сохраняются в отдельной таблице, в каталог попадают только принятые записи.
  • Unit-тесты и интеграционные тесты с настоящим PostgreSQL, включая проверку полного отката при сбое.

Стек и ключевые решения

TypeScript, Node.js, Next.js App Router, React, PostgreSQL 17 и Docker Compose. Для доступа к БД используется pg, для валидации — Zod, для CSV — csv-parse, для проверок — Vitest и Biome.

  • Ключ дедупликации — source_id. Это ID компании в выгрузке и первичный ключ в БД. Название, сайт и телефон не используются как уникальные ключи: разные компании могут разделять эти значения.
  • Конфликт не означает обновление. Если у одного ID различаются данные, JSON-загрузка завершается ошибкой и откатом транзакции. В CSV такая строка получает статус quarantined, а остальные корректные записи могут быть приняты. Ошибка записи в БД откатывает весь импорт.
  • Проблемные данные остаются доступными. review_records хранит промежуточный срез последнего CSV-импорта (staging), включая отклонённые записи (quarantine), исходные значения и причины классификации. Это не история всех загрузок.
  • База доступна только серверному коду. Каталог читает данные через Server Component и параметризованный SQL: пользовательский ввод передаётся отдельно от текста запроса, а строка подключения не отправляется в браузер. B-tree индексы поддерживают сортировку и фильтр города, GIN trigram индекс — поиск по части названия.

Подробности и ограничения — в техническом отчёте.

Быстрый запуск

Нужны Node.js >=20.12.0, npm >=10 и Docker с запущенным Linux daemon. Исходные JSON-страницы и CSV уже включены в data/raw.

Для нового клона и чистого Docker volume, в PowerShell:

git clone https://github.com/brodev3/company-data-explorer.git
cd company-data-explorer
npm ci
Copy-Item .env.example .env
docker compose up -d --wait
npm run import:pages -- --input ./data/raw
npm run import:review -- --input ./data/raw/review.csv
npm run dev

Откройте http://localhost:3000/companies.

В Bash замените только Copy-Item .env.example .env на cp .env.example .env; остальные команды и пути подходят обеим оболочкам. Уже существующий .env не перезаписывайте. При изменении настроек PostgreSQL согласуйте POSTGRES_*, DATABASE_URL и TEST_DATABASE_URL по образцу .env.example; значения примера предназначены только для локальной разработки.

Порядок загрузки: JSON → CSV. CSV-импорт сверяется с уже загруженными компаниями. На чистом volume Compose автоматически применяет полную schema.sql.

Если volume уже существует

При повторном запуске Compose не применяет схему заново. До импорта приведите существующую базу к текущей схеме:

  1. Если review_records имеет старую схему с parse_status, сначала выполните npm run db:migrate:review. Старые записи сохранятся в quarantine до нового CSV-импорта.
  2. Примените schema.sql, чтобы создать отсутствующие таблицы и индексы каталога:
docker compose exec -T db psql -v ON_ERROR_STOP=1 -U company_app -d company_data -f /docker-entrypoint-initdb.d/001-schema.sql

Команда использует пользователя и БД из .env.example; при своих значениях замените -U и -d. Если review_records ещё нет, шаг с миграцией пропустите: таблицу создаст схема. Если схема уже актуальна, повторное применение допустимо. Детали обновления — в техническом отчёте.

Проверки

Из корня репозитория:

npm run format:check
npm run lint
npm run typecheck
npm test
npm run test:integration
npm run build

npm test запускает unit-тесты без БД; npm run test:integration — сценарии с PostgreSQL. Оба набора можно запустить последовательно через npm run test:all.

Тесты проверяют валидацию и дедупликацию, повторный CSV-импорт, конфликты без перезаписи компаний, реальный rollback JSON/CSV после частичной записи, поиск с буквальными % и _, совместный фильтр и устойчивую пагинацию. Отдельно проверяются некорректные входные параметры и безопасные внешние ссылки. Ручные проверки интерфейса и найденные исправления описаны в разделе «Как проверял».

Условия интеграционных тестов: запущенный PostgreSQL, локальный TEST_DATABASE_URL в .env, доступ к служебной БД postgres, права CREATE DATABASE и установки pg_trgm. Разрешены только loopback-адреса (localhost, 127.0.0.1, ::1). Тесты создают и удаляют отдельные временные БД cde_test_*, не используя рабочую БД каталога. Локальный Compose подходит; удалённый Supabase этим тестовым helper не поддерживается.

Необязательная диагностика

Эти команды не нужны для обычного запуска. inspect:* проверяют файлы без записи в БД; db:check проверяет соединение и наличие обязательных объектов схемы.

npm run inspect:pages -- --input ./data/raw
npm run inspect:review -- --input ./data/raw/review.csv
npm run db:check
npm run db:check-conflict

db:check-conflict выполняется после импорта JSON: делает пробную запись, вызывает конфликт и проверяет откат транзакции без изменения исходных компаний.

Другие состояния интерфейса

Документация

  • Технический отчёт — разбор трёх задач, результаты импортов, устройство каталога, ручные проверки и ограничения.
  • ANOMALIES.md — странности CSV, конкретные строки и способ обнаружения.
  • queries.sql — топ-5 категорий, средний рейтинг по городам при 10+ отзывах и доля компаний с сайтом; как выполнить запросы.
  • schema.sql — таблицы, ограничения и индексы PostgreSQL.

About

PostgreSQL data importer and Next.js company catalogue

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages