Skip to content

Commit

Permalink
Merge pull request #9 from deanblackborough/main
Browse files Browse the repository at this point in the history
Improved initial UX and Refactoring
  • Loading branch information
deanblackborough committed Oct 12, 2023
2 parents c3b80f9 + cbf7af0 commit 38ad545
Show file tree
Hide file tree
Showing 39 changed files with 2,342 additions and 1,881 deletions.
2 changes: 1 addition & 1 deletion .docker/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:8.1-apache
FROM php:8.2-apache

COPY . /var/www/html
COPY .docker/app/vhost.conf /etc/apache2/sites-available/000-default.conf
Expand Down
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

COMPOSE_PROJECT_NAME="yatzygamescorer"
COMPOSE_PROJECT_NAME="yatzygamescorer"
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

The complete changelog for the Costs to Expect REST API, our changelog follows the format defined at https://keepachangelog.com/en/1.0.0/

## [1.04.0] - [2023-10-12]
### Added
- Added full account deletion.
- Added a getting started section for new sign-ups, allows the user to create players and begin a game in one go.
### Changed
- Updated Yahtzee account deletion, uses the API to delete the account rather than brute force.
- Switched to action and view controllers.
- Automatically sign-in the user after password creation.
- Switched to the support@costs-to-expect.com email and removed Twitter from footer.
- Updated content throughout the app.
- Updated to Laravel 10
- Updated to Boostrap 5.3
- Updated to PHP8.2

## [v1.03.0] - [2023-07-03]
### Added
- Added Budget Pro to the footer
### Changed
- Updated the example ENV file
- Updated dependencies
- Set version and release date
### Fixed
- Corrected a link

