Срез 0: скелет tabular-parser — без фронта и БД, воркер NATS без JetStream, парсер-заглушка, контракт v1.0 #3

Merged
aep merged 50 commits from feat/1-slice-0-skeleton into main 2026-10-04 18:41:02 +03:00
2 changed files with 46 additions and 0 deletions
Showing only changes of commit 479a76f81b - Show all commits

View File

@ -143,6 +143,20 @@ async def test_nats_disabled_starts_nothing_and_healthcheck_reports_off(
assert events == ["s3.close"]
async def test_minimal_environment_starts_and_healthcheck_answers(
patched_app: Any, monkeypatch: pytest.MonkeyPatch, minimal_settings: Callable[..., Any]
) -> None:
"""Старт с минимальным окружением: только MinIO, адрес NATS и DEBUG (без seed/jwt, БД и SMB)."""
monkeypatch.setattr(patched_app, "settings", minimal_settings())
assert patched_app.settings.NATS_ENABLED is True
async with running_app(patched_app) as client:
response = await client.get("/healthcheck")
assert response.status_code == 200 # noqa: PLR2004 - HTTP 200
assert set(response.json()) == {"uptime", "version", "nats"}
async def test_nats_enabled_subscribes_worker_and_reports_ok(
patched_app: Any, monkeypatch: pytest.MonkeyPatch, events: list[str]
) -> None:

View File

@ -0,0 +1,32 @@
"""Страж spec «Сервис не зависит от БД и фронта» (DECISION-4): ни зависимостей БД/SMB/шаблонной авторизации, ни
каталогов фронта, миграций, моделей и репозиториев."""
import re
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[3]
REQUIREMENTS = REPO_ROOT / "api" / "requirements.txt"
FORBIDDEN_PACKAGES = (
"asyncpg",
"sqlalchemy",
"alembic",
"smbprotocol",
"argon2-cffi",
"raisa_fastapi_protected_api",
)
FORBIDDEN_DIRS = ("web", "api/alembic", "api/src/db", "api/src/models", "api/src/repositories")
@pytest.mark.parametrize("package", FORBIDDEN_PACKAGES)
def test_requirements_have_no_database_or_template_auth_packages(package: str) -> None:
name = re.sub(r"[-_.]", "[-_.]", package) # имена пакетов сравниваются по PEP 503: -, _ и . равнозначны
pattern = re.compile(rf"^\s*{name}\s*(?:[=<>!~;\[]|$)", re.IGNORECASE)
lines = REQUIREMENTS.read_text(encoding="utf-8").splitlines()
assert not [line for line in lines if pattern.match(line)]
@pytest.mark.parametrize("directory", FORBIDDEN_DIRS)
def test_no_frontend_or_database_directories(directory: str) -> None:
assert not (REPO_ROOT / directory).exists()