Conversation
Backend - Layered as domain / application / infrastructure / presentation with the dependency rule pointing inwards; src/container.py is the composition root. The rule is enforced by tests/unit/test_architecture.py, which walks the AST and fails if an inner layer imports an outer one. - Entities are framework-free dataclasses persisted through SQLAlchemy's imperative mapping, so the domain stays pure without a duplicate ORM model. - State transitions moved onto the entities; statuses became StrEnums. - HTTPException no longer escapes the HTTP layer: use cases raise domain errors and one handler maps them to status codes. - 14 bugs fixed, including: deleting an alerted file failed on the FK; delete unlinked the blob before committing; a failed insert orphaned the blob; blocking I/O on the event loop; missing greenlet; a DSN made of "None" when an env var was absent; unbounded uploads; unsanitised filenames; Postgres data written outside its volume; alembic assets missing from the image. - Optimisations: uploads and metadata extraction are streamed in constant memory (the counters reproduce str.splitlines() exactly under arbitrary chunking); the three chained Celery tasks collapse into one invocation on one session; indexes added for both list queries and for alerts.file_id; one event loop per worker process; eager_defaults removes the post-write refresh; downloads use sendfile. - Tooling: uv, ruff, ty, and 99 pytest tests that need neither Postgres nor Redis. Frontend - page.tsx split by Feature-Sliced Design: app / views / widgets / features / entities / shared, with a single HTTP client and shared table primitives. - strict TypeScript, pinned dependencies, API origin from NEXT_PUBLIC_API_URL. - Fixed a Docker build that copied a .env.production that is not in the repo, and a favicon pointing at an unserved path. - The dashboard polls quietly while files are still processing. API behaviour is unchanged: same routes, response fields, statuses and alert messages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Затронуты src/, tests/, миграции, Dockerfile'ы, docker-compose и pyproject. Исполняемый код не менялся: AST всех 57 модулей (без докстрингов) совпадает с предыдущим коммитом. Отключены правила ruff RUF001-RUF003: проверка на омоглифы рассчитана на кодовые базы, где кириллица неожиданна, и на русских комментариях даёт только ложные срабатывания. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Бэкенд
domain/application/infrastructure/presentation, зависимостинаправлены только внутрь.
src/container.py- composition root, единственныймодуль, который знает про все слои сразу. Правило зависимостей проверяется:
tests/unit/test_architecture.pyобходит AST всехмодулей и падает, если внутренний слой импортирует внешний.
таблицы через imperative mapping SQLAlchemy. Домен остаётся чистым
StrEnum.HTTPExceptionбольше не выходит за пределы HTTP-слоя: use case'ы бросаютдоменные ошибки, один обработчик превращает их в коды ответа. Раньше их бросал
слой доступа к данным, который импортировал и Celery-воркер, - 404 внутри
фоновой задачи не значит ничего.
падало на внешнем ключе; blob удалялся с диска до коммита транзакции; при
неудачной вставке блоб оставался на диске навсегда; блокирующий I/O в event
loop; необъявленный
greenlet, без которого async-слой SQLAlchemy не работает;DSN вида
postgresql+asyncpg://None:None@None:None/Noneпри отсутствующейпеременной окружения; неограниченный размер загрузки; неочищенные имена файлов;
данные Postgres писались мимо volume;
alembic.iniи миграции отсутствовали вобразе. Полная таблица - в
backend/README.md.расходом памяти (счётчики строк и символов побайтово воспроизводят
str.splitlines()при любой нарезке на чанки); цепочка из трёх Celery-задачсвёрнута в один вызов на одной сессии; добавлены индексы под оба списочных
запроса и под
alerts.file_id; один event loop на процесс воркера;eager_defaultsубирает лишнийSELECTпосле каждой записи; отдача файловчерез
sendfile.Фронтенд
page.tsxразбит по Feature-Sliced Design:app/views/widgets/features/entities/shared, с одним HTTP-клиентом и общими примитивамитаблиц.
NEXT_PUBLIC_API_URL..env.production, которого нет врепозитории, и падала. Также исправлена иконка, ссылавшаяся на несуществующий
путь.