diff --git a/AIProjectCard.md b/AIProjectCard.md new file mode 100644 index 0000000..24c7109 --- /dev/null +++ b/AIProjectCard.md @@ -0,0 +1,1085 @@ +# Контекст проекта + +Мы разрабатываем стартап/проект для **автоматизированного end-to-end тестирования пользовательских API через GitHub Actions**. + +## Главная идея + +Продукт должен позволять разработчику проверить, что его backend-приложение действительно работает целиком с точки зрения пользователя. + +Это НЕ API monitoring и НЕ сервис, который постоянно проверяет API. + +Тест запускается **один раз** в рамках CI/CD pipeline. + +Основной сценарий: + +```text +GitHub Actions Job + │ + ├── Checkout repository + │ + ├── Build application + │ + ├── Start application + │ + ├── Wait until application is ready + │ + ├── Run API E2E tests + │ + ├── Generate report + │ + └── Cleanup +``` + +Например: + +```text +POST /register + ↓ +POST /login + ↓ +GET /profile + ↓ +POST /posts + ↓ +GET /posts/{id} + ↓ +DELETE /posts/{id} +``` + +Если любой шаг ломается, GitHub Actions Job должен завершиться с ошибкой. + +--- + +# Главная ценность продукта + +Продукт должен проверять не отдельные endpoints, а **полноценные пользовательские сценарии**. + +Например: + +```text +Register user + ↓ +получить user_id + ↓ +Login + ↓ +получить JWT + ↓ +Get profile с JWT + ↓ +Create post + ↓ +получить post_id + ↓ +Get post + ↓ +Delete post +``` + +Данные между запросами должны автоматически передаваться. + +Пример: + +```text +login.response.token + ↓ +Authorization: Bearer {{token}} + +create.response.id + ↓ +GET /posts/{{post_id}} +``` + +--- + +# Важное отличие от обычного API monitoring + +Не нужно постоянно проверять: + +```text +GET /health +GET /health +GET /health +``` + +Нас интересует одноразовая проверка: + +> "Я только что поднял приложение. Может ли реальный пользователь пройти через основной сценарий и работает ли API целиком?" + +--- + +# Основной execution environment + +Основной execution environment — **GitHub Actions**. + +Очень важно: + +Тестируемое приложение должно запускаться **в рамках того же GitHub Actions Job**, в котором выполняется API E2E test. + +Например: + +```yaml +jobs: + e2e: + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v4 + + - name: Start application + run: docker compose -f docker-compose.test.yml up -d + + - name: API E2E + uses: our-org/api-e2e@v1 + with: + spec: tests/api.yaml + base-url: http://localhost:8080 + + - name: Cleanup + if: always() + run: docker compose -f docker-compose.test.yml down -v +``` + +В будущем желательно, чтобы сам Action мог запускать Docker Compose и выполнять cleanup автоматически. + +--- + +# Требование к Docker + +Основной вариант для MVP: + +```text +Docker +Docker Compose +``` + +Типичное приложение: + +```text +docker-compose.test.yml + +api +postgres +redis +etc. +``` + +Продукт должен уметь: + +1. запустить приложение; +2. дождаться readiness; +3. проверить healthcheck; +4. выполнить тесты; +5. собрать результаты; +6. удалить контейнеры; +7. выполнить cleanup даже при падении тестов. + +--- + +# API Test Engine + +Главное ядро проекта — собственный API Test Engine. + +Он должен поддерживать: + +```text +GET +POST +PUT +PATCH +DELETE +HEAD +OPTIONS +``` + +Каждый request должен иметь: + +```text +Method +URL +Headers +Query parameters +Body +Timeout +Variables +Assertions +Extraction +``` + +--- + +# Variables + +Нужны обычные переменные: + +```yaml +variables: + email: test@example.com + password: Test123! +``` + +Использование: + +```yaml +url: /api/users/{{user_id}} +``` + +--- + +# Dynamic variables + +Нужна генерация тестовых данных: + +```text +{{random.uuid}} +{{random.email}} +{{random.username}} +{{random.string}} +{{random.number}} +{{timestamp}} +``` + +Это необходимо для сценариев регистрации и создания ресурсов. + +--- + +# Extraction + +Один request должен уметь извлекать данные из response и передавать их следующим request. + +Например: + +```yaml +- name: Login + + request: + method: POST + url: /api/login + + extract: + token: "$.token" +``` + +Следующий request: + +```yaml +- name: Profile + + request: + method: GET + url: /api/profile + + headers: + Authorization: "Bearer {{token}}" +``` + +Для JSON желательно использовать JSONPath или совместимый механизм. + +--- + +# Assertions + +Минимально необходимы: + +```text +HTTP status +JSON field exists +JSON value +Header +Response time +Regex +Contains +Equals +Not equals +Exists +``` + +Например: + +```yaml +expect: + status: 200 + + json: + user.id: + exists: true + + user.email: + equals: "{{email}}" +``` + +--- + +# OpenAPI + +Продукт обязательно должен поддерживать: + +```text +OpenAPI 3.0 +OpenAPI 3.1 +YAML +JSON +``` + +OpenAPI должен использоваться для: + +* импорта API; +* обнаружения endpoints; +* определения HTTP methods; +* определения parameters; +* определения request body; +* определения response schemas; +* генерации базовых тестов; +* schema validation. + +Например: + +```text +OpenAPI + ↓ +Parser + ↓ +Internal Test Model + ↓ +API Test Engine +``` + +--- + +# Postman + +Продукт должен поддерживать импорт: + +```text +Postman Collection v2 +Postman Collection v2.1 +``` + +Нужно поддержать: + +* requests; +* methods; +* URLs; +* headers; +* query parameters; +* body; +* variables; +* environments; +* authentication; +* request chains; +* basic assertions; +* extracted variables. + +Очень важно: + +OpenAPI и Postman **не должны напрямую использоваться Test Engine**. + +Оба формата должны преобразовываться во внутреннюю модель. + +```text +Postman ────────┐ + ↓ + Internal Test Model + ↑ +OpenAPI ────────┘ + ↓ + Test Engine +``` + +Это позволит позже добавлять другие форматы. + +--- + +# Authentication + +Минимально: + +```text +None +Basic Auth +Bearer Token +API Key +OAuth 2.0 +``` + +Особенно важен сценарий: + +```text +POST /login + ↓ +extract JWT + ↓ +Bearer {{token}} + ↓ +GET /profile +``` + +--- + +# Reporting + +После теста должны создаваться: + +```text +Console report +JUnit XML +JSON +HTML +GitHub Step Summary +``` + +Пример: + +```text +API E2E Tests + +✓ Register 184ms +✓ Login 92ms +✓ Profile 61ms +✓ Create post 142ms +✗ Delete post 83ms + +5 / 6 passed + +FAILED: +Delete post + +Expected: 204 +Received: 500 +``` + +GitHub Actions должен получать корректный exit code: + +```text +0 = success +1 = failure +``` + +Также нужны GitHub annotations: + +```text +::error +::warning +::notice +::group +``` + +--- + +# Local CLI + +Хотя основное выполнение происходит через GitHub Actions, Test Engine должен работать локально. + +Например: + +```bash +api-e2e run tests/api.yaml +``` + +или: + +```bash +api-e2e run \ + --spec tests/api.yaml \ + --base-url http://localhost:8080 +``` + +Также нужны: + +```bash +api-e2e validate +api-e2e import +api-e2e report +``` + +Локальный запуск нужен для debugging. + +Один и тот же тест должен работать: + +```text +Local + ↓ +api-e2e CLI + +CI + ↓ +GitHub Action +``` + +--- + +# Будущая SaaS-часть + +После создания рабочего Test Engine можно сделать веб-платформу. + +Frontend: + +```text +Dashboard +Projects +Test scenarios +Scenario editor +Request editor +Assertions editor +Run history +Test results +Logs +Reports +GitHub integration +``` + +Backend: + +```text +Users +Projects +Repositories +Test scenarios +Test runs +Results +GitHub integrations +``` + +Backend НЕ должен выполнять пользовательские API-тесты напрямую. + +Основное выполнение должно происходить в GitHub Actions. + +--- + +# GitHub App + +В дальнейшем желательно сделать полноценный GitHub App вместо ручного PAT. + +Пользователь: + +```text +Connect GitHub + ↓ +Install GitHub App + ↓ +Select repository + ↓ +Select tests +``` + +GitHub integration должна позволять запускать тесты: + +```text +Pull Request +Push +Manual +Release +Schedule +``` + +--- + +# Рекомендуемый стек + +Мы остановились на TypeScript. + +## Test Engine + +```text +TypeScript +Node.js +``` + +## CLI + +```text +TypeScript +Commander или аналог +``` + +## GitHub Action + +```text +TypeScript +Node.js +``` + +## Backend + +```text +TypeScript +Node.js +Fastify +``` + +## Database + +```text +PostgreSQL +``` + +## ORM + +```text +Drizzle или Prisma +``` + +## Frontend + +```text +Next.js +React +TypeScript +Tailwind +``` + +## Infrastructure + +```text +Docker +Docker Compose +GitHub Actions +``` + +--- + +# Предполагаемая архитектура + +```text + GitHub Actions + │ + ▼ + ┌─────────────────┐ + │ API E2E CLI │ + │ / Action │ + └────────┬────────┘ + │ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ + OpenAPI Parser Postman Parser Config + │ │ │ + └──────────────┼──────────────┘ + ▼ + Internal Test Model + │ + ▼ + Test Engine + │ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ + HTTP Variables Assertions + │ │ │ + └──────────────┼──────────────┘ + ▼ + Reports +``` + +--- + +# Структура репозитория + +Предполагаемая структура: + +```text +api-e2e/ +│ +├── packages/ +│ ├── engine/ +│ │ ├── http/ +│ │ ├── assertions/ +│ │ ├── variables/ +│ │ ├── extraction/ +│ │ ├── runner/ +│ │ └── reports/ +│ │ +│ ├── openapi/ +│ │ └── parser/ +│ │ +│ ├── postman/ +│ │ └── parser/ +│ │ +│ ├── config/ +│ └── cli/ +│ +├── action/ +│ ├── action.yml +│ └── src/ +│ +├── backend/ +├── frontend/ +│ +├── examples/ +│ ├── basic/ +│ ├── docker-compose/ +│ ├── openapi/ +│ └── postman/ +│ +├── tests/ +│ +├── docker-compose.yml +├── package.json +└── README.md +``` + +--- + +# Очередность разработки + +Очень важно: **не начинать сразу с SaaS/frontend/backend**. + +Разработка должна идти в следующем порядке. + +## Phase 1 — Test Engine + +Сначала сделать полностью автономный CLI. + +Цель: + +```bash +api-e2e run tests/api.yaml +``` + +Он должен: + +```text +Load config +↓ +Execute requests +↓ +Pass variables +↓ +Extract values +↓ +Run assertions +↓ +Return result +↓ +Exit code +``` + +После этой фазы можно локально протестировать полноценный E2E workflow. + +--- + +## Phase 2 — Variables + Extraction + Assertions + +Добавить: + +* static variables; +* environment variables; +* random data; +* JSON extraction; +* JSONPath; +* status assertions; +* JSON assertions; +* header assertions; +* response-time assertions; +* regex; +* contains; +* equals; +* exists. + +--- + +## Phase 3 — Docker + +Добавить: + +* Docker Compose; +* startup; +* readiness; +* healthcheck; +* timeout; +* logs; +* cleanup; +* cleanup on failure. + +Цель: + +```bash +api-e2e run \ + --compose docker-compose.test.yml \ + --spec tests/api.yaml +``` + +Должно происходить: + +```text +Start containers +↓ +Wait for API +↓ +Run tests +↓ +Generate report +↓ +Cleanup +``` + +--- + +## Phase 4 — GitHub Action + +После того как CLI работает локально: + +* action.yml; +* inputs; +* outputs; +* exit codes; +* GitHub annotations; +* GitHub Step Summary; +* JUnit; +* artifacts. + +Цель: + +```yaml +- uses: our-org/api-e2e@v1 + with: + spec: tests/api.yaml + compose: docker-compose.test.yml +``` + +--- + +## Phase 5 — OpenAPI + +Добавить: + +* OpenAPI 3.0; +* OpenAPI 3.1; +* YAML; +* JSON; +* endpoint discovery; +* request generation; +* response schema validation; +* authentication; +* test generation. + +--- + +## Phase 6 — Postman + +Добавить: + +* Collection v2; +* Collection v2.1; +* environments; +* variables; +* headers; +* authentication; +* body; +* assertions; +* extracted variables; +* chained requests. + +--- + +## Phase 7 — Web UI + +Только после рабочего CLI и GitHub Action. + +Добавить: + +* authentication; +* projects; +* GitHub integration; +* test scenario editor; +* request editor; +* assertions editor; +* run history; +* results; +* logs; +* reports. + +--- + +## Phase 8 — GitHub App + +Добавить: + +* GitHub App; +* repository selection; +* workflow integration; +* permissions; +* webhooks; +* automatic PR integration. + +--- + +## Phase 9 — SaaS + +После появления рабочего продукта: + +* accounts; +* teams; +* projects; +* usage limits; +* billing; +* plans; +* cloud storage; +* test history. + +--- + +# MVP + +Первый MVP должен содержать только: + +* GitHub Action; +* CLI; +* YAML test specification; +* HTTP requests; +* variables; +* extraction; +* assertions; +* Docker Compose; +* startup; +* readiness; +* cleanup; +* JUnit; +* GitHub Summary; +* OpenAPI import; +* Postman import. + +Не делать в MVP: + +* API monitoring; +* browser testing; +* load testing; +* Kubernetes; +* собственные CI runners; +* AI; +* десятки интеграций; +* сложную SaaS-платформу. + +--- + +# Безопасность + +Это критически важная часть. + +Тесты могут содержать: + +```text +API keys +Passwords +JWT +Cookies +Database credentials +Production secrets +``` + +Поэтому: + +* secrets нельзя писать в logs; +* Authorization headers должны маскироваться; +* passwords нельзя сохранять; +* secrets должны передаваться через GitHub Secrets; +* response body не должен отправляться на наш сервер без явного разрешения; +* необходимо ограничивать размеры response; +* необходимо ограничивать timeout; +* необходимо валидировать URLs; +* необходимо предотвращать SSRF; +* нельзя выполнять произвольные shell-команды из пользовательской конфигурации; +* выполнение тестов должно происходить в изолированном GitHub Actions environment. + +Особенно важно: + +**Backend SaaS не должен напрямую выполнять произвольные HTTP-запросы пользователей.** + +--- + +# Главный принцип разработки + +Не пытаться сразу создать огромную платформу. + +Сначала должно работать: + +```text +Docker Compose + ↓ +Application + ↓ +API E2E Engine + ↓ +Assertions + ↓ +Report + ↓ +Cleanup +``` + +Потом: + +```text +CLI + ↓ +GitHub Action +``` + +Потом: + +```text +OpenAPI + + +Postman +``` + +И только потом: + +```text +Frontend + + +Backend + + +GitHub App + + +SaaS +``` + +--- + +# Конечная концепция продукта + +Продукт должен отвечать на простой вопрос: + +> **«Если я только что поднял своё приложение, может ли реальный пользователь пройти через основной API-сценарий от начала до конца?»** + +Пример: + +```text +Application started + ↓ +Healthcheck + ↓ +Register + ↓ +Login + ↓ +Get profile + ↓ +Create resource + ↓ +Get resource + ↓ +Update resource + ↓ +Delete resource + ↓ +PASS +``` + +В идеале пользователь должен иметь возможность взять существующий: + +```text +OpenAPI +``` + +или: + +```text +Postman Collection +``` + +и практически сразу получить готовый E2E-тест, который можно запускать локально и в GitHub Actions. + +Главная конкурентная идея продукта: + +> **Не заменять Postman или OpenAPI, а превращать существующие API-описания в воспроизводимые E2E CI-тесты, которые проверяют реальный пользовательский сценарий на только что запущенном приложении.**