Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Repo Observer

A Slim Framework 4 application for monitoring GitHub repository releases and sending notifications.

Requirements

  • Docker & Docker Compose (recommended)

Installation

1. Clone the Repository

git clone https://github.com/DimaMaimesko/repo-observer.git
cd repo-observer

2. Copy the example environment file

cp .env.example .env

3. Start the Application

docker-compose up -d

4. Install Dependencies

docker-compose exec slim composer install

5. Run Database Migrations

docker-compose exec slim php vendor/bin/doctrine-migrations migrate --no-interaction

Access the Application (Local)

API Key: secret-api-key

Application web interface: http://localhost:8081

MailPit (Email viewer): http://localhost:8025

Prometheus metrics: http://localhost:8081/metrics

Access the Application (Production)

API Key: secret-api-key

Архітектура

Проєкт зроблено з використанням фреймворків Slim Framework 4 та Doctrine. При виконанні проекта намагався дотримуватись принципів Domain Driven Design, чистої архітектури та CQRS паттерну.

  • Доменна логіка розміщена в src/Domain, у Value Objects (Email, Repo, Id) виконується валідація данних, entity Subscription являє собою Rich Domain Model з інкапсульованою бізнес логікою (методи confirm(), unsubscribe(), updateLastSeenTag()).
  • Використовується Repository Pattern - інтерфейс репозиторію на стороні домену, конкретна реалізація інтерфейсу - на стороні інфраструктури (Infrastructure/DoctrineSubscriptionRepository.php).
  • Доменні сервіси (src/Domain/Subscription/Service) являють собою чітковизначені інтерфейси, які реалізуються на стороні інфраструктури або конкретні сервіси які не належать до entity, але використовуються в межах бізнес логіки (в use cases).
  • Use cases (src/Domain/Subscription/UseCase) являють собою сценарії використання нашої бізнес-логіки, кожен сценарій являє собою команду (Command) та обробник (Handler), вони аркеструють роботу доменних об'єктів не містячи бізнес логіки самі по собі.
  • В контексті CQRS паттерну use cases являють собою команди (Command) які використовують доменні сутності та змінють стан системи, a src/Domain/ReadModel/Subscription/SubscriptionFetcher являє собою модель запросів (Query), які для відображення інформації використовують швидкі оптимізовані запроси в базу даних (PDO).
  • src/Infrastructure - імплементація інтерфейсів доменних об'єктів, інтеграція з зовнішніми сервісами (Mailer, GitHub) та репозіторієм.

Тести

Реалізовані unit tests та integration tests. Структура папок у тестах відповідає структурі папок доменних об'єктів.

  • Unit tests працюють повністю ізольовано від зовнішнього середовища - не використовують базу данних, не відсилають повідомлення на електронну пошту, не використовують зовнішні API (GitHub), замість цього використовують mock-об'єкти. Unit тестами покрита доменна логіка та use cases.
  • Інтеграційні тести перевіряють роботу контроллерів з реальними HTTP запросами, тестовою базою данних та меілером (Mailpit). (Але запроси в GitHub API імітуються). Також інтеграційними тестами перевіряється робота реальних Mailer, Repository та ReadModel.
  • Також зроблений тест який тестує цілком весь флоу підписки та відписки, це мабуть вже можна віднести до E2E тестів.

Для періодичного сканування підписок реалізовано cron job який запускається раз на 5 хвилин і сканує всі активні підписки. Для локальної розробки в якості mail сервера використовується Mailpit, вебінтерфейс якого доступний за адресою http://localhost:8025.

Обробка помилок зовнішнього API

У нас є два сценарії отримання помилок 429 Too Many Requests від зовнішнього API:

  1. Під час підписки на репозиторій: Ми повертаємо користувачу наступний респонс:

    {
      "error": "GitHub API rate limit exceeded. Retry after 120 seconds.",
      "retry_after": 120
    }

    Таким чином він знає причину помилки і знає через який час спробувати знову.

  2. Під час роботи cron job зі сканування репозіторіїв: При отриманні помилки 429 - припиняємо всю подальшу роботу так як немає сенсу продовжувати далі. Через 5 хвилин процесс сканування запуститься знову і якщо rate limit збросився - повторюємо сканування.

User flow

  1. Користувач підписується на репозиторій.
  2. Йому приходить лист із посиланням на підтвердження підписки.
  3. Користувач підтверджує підписку на репозиторій.
  4. При публікації нової версії репозиторію користувач отримує лист із посиланням на нову версію. Також у листі є кнопка для відписки від репозиторію.

Деплой

Деплой виконується на AWS EC2 instance через CI/CD pipeline. Деплоймент флоу виглядає наступним чином:

  1. Push комміта в репозіторій.
  2. Після push тригериться CI pipeline.
  3. Запускається лінтер.
  4. Запускаються тести.
  5. Якщо попередні кроки пройшли успішно - запускається CD pipeline.
  6. Білдиться docker image.
  7. Docker image пушиться в DockerHub.
  8. SSH to EC2 → Pull new image → Restart containers.
  9. Run migrations → Verify deployment.

Конфігурація Docker

Конфігурація Docker контейнерів для прода відрізняється від конфігурації для локального розроблення.

Local Development (docker-compose.yml)

  • 5 services: slim, postgres, redis, mailer, cron
  • Uses PHP built-in server (php -S)
  • Includes Mailpit (email testing tool)
  • Separate cron service for scheduled tasks

Production (docker-compose.prod.yml)

  • 3 services: app, postgres, redis
  • Uses Nginx + PHP-FPM (via Dockerfile.prod)
  • Sendgrid SMTP instead of mail testing tool
  • Cron handled inside app container (via Supervisor)
  • Multi-stage builds

Redis-кешування

Для реалізації Redis-кешування було використано Decorator pattern. CachedGitHubRepositoryChecker декорує GitHubRepositoryChecker, обидва реалізують інтерфейс GitHubRepositoryChecker, декоратор додає кешуючу поведінку "навколо" оригінальної поведінки, не змінюючи її кода.

API key автентифікація

Додано middleware для перевірки API ключа в X-API-KEY header. Middleware застосовано для всіх /api роутів. Довелося додати ключ до HTML сторінки та змінити swagger.yaml В swagger.yaml додано securityDefinitions секція, 401 response до всіх ендпоінтів.

Prometheus metrics

Використовуються наступні метрики:

  • http_requests_total:Total number of HTTP requests
  • http_requests_in_progress:Number of HTTP requests currently being processed
  • http_request_duration_seconds:HTTP request duration in seconds
  • db_queries_total:Total number of database queries
  • emails_sent_total:Total number of emails sent

Метрики доступні за адресами:

gRPC-інтерфейс

Додан gRPC-інтерфейс як доповнення до REST API. Обидва інтерфейси використовують наявну бізнес-логіку. Кожен метод реалізовано окремим обробником, який використовує наявні use cases.

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages