Skip to content

Commit

Permalink
docs: update documentation with last changes
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-chinour committed Nov 7, 2024
1 parent fc2be7a commit fe33392
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 27 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=bugs)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=coverage)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)

![PHP 8.3](https://img.shields.io/badge/php_8.3-brightgreen?logo=php&logoColor=white)
![Symfony 7.1](https://img.shields.io/badge/Symfony_7.1-brightgreen?logo=symfony)

**Sandbox project used to try some stuffs and made good code (_I believe_) on my free time.**

## Documentation

**Documentation is available in docs folder or with [Docsify](https://docsify.js.org) in this
Expand Down
80 changes: 53 additions & 27 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=bugs)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=adrien-chinour_blog&metric=coverage)](https://sonarcloud.io/summary/new_code?id=adrien-chinour_blog)

# Installation 🔧

> Installation requires `make` on your machine as well as `docker` (with a version that includes Compose).
```sh
# Create .env.local file
cp .env .env.local

# Put values on missing environnements variables
# Put values on missing environnements variables (or use InMemory repository)
nano .env.local

# Build application container and install dependencies (composer)
Expand All @@ -24,7 +27,15 @@ make install

## Overview

> TODO make a schema about project architecture
This project is an **API gateway** designed for a Tech Blog system, connecting external systems (such as a CMS) to the
blog's front end. It enables seamless integration and management of core blog components like articles, projects, and
comments, while also offering advanced features like a Feature Flag system to toggle specific functionalities.

Unlike typical APIs, this gateway is built to function without a dedicated database. Instead, it leverages simple
objects to represent domain models, creating a clear separation between the **Domain Layer**
and **Infrastructure Layer**. This modular architecture enhances flexibility, enabling easy adaptation to various
external data sources. For a deeper dive into the system’s layer architecture, see the chapter on **system layering and
structure**.

## Coding standards

Expand All @@ -48,26 +59,40 @@ Allowed types are :
- **build** – changes that affect the build system or external dependencies
- **revert** – reverts a previous commit

## Layers
### PHP

See the [PER Coding Style](https://www.php-fig.org/per/) (an evolution of PSR-12) as well as
the [Symfony coding standards](https://symfony.com/doc/current/contributing/code/standards.html).

> Easy Coding Standard is used to prevent coding standard deviation on PHP code. (See Quality CI)
## System layering and structure

Project not use default Symfony structure but use a multi layer organisation. These layers are :
This project deviates from the default Symfony structure, adopting a multi-layered architecture for better organization
and separation of concerns. The layers are as follows:

- **Domain** : contain business logic, in our case Models and Repositories Interface.
- **Infrastructure** : make link with framework (Symfony) and External services (Contentful, GitHub, etc.).
- **Application** : define actions on application, implement CQRS pattern.
- **Presentation** : in charge of http request/response handling.
1. Domain Layer: Contains the core business logic, including Models and Repository Interfaces. This layer is
framework-agnostic, focusing solely on the business rules and data definitions that drive the application.
2. Application Layer: Defines and manages application actions, implementing the CQRS (Command Query Responsibility
Segregation) pattern to separate read and write operations for improved clarity and maintainability.
3. Presentation Layer: Responsible for handling HTTP requests and responses, acting as the main interface between the
API and its consumers.
4. Infrastructure Layer: Manages integration with the Symfony framework and external services such as Contentful,
GitHub, and others. This layer serves as the bridge to third-party services, ensuring external dependencies are
decoupled from core business logic.

> See [Domain-driven design](https://en.wikipedia.org/wiki/Domain-driven_design).
>
# Query/Command Bus 🚌

Application Layer of project use the [CQRS](https://en.wikipedia.org/wiki/Command_Query_Responsibility_Segregation)
architecture pattern.
The Application Layer of this project follows
the [CQRS](https://en.wikipedia.org/wiki/Command_Query_Responsibility_Segregation) (Command Query Responsibility
Segregation) architecture pattern.

Implementation is made with [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) using the
default `sync` Transport for Query and Command.
This pattern is implemented using [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html), with
the default `sync` transport currently handling both Queries and Commands.

> **✨ Improvement** : Use an async Transport for Command.
> **✨ Improvement**: Configure asynchronous transport for Commands.
## Query Caching

Expand All @@ -94,7 +119,7 @@ final readonly class GetArticleQuery implements CacheableQueryInterface
## Cache invalidation

Cache can be purged from `/webhook/cache-invalidation` with `tag[]` defined in query.
Cache can be purged from `/cache/invalidation` with `tag[]` defined in query.

# Security 👮

Expand Down Expand Up @@ -139,23 +164,24 @@ hour, if all crawled page are 404. Only 10, if all page need authentication.

> rate limit is store using default Symfony cache (filesystem). It will be reset on every new app deployment.
## Secure routes
## Secure Routes

Accessing routes under `^/webhook` is available with authentication. Security is configured under Symfony
SecurityBundle in `config/security.php`.
Certain routes are restricted to users with the `ADMIN` role. Security is configured through Symfony’s SecurityBundle,
located in `config/security.php`.

There is no user database, it used _in memory_ provider with a default admin user with ROLE_ADMIN. Authentication
use `Symfony\Component\Security\Http\Authenticator\AccessTokenAuthenticator`
and `App\Infrastructure\Symfony\Security\AccessTokenHandler`.
Since there is no user database, an _in-memory_ provider is used with a default admin user assigned the `ROLE_ADMIN`.
Authentication is managed via `Symfony\Component\Security\Http\Authenticator\AccessTokenAuthenticator` and
`App\Infrastructure\Symfony\Security\AccessTokenHandler`.

**Usage (send a cache invalidation request):**
**Usage Example: Sending a Cache Invalidation Request**

```shell
curl -H "Authorization: Bearer {{token}}" https://www.udfn.fr/webhook/cache-invalidation?tag[]=article
curl -H "Authorization: Bearer {{token}}" https://{host}/cache/invalidation?tag[]=article
```

> 3 bad login attempt will ban IP for 1 hour. (Configuration from SecurityBundle using RateLimiter component).
> See documentation : https://symfony.com/doc/current/security.html#limiting-login-attempts
> Note: After 3 failed login attempts, the IP address will be banned for 1 hour. This behavior is configured via the
> SecurityBundle’s RateLimiter component. For more details, refer to the Symfony documentation
> on [rate limiting](https://symfony.com/doc/current/security.html#limiting-login-attempts).
# CI/CD ‍🔄

Expand All @@ -164,5 +190,5 @@ folder.

Defined workflows :

- `quality.yaml` is the continuous integration workflow. It install and validate composer dependencies, then run quality
checks like PHPStan, ECS, Pest test suites and k6 load tests.
- `quality.yaml` defines the continuous integration workflow. It installs and validates Composer dependencies, then runs
quality checks, including PHPStan, ECS, PHPUnit tests, and SonarCloud analysis.

0 comments on commit fe33392

Please sign in to comment.