## [1.02.0] - [2023-01-30]
### Changed
- Updated authentication to match recent changes to the Costs to Expect API.
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
![Score sheet](/resources/art/score-sheet.png)
[![Minimum PHP Version](https://img.shields.io/badge/php-^8.2-8892BF.svg)](https://php.net/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/costs-to-expect/yatzy/blob/main/LICENSE)
[![Laravel Forge Site Deployment Status](https://img.shields.io/endpoint?url=https%3A%2F%2Fforge.laravel.com%2Fsite-badges%2F13270108-d2e9-459a-9491-8cd34a122001&style=flat-square)](https://forge.laravel.com/servers/581137/sites/2028561)

# Yatzy Game Scoring

## Overview

Game scoring for Yatzy, powered by the Costs to Expect API.

![Score sheet](/resources/art/score-sheet.png)

## Other Apps

[Yahtzee](https://github.com/costs-to-expect/yahtzee)

We plan to create Apps for each of the Board and dice games we play, the Apps will all be Open Source, you
are free to create your own and then submit a PR to the Costs to Expect [API](https://github.com/costs-to-expect/api)
to add the new game type.
Expand All @@ -24,6 +30,12 @@ Go to the project root directory and run the below.
* $ `docker network create costs.network` *
* $ `docker compose build`
* $ `docker compose up`
* $ `docker exec yatzy.app php artisan key:generate`

After generating the key, you need to restart your containers, so run down and up again to force the new key to be used.

* $ `docker exec yatzy.app php artisan migrate:install`
* $ `docker exec yatzy.app php artisan migrate`

*We include a network for local development purposes, I need to connect to a local version of the Costs to Expect
API, You probably don't need this so remove the network section from your docker compose file and don't create the
Expand Down
27 changes: 27 additions & 0 deletions app/Actions/Account/DeleteAccount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);

namespace App\Actions\Account;

/**
* @author Dean Blackborough <dean@g3d-development.com>
* @copyright Dean Blackborough (Costs to Expect) 2018-2022
* https://github.com/costs-to-expect/yatzy/blob/main/LICENSE
*/
class DeleteAccount
{
public function __invoke(
string $bearer_token,
string $user_id,
string $email
): bool
{
\App\Jobs\DeleteAccount::dispatch(
$bearer_token,
$user_id,
$email
)->delay(now()->addSeconds(5));

return true;
}
}
119 changes: 119 additions & 0 deletions app/Actions/Game/Start.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);

namespace App\Actions\Game;

use App\Actions\Action;
use App\Api\Service;
use App\Models\ShareToken;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;

/**
* @author Dean Blackborough <dean@g3d-development.com>
* @copyright Dean Blackborough (Costs to Expect) 2018-2022
* https://github.com/costs-to-expect/yatzy/blob/main/LICENSE
*/
class Start extends Action
{
private array $players = [];

public function __invoke(Service $api, string $resource_type_id, string $resource_id, array $input): int
{
if (array_key_exists('players', $input) === false || $input['players'] === null || $input['players'] === '') {
$this->message = 'Missing players';
$this->validation_errors['players'] = ['errors' => ['Please enter the player names, one per line']];
return 422;
}

$players = explode(PHP_EOL, $input['players']);

if ($players === []) {
$this->message = 'Missing players';
$this->validation_errors['players'] = ['errors' => ['Please enter the player names, one per line']];
return 422;
}

foreach ($players as $player) {
$result = $this->createPlayer($api, $resource_type_id, $player);
if ($result === false && $this->validation_errors !== []) {
$this->message = 'Failed to create player';
$this->validation_errors['players'] = ['errors' => ['Failed to create player named "' . $player . '", is the a name taken by another player?']];
return 422;
}
}

$create_game_response = $api->createGame(
$resource_type_id,
$resource_id,
'Yatzy game',
'Yatzy game create via the Yatzy app'
);

if ($create_game_response['status'] === 201) {

$config = Config::get('app.config');

$this->game_id = $create_game_response['content']['id'];

foreach ($this->players as $player_id) {
$response = $api->addPlayerToGame(
$resource_type_id,
$resource_id,
$this->game_id,
$player_id
);

try {
$token = new ShareToken();
$token->token = Str::uuid();
$token->game_id = $this->game_id;
$token->player_id = $player_id;
$token->parameters = json_encode([
'resource_type_id' => $resource_type_id,
'resource_id' => $resource_id,
'game_id' => $this->game_id,
'player_id' => $player_id,
'player_name' => $response['content']['category']['name'],
'owner_bearer' => request()->cookie($config['cookie_bearer'])
], JSON_THROW_ON_ERROR);
$token->save();
} catch (\Exception) {
abort(500, 'Failed to create share token for player, create token manually');
}
}

return 201;
}

$this->message = $create_game_response['content'];

if ($create_game_response['status'] === 422) {
$this->validation_errors = $create_game_response['fields'];
return $create_game_response['status'];
}

return $create_game_response['status'];
}

protected function createPlayer($api, $resource_type_id, $player): bool
{
$create_player_response = $api->createPlayer(
$resource_type_id,
$player,
'New player - Added via the Yatzy App - Start'
);

if ($create_player_response['status'] === 422) {
$this->validation_errors = $create_player_response['fields'];
return false;
}

if ($create_player_response['status'] === 201) {
$this->players[] = $create_player_response['content']['id'];
return true;
}

return false;
}
}
33 changes: 21 additions & 12 deletions app/Api/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,17 +244,6 @@ public function deletePlayerScoreSheet(
return $this->http->delete($uri['uri']);
}

#[ArrayShape(['status' => "integer", 'content' => "array"])]
public function deleteResource(
string $resource_type_id,
string $resource_id
): array
{
$uri = Uri::resource($resource_type_id, $resource_id);

return $this->http->delete($uri['uri']);
}

#[ArrayShape(['status' => "integer", 'content' => "array"])]
public function getGame(
string $resource_type_id,
Expand Down Expand Up @@ -359,11 +348,31 @@ public function register(array $payload): array
$uri['uri'],
[
'name' => $payload['name'],
'email' => $payload['email']
'email' => $payload['email'],
'registered_via' => 'yatzy',
]
);
}

#[ArrayShape(['status' => "integer", 'content' => "array", 'fields' => "array"])]
public function requestResourceDelete(
string $resource_type_id,
string $resource_id
): array
{
$uri = Uri::requestResourceDelete($resource_type_id, $resource_id);

return $this->http->post($uri['uri'], []);
}

#[ArrayShape(['status' => "integer", 'content' => "array", 'fields' => "array"])]
public function requestAccountDelete(): array
{
$uri = Uri::requestAccountDelete();

return $this->http->post($uri['uri'], []);
}

#[ArrayShape(['status' => "integer", 'content' => "array", 'fields' => "array"])]
public function updateGame(
string $resource_type_id,
Expand Down
33 changes: 33 additions & 0 deletions app/Api/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,39 @@ public static function resource(string $resource_type_id, string $resource_id, a
];
}

#[ArrayShape(['uri' => "string", 'name' => "string"])]
public static function requestResourceDelete(
string $resource_type_id,
string $resource_id,
array $parameters = []
): array {
$uri = '/'.self::VERSION.'/auth/user/permitted-resource-types/'.
$resource_type_id.'/resources/' . $resource_id .'/request-delete';
if (count($parameters) > 0) {
$uri .= '?'.http_build_query($parameters);
}

return [
'uri' => $uri,
'name' => 'Request resource deletion',
];
}

#[ArrayShape(['uri' => "string", 'name' => "string"])]
public static function requestAccountDelete(
array $parameters = []
): array {
$uri = '/'.self::VERSION.'/auth/user/request-delete';
if (count($parameters) > 0) {
$uri .= '?'.http_build_query($parameters);
}

return [
'uri' => $uri,
'name' => 'Request account deletion',
];
}

#[ArrayShape(['uri' => "string", 'name' => "string"])]
public static function resources(string $resource_type_id, array $parameters = []): array
{
Expand Down
Loading

0 comments on commit 38ad545

Please sign in to comment.