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

Health check #308

Open
wants to merge 6 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
2 changes: 1 addition & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ jobs:
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Running static analysis
run: vendor/bin/phpstan analyse --memory-limit=2G
run: vendor/bin/phpstan analyse --level=1 --memory-limit=2G
4 changes: 0 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
FROM php:8.2-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
Expand Down Expand Up @@ -38,8 +36,6 @@ RUN useradd -G www-data,root -u 1000 -d /home/dev dev
RUN mkdir -p /home/dev/.composer && \
chown -R dev:dev /home/dev

USER $user

RUN echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/php.ini
RUN echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/php.ini
RUN echo "xdebug.idekey=PHPSTORM" >> /usr/local/etc/php/conf.d/php.ini
Expand Down
33 changes: 15 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ docker_push_image:
@docker push fokosun/cookbookshq-api:v1

db_seed: ## seed the database
@php artisan db:seed
@docker-compose exec app php artisan db:seed

db_migrate: ## run db migrations
@php artisan migrate
@docker-compose exec app php artisan migrate

db_schemefy: ## Display the db schema in table format
@php artisan schema:show
@docker-compose exec app php artisan schema:show

setup: composer generate_key jwt_key db_connection

Expand All @@ -53,16 +53,16 @@ db_connection: ## Generate DB Connection details and set in .env
@docker-compose exec app php artisan db:connection

login: ## Creates a new user/token or generate new token for given user
@php artisan auth:token
@docker-compose exec app php artisan auth:token

test_unit: ## Run unit testsuite
@php vendor/bin/phpunit --testsuite=Unit
@docker-compose exec app php vendor/bin/phpunit --testsuite=Unit

test_feature: ## Run Feature tests
@php vendor/bin/phpunit --testsuite=Feature
@docker-compose exec app php vendor/bin/phpunit --testsuite=Feature

test: ## Run the entire test suites
@php vendor/bin/phpunit tests/
@docker-compose exec app php vendor/bin/phpunit tests/

shell_app: ## ssh into the app container
@docker-compose exec app /bin/bash
Expand All @@ -73,30 +73,27 @@ shell_db: ## ssh into the database container
clear: clear_cache clear_views clear_routes dump_autoload

clear_cache:
@php artisan cache:clear
@docker-compose exec app php artisan cache:clear

clear_views:
@php artisan view:clear
@docker-compose exec app php artisan view:clear

clear_routes:
@php artisan route:clear
@docker-compose exec app php artisan route:clear

dump_autoload: ## Composer dumpautoload
@composer dumpautoload
@docker-compose exec app composer dumpautoload

up: ## Restarts and provisions the containers in the background
@docker-compose up -d

docker_prune: prune_images prune_volumes prune_containers
docker_prune: prune_volumes prune_images

prune_images: ## Remove dangling images and free up space
@docker image prune

prune_containers: ## Remove the containers
@docker container prune
@docker image rm api-app mariadb nginx redis

prune_volumes: ## Removes dangling volumes
@docker volume prune
@docker volume rm api_mysqldata api_cache

static_analysis:
@php ./vendor/bin/phpstan analyse --memory-limit=2G
@docker-compose exec app php ./vendor/bin/phpstan analyse --memory-limit=2G
8 changes: 8 additions & 0 deletions app/Dtos/Contracts/isReadOnly.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Dtos\Contracts;

interface isReadOnly
{
public function toArray(): array;
}
34 changes: 34 additions & 0 deletions app/Dtos/HealthChecksDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace App\Dtos;

use App\Dtos\Contracts\isReadOnly;

