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(backend): Add progression system #45

Merged
merged 5 commits into from
Feb 20, 2023
Merged
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
91 changes: 0 additions & 91 deletions config/Migrations/20230215181736_AddPolls.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,6 @@ public function up(): void
]
)
->update();

$this->table('products')->drop()->save();

$this->table('purchases')->drop()->save();
}

/**
Expand Down Expand Up @@ -184,93 +180,6 @@ public function down(): void
->dropForeignKey(
'user_id'
)->save();
$this->table('products')
->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
->addColumn('description', 'text', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('image_link', 'string', [
'default' => null,
'limit' => 1024,
'null' => true,
])
->addColumn('price', 'integer', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('stock', 'integer', [
'default' => '0',
'limit' => null,
'null' => true,
])
->addColumn('created', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('modified', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->create();

$this->table('purchases')
->addColumn('user_id', 'char', [
'default' => null,
'limit' => 255,
'null' => false,
])
->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
->addColumn('description', 'text', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('image_link', 'string', [
'default' => null,
'limit' => 1024,
'null' => false,
])
->addColumn('price', 'integer', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('created', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->addIndex(
[
'user_id',
]
)
->create();

$this->table('purchases')
->addForeignKey(
'user_id',
'users',
'id',
[
'update' => 'NO_ACTION',
'delete' => 'NO_ACTION',
]
)
->update();

$this->table('poll_options')->drop()->save();
$this->table('poll_responses')->drop()->save();
Expand Down
87 changes: 87 additions & 0 deletions config/Migrations/20230220223740_AddProgression.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class AddProgression extends AbstractMigration
{
/**
* Up Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-up-method
* @return void
*/
public function up(): void
{
$this->table('progression')
->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => true,
])
->addColumn('sent_threshold', 'integer', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('received_threshold', 'integer', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('operator', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
->addColumn('created', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('modified', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->create();

$this->table('users')
->addColumn('progression_id', 'integer', [
'after' => 'id',
'default' => null,
'null' => true,
])
->update();

$this->table('users')
->addForeignKey(
'progression_id',
'progression',
'id',
[
'update' => 'NO_ACTION',
'delete' => 'NO_ACTION',
]
)
->update();
}

/**
* Down Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-down-method
* @return void
*/
public function down(): void
{
$this->table('users')
->dropForeignKey(
'progression_id'
)->save();

$this->table('progression')->drop()->save();
}
}
11 changes: 10 additions & 1 deletion frontend/src/views/Profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@
<div class="py-4">
<h2 class="text-lg font-medium leading-6">Your Potato Stats</h2>
<p class="mt-1 text-sm text-zinc-500">
You did gib <strong>{{ user.sent_count }}</strong> 🥔 and did receive <strong>{{ user.received_count }}</strong> 🥔 since you started potatoing
You did gib <strong>{{ user.sent_count ?? 0 }}</strong> 🥔 and did receive <strong>{{ user.received_count ?? 0 }}</strong> 🥔 since you started potatoing
<strong>{{ new Date(user.created).toLocaleDateString('en-us', { year:"numeric", month:"short", day:"numeric"}) }}.</strong>
</p>
<p
v-if="user.progression"
class="mt-1 text-sm text-zinc-500"
>
Your current potato level is
<span class="bg-purple-100 text-purple-800 text-sm font-medium ml-auto px-2.5 py-0.5 rounded dark:bg-purple-900 dark:text-purple-300">
Level {{ user.progression.id }} ({{ user.progression.name }})
</span>
</p>
</div>
<div class="py-4">
<h2 class="text-lg font-medium leading-6">Your activity in the last 30 days</h2>
Expand Down
72 changes: 72 additions & 0 deletions src/Command/ProgressionCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);

namespace App\Command;

use App\Model\Entity\User;
use App\Service\ProgressionService;
use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;

/**
* Progression command.
*/
class ProgressionCommand extends Command
{
/**
* Hook method for defining this command's option parser.
*
* @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
* @return \Cake\Console\ConsoleOptionParser The built parser.
*/
public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
{
$parser = parent::buildOptionParser($parser);

return $parser;
}

/**
* @param \Cake\Console\Arguments $args The command arguments.
* @param \Cake\Console\ConsoleIo $io The console io
* @return null|void|int The exit code or null for success
*/
public function execute(Arguments $args, ConsoleIo $io)
{
$io->out('Updating progression for all users');

$usersTable = $this->fetchTable('Users');
$users = $usersTable->find()
->where([
'Users.slack_is_bot' => false,
'Users.status' => User::STATUS_ACTIVE,
'Users.role !=' => User::ROLE_SERVICE,
])
->all();

$io->comment($users->count() . ' users will be updated');

/** @var \Cake\Command\Helper\ProgressHelper $progress */
$progress = $io->helper('Progress');
$progress->init([
'total' => $users->count(),
]);

$progressionService = new ProgressionService();

foreach ($users as $user) {
$progressionService->progress($user);

$progress->increment(1);
$progress->draw();

// Avoid getting rate limited by Slack
usleep(200 * 1000); // 200ms
}

$io->success("\n[DONE]");
}
}
1 change: 1 addition & 0 deletions src/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public function get(): Response
'received_count' => $reivedCountQuery,
])
->where(['Users.id' => $this->Authentication->getIdentityData('id')])
->contain('Progression')
->enableAutoFields(true)
->first();

Expand Down
14 changes: 14 additions & 0 deletions src/Event/AppHomeOpenedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ public function process(): void
'* :potato: since you started potatoing *' . $user->created->format('M j, Y') . '*.',
],
],
[
'type' => 'section',
'text' => [
'type' => 'mrkdwn',
'text' => (function () use ($user): string {
if ($user->progression === null) {
return 'Your current potato level is `Potato Novice`';
}

return 'Your current potato level is `Level ' . $user->progression->id . ' (' .
$user->progression->name . ')`';
})(),
],
],
[
'type' => 'divider',
],
Expand Down
36 changes: 36 additions & 0 deletions src/Model/Entity/Progression.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);

namespace App\Model\Entity;

use Cake\ORM\Entity;

/**
* Progression Entity
*
* @property int $id
* @property string|null $name
* @property int $sent_threshold
* @property int $received_threshold
* @property string $operator
* @property \Cake\I18n\FrozenTime|null $created
* @property \Cake\I18n\FrozenTime|null $modified
*/
class Progression extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array<string, bool>
*/
protected $_accessible = [
'*' => false,
];

public const OPERATOR_AND = 'AND';
public const OPERATOR_OR = 'OR';
}
1 change: 1 addition & 0 deletions src/Model/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* User Entity
*
* @property string $id
* @property int $progression_id
* @property string $status
* @property string $role
* @property string $slack_user_id
Expand Down
Loading