Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: add sample structure for project #61

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,16 @@ DEPLOYER_SENTRY_TOKEN=50b88fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEPLOYER_SENTRY_ORG=wayofdev
DEPLOYER_SENTRY_PROJECT=laravel-cycle-starter-tpl
DEPLOYER_SENTRY_SERVER=https://wayofdev.sentry.io

#######################################
# Authentication
#######################################
AUTH0_ADMIN_DOMAIN=dev-xxx.us.auth0.com
AUTH0_ADMIN_CLIENT_ID=XXX
AUTH0_ADMIN_CLIENT_SECRET=XXX
AUTH0_ADMIN_AUDIENCE=http://api.prod.xxx.io/api/admin

AUTH0_PUBLIC_DOMAIN=dev-xxx.us.auth0.com
AUTH0_PUBLIC_CLIENT_ID=YYY
AUTH0_PUBLIC_CLIENT_SECRET=YYY
AUTH0_PUBLIC_AUDIENCE=http://api.prod.xxx.io/api/public
20 changes: 14 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
fail-fast: true
matrix:
os: ["ubuntu-22.04"]
php: ["8.1", "8.2"]
php: ["8.2"]

steps:
- name: 📦 Check out the codebase
Expand All @@ -29,7 +29,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, fileinfo, xdebug
extensions: curl, mbstring, zip, fileinfo, xdebug, decimal
ini-values: error_reporting=E_ALL
tools: composer:v2
coverage: xdebug
Expand All @@ -46,6 +46,13 @@ jobs:
path: vendor
key: vendor-${{ runner.os }}-${{ hashFiles('**/composer.lock') }}-${{ matrix.php }}

- name: ♻️ Restore cached .build directory
id: cached-build-dir
uses: actions/cache@v3
with:
path: .build
key: build-${{ runner.os }}-${{ hashFiles('**/composer.lock') }}-${{ matrix.php }}

- name: 📥 Install backend dependencies
if: steps.cached-composer-dependencies.outputs.cache-hit != 'true'
run: composer install
Expand All @@ -70,15 +77,16 @@ jobs:
run: php artisan storage:link

- name: 🔍 Run coding standards task
run: |
composer run cs:diff
run: composer run cs:diff

- name: 🔍 Run static analysis using phpstan
run: |
composer run stan
run: composer run stan
env:
PHPSTAN_OUTPUT_FORMAT: github

- name: 🔍 Run dependency tracking analysis using deptrac
run: composer run deptrac:ci

- name: 🧪 Execute phpunit and pest tests
run: |
composer run test:cc
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fail-fast: true
matrix:
os: ["ubuntu-22.04"]
php: ["8.1"]
php: ["8.2"]
environment:
name: production
url: https://prod.laravel-cycle-starter-tpl.wayof.dev
Expand All @@ -29,7 +29,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, fileinfo
extensions: curl, libxml, mbstring, zip, fileinfo, decimal
ini-values: error_reporting=E_ALL
tools: composer:v2

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fail-fast: true
matrix:
os: ["ubuntu-22.04"]
php: ["8.1"]
php: ["8.2"]
environment:
name: staging
url: https://staging.laravel-cycle-starter-tpl.wayof.dev
Expand All @@ -29,7 +29,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, fileinfo
extensions: curl, libxml, mbstring, zip, fileinfo, decimal
ini-values: error_reporting=E_ALL
tools: composer:v2

Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-added-large-files
args: ['--maxkb=2048']
- id: fix-encoding-pragma

- repo: https://github.com/commitizen-tools/commitizen
Expand Down
39 changes: 39 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ lint-stan:
$(APP_COMPOSER) run-script stan
.PHONY: lint-stan

lint-deps:
$(APP_COMPOSER) run-script deptrac
.PHONY: lint-deps

test: ## Run project php-unit and pest tests
$(APP_COMPOSER) test
.PHONY: test
Expand All @@ -186,6 +190,14 @@ test-cc: ## Run project php-unit and pest tests in coverage mode and build repor
$(APP_COMPOSER) test:cc
.PHONY: test-cc

api-docs-public: ## Generate openapi docs specification file for public api
$(APP_EXEC) php artisan open-docs:generate public
.PHONY: api-docs-public

api-docs-admin: ## Generate openapi docs specification file for admin api
$(APP_EXEC) php artisan open-docs:generate admin
.PHONY: api-docs-admin


# Composer Commands
# ------------------------------------------------------------------------------------
Expand All @@ -197,11 +209,38 @@ update: ## Update composer dependencies
$(APP_COMPOSER) update $(package)
.PHONY: update

du: ## Dump composer autoload
$(APP_COMPOSER) dump-autoload
.PHONY: du

show: ## Shows information about installed composer packages
$(APP_COMPOSER) show
.PHONY: show