readonly class HealthChecksDto implements isReadOnly
{
public function __construct(
private string $name,
private array $meta,
private string $status,
private string $notificationMessage,
private string $shortSummary
) {}

public function get(string|array $property): string|array|null
{
return $this->$property ?? null;
}

public function toArray(): array
{
return [
'name' => $this->name,
'meta' => $this->meta,
'status' => $this->status,
'notificationMessage' => $this->notificationMessage,
'shortSummary' => $this->shortSummary
];
}
}
4 changes: 3 additions & 1 deletion app/Dtos/TikTokUserDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace App\Dtos {

readonly class TikTokUserDto
use App\Dtos\Contracts\isReadOnly;

readonly class TikTokUserDto implements isReadOnly
{
public int $user_id;
public string $open_id;
Expand Down
2 changes: 0 additions & 2 deletions app/Http/Controllers/CommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
{
public function addComment(Request $request)
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 19 in app/Http/Controllers/CommentController.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$payload = $request->only([
'resource-type', 'resource-id', 'comment'
]);
Expand Down Expand Up @@ -49,8 +48,7 @@

public function destroyComment(Request $request)
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 51 in app/Http/Controllers/CommentController.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$payload = $request->only(['comment-id']);
$comment = Comment::findOrFail($request->only(['comment-id']))->first();

Expand Down
77 changes: 77 additions & 0 deletions app/Http/Controllers/HealthCheckController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Http\Controllers;

use App\Dtos\HealthChecksDto;
use Illuminate\Http\JsonResponse;
use Spatie\CpuLoadHealthCheck\CpuLoadCheck;
use Spatie\Health\Checks\Checks\UsedDiskSpaceCheck;
use Spatie\Health\Checks\Result;
use Spatie\Health\Health;
use Spatie\Health\Checks\Checks\DatabaseCheck;
use Spatie\Health\Checks\Checks\EnvironmentCheck;

class HealthCheckController extends Controller
{
private Health $healthChecker;

/**
* @class HealthCheckerController
*/
public function __construct(Health $healthChecker)
{
$this->healthChecker = $healthChecker;
}

/**
* CookbooksHQ Health status checks
*
* @return \Illuminate\Http\JsonResponse
*/
public function check(): JsonResponse
{
$this->registerChecks();

return $this->successResponse(
array_map(function ($check) {
return $this->newHealthStatusDto($check->run(), $check->getName())->toArray();
}, $this->healthChecker->registeredChecks()->toArray())
);
}

/**
* @return void
*/
private function registerChecks(): void
{
$this->healthChecker->checks(
[
EnvironmentCheck::new()->expectEnvironment(getenv('APP_ENV')),
UsedDiskSpaceCheck::new()
->warnWhenUsedSpaceIsAbovePercentage(70)
->failWhenUsedSpaceIsAbovePercentage(90),
CpuLoadCheck::new()
->failWhenLoadIsHigherInTheLast5Minutes(2.0)
->failWhenLoadIsHigherInTheLast15Minutes(1.5),
DatabaseCheck::new()
->connectionName(getenv('DB_CONNECTION'))
]
);
}

/**
* @param Result $healthStatusResult
* @param string $checkName
* @return HealthChecksDto
*/
private function newHealthStatusDto(Result $healthStatusResult, string $checkName): HealthChecksDto
{
return new HealthChecksDto(
$checkName,
$healthStatusResult->meta,
$healthStatusResult->status->value,
$healthStatusResult->notificationMessage,
$healthStatusResult->shortSummary
);
}
}
1 change: 0 additions & 1 deletion app/Http/Controllers/RecipeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ public function addClap(Request $request): JsonResponse
);

return ($recipe = $this->service->addClap($request->get('recipe_id'))) ?
/** @phpstan-ignore-next-line */
$this->successResponse(['updated' => true, 'claps' => $recipe->claps]) :
$this->errorResponse(['error' => 'There was an error processing this request. Please try again.']);
}
Expand Down
3 changes: 0 additions & 3 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@

public function followUser(Request $request)
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 83 in app/Http/Controllers/UserController.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
if ($toFollow = $request->get('toFollow')) {
$userToFollow = $this->service->findWhere($toFollow)->first();

Expand Down Expand Up @@ -146,8 +145,7 @@

public function addFeedback(Request $request)
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 148 in app/Http/Controllers/UserController.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$hasRespondedAlready = UserFeedback::where(['user_id' => $user->getKey(), 'type' => 'feedback']);

if (collect($hasRespondedAlready->pluck('response')->toArray())->isEmpty()) {
Expand All @@ -172,8 +170,7 @@

public function listVideos(HttpRequestRunner $requestRunner)
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 173 in app/Http/Controllers/UserController.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$tikTokUser = $user->getTikTokUser();
$errors = [
'videos_count' => 0,
Expand Down
2 changes: 0 additions & 2 deletions app/Http/Middleware/JWTAuthGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
public function handle(Request $request, Closure $next)
{
try {
/** @phpstan-ignore-next-line */
if (JWTAuth::parseToken()->authenticate()) {

Check failure on line 20 in app/Http/Middleware/JWTAuthGuard.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().

/** @phpstan-ignore-next-line */
$request->merge(["user_id" => JWTAuth::parseToken()->user()->getKey()]);

Check failure on line 22 in app/Http/Middleware/JWTAuthGuard.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().

return $next($request);
}
Expand Down
24 changes: 22 additions & 2 deletions app/Interfaces/serviceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,33 @@

interface serviceInterface
{
/**
* @return mixed
*/
public function index();

public function show($option);
/**
* @param string|int $option
* @return mixed
*/
public function show(string|int $option);

/**
* @param Request $request
* @return mixed
*/
public function store(Request $request);

/**
* @param Request $request
* @param string $option
* @return mixed
*/
public function update(Request $request, string $option);

public function findWhere($q);
/**
* @param string|int $q
* @return mixed
*/
public function findWhere(string|int $q);
}
3 changes: 0 additions & 3 deletions app/Services/CookbookService.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,12 @@ public function store(Request $request): bool
}
}

/** @phpstan-ignore-next-line */
$cookbook->slug = DbHelper::generateUniqueSlug($request->name, 'cookbooks', 'slug');

if ($cookbook->save()) {
/** @phpstan-ignore-next-line */
$cookbook->users()->attach($cookbook->user_id);

foreach ($categories as $category) {
/** @phpstan-ignore-next-line */
$cookbook->categories()->attach($category);
}

Expand Down
5 changes: 0 additions & 5 deletions app/Services/SearchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
}
}

/** @phpstan-ignore-next-line */
$result->metaData = [
'contains' => $contains,
'missing' => $missing
Expand Down Expand Up @@ -166,7 +165,6 @@
}
}

/** @phpstan-ignore-next-line */
$result->metaData = [
'contains' => $contains,
'missing' => $missing
Expand Down Expand Up @@ -244,8 +242,7 @@
*/
public function getAllCookbooksByMe($cookbookName = "")
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 245 in app/Services/SearchService.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$me = $user->getKey();

$myOtherContributions = CookbookUser::whereIn("user_id", [$me])->get()->pluck("cookbook_id")->toArray();
Expand All @@ -269,8 +266,7 @@
*/
public function getAllRecipesByMe($recipeName = "")
{
/** @phpstan-ignore-next-line */
if ($user = JWTAuth::parseToken()->user()) {

Check failure on line 269 in app/Services/SearchService.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$me = $user->getKey();

if ($recipeName == "") {
Expand All @@ -285,8 +281,7 @@

public function getFollowing()
{
/** @phpstan-ignore-next-line */
if ($me = JWTAuth::parseToken()->user()) {

Check failure on line 284 in app/Services/SearchService.php

View workflow job for this annotation

GitHub Actions / php-cs

Call to an undefined static method Tymon\JWTAuth\Facades\JWTAuth::parseToken().
$recipes = [];
$following = Following::where(['follower_id' => $me->getKey()])->pluck('following')->toArray();

Expand Down
Loading
Loading