embeddevio
f077a85cba
test(ci): ветка проверки пайплайна — deploy/Dockerfile из #18 (Refs #17 )
ci / lint (push) Successful in 50s
contract-openapi / openapi-contract (push) Failing after 41s
contract-openapi / ts-client-is-current (push) Failing after 40s
ci / unit (push) Successful in 45s
ci / security (push) Successful in 1m11s
ci / build (push) Successful in 1m15s
ci / image-scan (push) Failing after 4s
ci / push (push) Has been skipped
2026-10-28 22:01:48 +03:00
embeddevio
a941525f2e
ci: тесты требуют requirements-contract.txt; явный guard на отсутствие deploy/Dockerfile
...
ci / lint (push) Successful in 42s
contract-openapi / openapi-contract (push) Failing after 41s
contract-openapi / ts-client-is-current (push) Failing after 31s
ci / unit (push) Successful in 41s
ci / security (push) Successful in 1m19s
ci / build (push) Has been skipped
ci / image-scan (push) Has been skipped
ci / push (push) Has been skipped
Refs #17
2026-10-28 22:01:14 +03:00
embeddevio
b13f5e8ac5
ci: пайплайн с гейтами (lint, unit+coverage>=70%, security, build, image-scan, push staging-<sha>)
...
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 1s
ci / lint (push) Successful in 7m38s
ci / unit (push) Failing after 1m3s
ci / security (push) Successful in 2m19s
ci / build (push) Has been skipped
ci / image-scan (push) Has been skipped
ci / push (push) Has been skipped
Refs #17 , Refs #15
- lint: ruff check/format + mypy strict
- unit: pytest с --cov-fail-under=70, артефакты coverage.xml + htmlcov
- security: bandit -lll (HIGH) + pip-audit, артефакты bandit/pip-audit
- build: docker build deploy/Dockerfile -> staging-<sha> (активируется после merge #18 )
- image-scan: trivy HIGH/CRITICAL --exit-code 1
- push: docker login + push в registry 192.168.1.111:3000
Обход дефекта Gitea git-http (upload-pack отдаёт пустой pack): fallback
на archive/<sha>.tar.gz, actions/checkout остаётся основным путём.
2026-10-28 21:47:05 +03:00
embeddevio
4ff22f4323
Merge pull request 'Sprint 0 / #20 : хранилище состояния — SQLite WAL, миграции, audit log, атомарный apply/rollback' ( #50 ) from feat/20-storage into main
...
contract-openapi / openapi-contract (push) Failing after 37s
contract-openapi / ts-client-is-current (push) Failing after 38s
Sprint 0 / #20 : хранилище состояния — SQLite WAL, миграции, audit log, атомарный apply/rollback
Правки по ревью QA (#54 critical, #55 D-1/D-2) внесены и приняты:
RLock на чтения, BaseException → revert + failed в аудите, old_value внутри транзакции.
Гейт на merge-состоянии (main + PR): ruff/format чисто, mypy strict 21 файл,
pytest 107 passed / coverage 97.80% (порог 70%), 55/55 AC-проб, 28/28 security-проб,
мутационная проверка тестов пройдена. Ревью: qa-engineer (APPROVE) + TechLead.
Refs #20 , #54 , #55 , #52 .
2026-10-28 21:35:41 +03:00
embeddevio
3e3519edc8
Merge pull request 'Sprint 0 / #19 : OpenAPI 3.1 контракт API v1 + TS-клиент и контрактные тесты' ( #57 ) from feat/19-openapi into main
...
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
Sprint 0 / #19 : OpenAPI 3.1 контракт API v1 + TS-клиент и контрактные тесты
AC проверены независимо (ревью TechLead): генератор TS-клиента (blob сверен),
отклонение схемы роняет контрактный тест (мутации), секретов в ответах нет.
Гейты: ruff/mypy чисто, pytest 93 passed / coverage 95.48% (порог 70%).
CI green недостижим — runner отсутствует (#52 ); отклонение зафиксировано в PR.
Refs #19 , #15 , #52 .
2026-10-28 21:21:13 +03:00
embeddevio
063ecf18ce
Merge pull request 'Sprint 0 / #16 : каркас монорепозитория, ADR-001..008 и линтеры' ( #47 ) from feat/16-repo-skeleton into main
...
Sprint 0 / #16 : каркас монорепозитория, ADR-001..008, линтеры (ruff/mypy/pytest, coverage>=70)
Гейты прогнаны вручную на байтах ветки (CI runner отсутствует — #52 ):
ruff check rc=0, ruff format --check rc=0, mypy strict rc=0,
pytest 2 passed / coverage 100% (порог 70%).
Ревью: TechLead. Refs #16 , #15 , #52 .
2026-10-28 21:16:03 +03:00
embeddevio
c4661c9db9
test( #20 ): регрессионные тесты потокобезопасности ( #54 ) и BaseException/TOCTOU ( #55 )
...
Новый файл backend/tests/test_store_concurrency.py:
* N потоков × M upsert с чтениями → 0 ошибок, rules == audit_rows == N*M;
* чтение во время открытой транзакции другого потока не видит незафиксированных
строк (ждёт коммита);
* чтение во время падающего apply не видит состояния, которое будет откачено
(AC «не частично применённая конфигурация»);
* BaseException (KeyboardInterrupt/SystemExit/CancelledError) из Applier →
revert вызван, failed в audit_log, БД восстановлена;
* два конкурентных set_geoip_schedule → связная цепочка old→new в журнале.
На коде до правки все 7 тестов падают; после — проходят.
Refs #20 , Refs #54 , Refs #55
2026-10-28 21:12:35 +03:00
embeddevio
e989e46b19
chore(ui): generated TS client schema.d.ts (block 5/5: operations tail)
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 1s
2026-10-28 21:12:09 +03:00
embeddevio
249f32e3f9
fix( #20 ): потокобезопасные чтения, BaseException в apply, old_value внутри транзакции ( #54 , #55 )
...
Закрывает замечания ревью QA по PR #50 :
* #54 : все чтения Store идут через Database.read() под тем же RLock, что
транзакции; контракт «одно соединение, все операции под локом»
задокументирован в db.py и README модуля. Устраняет TypeError/IndexError
на общем соединении, грязные чтения и выдачу состояния, которое затем
откатывается падающим apply.
* #55 D-1: apply ловит BaseException — отмена/CancelledError/
KeyboardInterrupt вызывают Applier.revert(previous) и пишут failed в
audit_log (без «висящей» записи staged); падение revert попадает в detail.
* #55 D-2: set_geoip_schedule читает old_value внутри той же транзакции.
Refs #20 , Refs #54 , Refs #55
2026-10-28 21:12:09 +03:00
embeddevio
d8fc5c7f7d
chore(ui): generated TS client schema.d.ts (block 4/5: operations)
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 0s
2026-10-28 21:11:54 +03:00
embeddevio
4ff7d39fb1
chore(ui): generated TS client schema.d.ts (block 3/5: responses)
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 0s
2026-10-28 21:11:36 +03:00
embeddevio
5522f32638
chore(ui): generated TS client schema.d.ts (block 2/5: schemas)
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 0s
2026-10-28 21:11:21 +03:00
embeddevio
ba1a870d32
chore(ui): fix bearer placeholder in generated client
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 0s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 0s
2026-10-28 21:10:57 +03:00
embeddevio
217a11919d
chore(ui): generated TS client schema.d.ts (block 1/5: paths)
contract-openapi / openapi-contract (push) Failing after 0s
contract-openapi / ts-client-is-current (push) Failing after 1s
contract-openapi / openapi-contract (pull_request) Failing after 0s
contract-openapi / ts-client-is-current (pull_request) Failing after 0s
2026-10-28 21:09:21 +03:00
embeddevio
8691a3dec1
chore(ui): add generated TS client schema.d.ts (part 1/4)
contract-openapi / openapi-contract (push) Failing after 27s
contract-openapi / ts-client-is-current (push) Failing after 30s
contract-openapi / ts-client-is-current (pull_request) Failing after 1s
contract-openapi / openapi-contract (pull_request) Failing after 43s
2026-10-28 21:08:12 +03:00
embeddevio
3387eb0f60
test(contract): restore trailing newline at EOF
contract-openapi / openapi-contract (push) Failing after 32s
contract-openapi / ts-client-is-current (push) Failing after 28s
contract-openapi / openapi-contract (pull_request) Failing after 32s
contract-openapi / ts-client-is-current (pull_request) Failing after 33s
2026-10-28 21:07:11 +03:00
embeddevio
c53e2ef9b1
test(contract): align response contract test with the verified green run
contract-openapi / openapi-contract (push) Failing after 40s
contract-openapi / ts-client-is-current (push) Failing after 1m24s
2026-10-28 21:06:55 +03:00
embeddevio
c6150bd5fd
test(contract): align spec test with the verified green run
contract-openapi / openapi-contract (push) Failing after 18m54s
contract-openapi / ts-client-is-current (push) Failing after 18m49s
2026-10-28 21:06:33 +03:00
embeddevio
95f1337fd4
chore(ui): скрипт генерации TS-клиента из OpenAPI (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- ui/scripts/generate-api.sh: openapi-typescript@7 над docs/openapi.yaml.
- ui/src/api/generated/README.md: правила перегенерации и семантика writeOnly-секретов.
2026-10-22 00:23:16 +03:00
embeddevio
3dac7e730a
test(api): контрактные тесты «схема ↔ реализация» (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- test_openapi_spec: валидность 3.1, полнота операций по ТЗ, writeOnly-секреты,
единый формат Error, соответствие pydantic-моделей схемам.
- test_contract_responses: все эндпоинты против схем, ошибки 401/404/409/422/503,
WS-кадры, отсутствие секретов в ответах.
- test_contract_negative: доказательство AC — подмена реализации на расходящуюся
роняет контрактный тест с указанием пути до поля.
2026-10-22 00:22:46 +03:00
embeddevio
7d9cf8ca5e
feat(api): роутеры API v1 и WebSocket-поток метрик (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- ops: health/ready/metrics без аутентификации (503 = схема Error).
- auth: login/logout/session, cookie-сессия + CSRF-токен.
- status/config/routing/devices+logs: все эндпоинты контракта.
- ws/metrics: /api/v1/metrics/stream, токен в заголовке или query.
2026-10-22 00:21:56 +03:00
embeddevio
839f773010
feat(api): контрактный харнесс и in-memory состояние мок-сервера (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- contract.py: загрузка docs/openapi.yaml, вырезание writeOnly-секретов из схем
ответов, валидация тела ответа (jsonschema Draft2020-12 + FormatChecker),
двусторонняя сверка маршрутов приложения и контракта.
- state.py: мок-состояние туннеля/правил/устройств/журнала; секреты хранятся
отдельно от словарей-ответов.
2026-10-22 00:21:43 +03:00
embeddevio
83d5a23406
feat(api): мок-контрол-плейн по контракту + единый формат ошибок (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- app.py: create_app() собирает мок-сервер и отдаёт /openapi.json из спецификации.
- errors.py: ApiError + хендлеры, приводящие 4xx/5xx/422 к схеме Error.
- deps.py: Bearer-токен и cookie-сессия (ADR-008).
- schemas.py: pydantic-модели запросов, зеркалящие схемы контракта (extra=forbid,
writeOnly для секретов).
2026-10-22 00:21:06 +03:00
embeddevio
cc3640f13c
docs(api): OpenAPI 3.1 контракт API v1 как source of truth (Refs #19 )
...
contract-openapi / openapi-contract (push) Has been cancelled
contract-openapi / ts-client-is-current (push) Has been cancelled
- docs/openapi.yaml: все эндпоинты ТЗ, единый формат ошибок {code,message,details},
writeOnly для private_key/preshared_key/password, WS-кадры metrics/stream.
- requirements-contract.txt: зависимости контрактных тестов (jsonschema,
openapi-spec-validator, PyYAML) до мержа каркаса PR #47 .
- .gitea/workflows/contract-openapi.yml: lint + контрактный тест + проверка
актуальности сгенерированного TS-клиента.
2026-10-22 00:20:36 +03:00
embeddevio
7e10ffaf8a
test(store): репозиторий (аудит по всем сущностям) и персистентность после рестарта ( #20 )
2026-10-21 23:45:30 +03:00
embeddevio
89e5a5a883
test(store): миграции, аудит, атомарный apply/rollback ( #20 )
2026-10-21 23:45:06 +03:00
embeddevio
238d39a274
feat(store): репозиторий Store — аудируемые мутации по всем сущностям ( #20 )
2026-10-21 23:44:03 +03:00
embeddevio
34610b069c
feat(store): миграции схемы v1, репозиторий с аудитом, атомарный apply/rollback ( #20 )
2026-10-21 23:43:45 +03:00
embeddevio
c5b06a7ea4
feat(store): SQLite WAL, миграции, валидация, аудит, снимки состояния ( #20 )
2026-10-21 23:43:14 +03:00
embeddevio
9163265782
feat(store): схемы/модели/ошибки слоя хранения ( #20 )
2026-10-21 23:42:32 +03:00
embeddevio
1db3824cb4
docs( #16 ): ADR-007 (web-сервер) и ADR-008 (безопасность)
2026-10-21 23:29:36 +03:00
embeddevio
d9cad87fc8
docs( #16 ): ADR-005 (DNS) и ADR-006 (состояние)
2026-10-21 23:29:29 +03:00
embeddevio
63a2df893d
docs( #16 ): ADR-003 (reconcile) и ADR-004 (GeoIP провайдер)
2026-10-21 23:29:24 +03:00
embeddevio
63e653b710
docs( #16 ): ADR-001, ADR-002, индекс и шаблон ADR
2026-10-21 23:29:18 +03:00
embeddevio
5647d339b1
chore( #16 ): каркас пакетов backend, тестов и заглушки ui/deploy/tests
2026-10-21 23:28:59 +03:00
embeddevio
63c4fa930d
chore( #16 ): skeleton репозитория — README, Makefile, линтеры, зависимости
2026-10-21 23:28:50 +03:00
embeddevio
f7936fa882
Initial commit
2026-10-16 22:45:47 +03:00