# Database Commands
# ------------------------------------------------------------------------------------
db-wipe: ## Wipe database
$(APP_EXEC) php artisan db:wipe
.PHONY: db-wipe

db-refresh: ## Delete migration files, wipe database, create new migrations, run them and seed database
rm ./app/database/migrations/cycle/* || true
$(APP_EXEC) php artisan cache:clear
$(APP_EXEC) php artisan db:wipe
$(APP_EXEC) php artisan cycle:orm:migrate
$(APP_EXEC) php artisan cycle:migrate
$(APP_EXEC) php artisan db:seed -vvv
.PHONY: db-refresh


# Authentication Commands
# ------------------------------------------------------------------------------------
auth0-get: ## Install auth0 cli
$(APP_EXEC) curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh -s -- -b .
.PHONY: auth0-get


# Deployer Commands
# ------------------------------------------------------------------------------------
dep-staging:
Expand Down
93 changes: 91 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<br>

# Laravel Starter Template
# Laravel Cycle ORM Starter Template

This is an **opinionated** modified version of the Laravel framework which aims at providing a Domain-Driven Design (DDD) structure and using [CycleORM](https://cycle-orm.dev) instead of Eloquent.

Expand Down Expand Up @@ -157,12 +157,13 @@ Useful resources about Laravel and DDD approach:

* [Laravel Beyond CRUD](https://spatie.be/products/laravel-beyond-crud)
* [Laravel Skeleton](https://romanzipp.github.io/Laravel-Skeleton/) by [romanzipp](https://github.com/romanzipp)
* [Using Deptrac to maintain code quality](https://getparthenon.com/blog/using-deptrac-to-maintain-code-quality/)

<br>

## 🙆🏼‍♂️ Author Information

This repository was created in **2022** by [lotyp / wayofdev](https://github.com/wayofdev).
This repository was created in **2023** by [lotyp / wayofdev](https://github.com/wayofdev).

<br>

Expand All @@ -177,3 +178,91 @@ We are open to all kinds of contributions. If you want to:
- 👨‍💻 Contribute to the code

<br>

## 🧰 Project Architecture

This project uses Domain-Driven Design (DDD) principles and is structured into four main layers: Domain, Application, Bridge, and Infrastructure. Each layer has specific responsibilities and dependencies, as described below.

### → Layers

* **Domain:**

The Domain layer is the core of our business software, and it encapsulates the business rules. This involves entities, value objects, aggregates, events, and domain services.

<ins>The Domain layer does not depend on any other layer</ins>, thereby preserving the integrity and independence of the business logic.

* **Application:**

The Application layer orchestrates the coordination of domain objects to perform specific use cases of our application. This includes things like application services and command/query handlers.

This layer depends on the Domain layer for business rules and the Infrastructure layer for technical capabilities.

* **Bridge:**

The Bridge layer is the adapter that allows our application to interact with the outside world. It uses Laravel to route HTTP requests or console commands to the corresponding Application layer use case.

This layer depends on the Application layer, Domain layer, and Infrastructure layer. It uses the Application layer to orchestrate operations, the Domain layer for domain knowledge, and the Infrastructure layer for technical capabilities.

* **Infrastructure:**

The Infrastructure layer provides generic technical capabilities to support the higher layers. This includes things like database access, file system access, and other technical concerns.

This layer can depend on the Domain layer, meaning it can use domain entities, value objects, or services when implementing its technical concerns.

For more information check [deptrac.yaml](https://github.com/wayofdev/laravel-cycle-starter-tpl/blob/develop/app/deptrac.yaml) located in repository `app` folder.

### → Architecture Rules

These layer dependencies are enforced using the Deptrac tool, which checks the codebase for violations of our architecture rules. The rules are defined in the [deptrac.yaml](https://github.com/wayofdev/laravel-cycle-starter-tpl/blob/develop/app/deptrac.yaml) file and specify that:

- The **Domain** layer **does not** depend on any other layer.
- The **Application** layer **depends** on the **Domain** and **Infrastructure** layers.
- The **Bridge** layer depends on the **Domain**, **Application**, and **Infrastructure** layers.
- The **Infrastructure** layer depends on the **Domain** layer.

By adhering to these rules, we can ensure a clean separation of concerns in our application, with the business logic (Domain) kept separate from use case orchestration (Application), communication with the outside world (Bridge), and technical concerns (Infrastructure).

### → Dependency Tracking using Deptrac

We use Deptrac to enforce a clean architecture within our codebase. Deptrac helps us adhere to the principles of layered architecture by defining and checking rules that describe which parts of our code can depend on others.

Deptrac operates on the level of PHP classes, analyzing the dependencies between them and comparing them to the architecture rules defined in [deptrac.yaml](https://github.com/wayofdev/laravel-cycle-starter-tpl/blob/develop/app/deptrac.yaml). If a class has a dependency that violates these rules, Deptrac will alert us.

Using Deptrac allows us to ensure a clean separation of concerns in our codebase, making it easier to understand, test, and maintain.

* To generate images from deptrac dependency `graphviz` needs to be installed on your system:

```bash
$ brew install graphviz
```

* Running deptrac

To run Deptrac and check for violations of our architecture rules, you can use one of the following commands:

```bash
$ make lint-deps
```

or navigate to the repository's app directory and execute:

```bash
$ cd app
$ composer deptrac
```

This will run Deptrac and report any violations in the console output.

To create a visual graph of our dependencies, you can run:

```bash
$ composer deptrac:gv
```

This command will generate an image in the `assets` directory.

### → Architecture Diagram

![Architecture Diagram](assets/deptrac.svg)

<br>
4 changes: 2 additions & 2 deletions app/bootstrap/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@

$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
Laravel\Http\Kernel::class
Laravel\HttpKernel::class
);

$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
Laravel\Console\Kernel::class
Laravel\ConsoleKernel::class
);

$app->singleton(
Expand Down
57 changes: 38 additions & 19 deletions app/composer.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,48 @@
{
"name": "laravel/laravel",
"name": "wayofdev/laravel-cycle-starter-tpl",
"type": "project",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"description": "Laravel backend application template for building APIs with CycleORM support.",
"keywords": ["php", "boilerplate", "laravel", "cycle", "cycleorm", "api", "backend", "starter", "template"],
"license": "MIT",
"require": {
"php": "^8.2",
"ext-pdo": "*",
"php": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.8",
"laravel/tinker": "^2.8",
"sentry/sentry-laravel": "^3.3",
"auth0/login": "^7.9",
"beberlei/assert": "^3.3",
"cycle/annotated": "^3.3",
"deployer/deployer": "^7.3",
"wayofdev/laravel-cycle-orm-adapter": "*"
"eventsauce/eventsauce": "^3.4",
"guzzlehttp/guzzle": "^7.7",
"laravel/framework": "^10.14",
"laravel/tinker": "^2.8",
"lcobucci/clock": "^3.1",
"ramsey/uuid": "^4.7",
"sentry/sentry-laravel": "^3.6",
"spatie/laravel-route-attributes": "^1.18",
"wayofdev/laravel-cycle-orm-adapter": "*",
"wayofdev/laravel-cycle-orm-event-sourcing": "^1.2",
"wayofdev/laravel-open-docs": "^2.0",
"wayofdev/laravel-paginator": "^1.2",
"wayofdev/laravel-request-query-builder": "^1.3",
"wayofdev/laravel-symfony-serializer": "^1.1",
"zircote/swagger-php": "^4.7"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.31",
"fakerphp/faker": "^1.9.1",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^7.0",
"fakerphp/faker": "^1.23",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^7.7",
"nunomaduro/larastan": "^2.6",
"pestphp/pest-plugin-laravel": "^2.0",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpunit/phpunit": "^10.1",
"phpunit/phpunit": "^10.2",
"qossmic/deptrac-shim": "^1.0",
"rinvex/countries": "^9.0",
"roave/security-advisories": "dev-latest",
"spatie/laravel-ignition": "^2.0",
"wayofdev/cs-fixer-config": "^1.2"
"spatie/laravel-ignition": "^2.2",
"wayofdev/cs-fixer-config": "^1.2",
"wayofdev/laravel-cycle-orm-factories": "^1.1"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -59,9 +75,12 @@
],
"cs:fix": "php vendor/bin/php-cs-fixer fix -v",
"cs:diff": "php vendor/bin/php-cs-fixer fix --dry-run -v --diff",
"test": "php vendor/bin/pest",
"test:cc": "XDEBUG_MODE=coverage php vendor/bin/pest --coverage-clover coverage.xml",
"stan": "php vendor/bin/phpstan analyse --memory-limit=2G"
"test": "php vendor/bin/pest --colors=always",
"test:cc": "XDEBUG_MODE=coverage php vendor/bin/pest --colors=always --coverage-clover coverage.xml",
"stan": "php vendor/bin/phpstan analyse --memory-limit=2G",
"deptrac": "php vendor/bin/deptrac analyse --config-file=deptrac.yaml -v --cache-file=.build/.deptrac.cache",
"deptrac:ci": "php vendor/bin/deptrac analyse --config-file=deptrac.yaml -v --cache-file=.build/.deptrac.cache --formatter github-actions",
"deptrac:gv": "php vendor/bin/deptrac analyse --config-file=deptrac.yaml -v --cache-file=.build/.deptrac.cache --formatter graphviz-image --output ../assets/deptrac.svg"
},
"extra": {
"laravel": {
Expand All @@ -83,6 +102,6 @@
"phpstan/extension-installer": true
}
},
"minimum-stability": "stable",
"minimum-stability": "dev",
"prefer-stable": true
}
Loading