From fe5355d18255676c657363f264eb7caf4b2bbc4a Mon Sep 17 00:00:00 2001 From: myrmidex Date: Thu, 19 Mar 2026 21:14:36 +0100 Subject: [PATCH] 4 - Add BucketTypeEnum and update Bucket model, migration, factory, and resource --- app/Enums/BucketTypeEnum.php | 24 ++++++++++ app/Http/Resources/BucketResource.php | 2 + app/Models/Bucket.php | 4 ++ database/factories/BucketFactory.php | 45 ++++++++++++++++++- ...2025_12_29_205724_create_buckets_table.php | 2 + tests/Unit/Enums/BucketTypeEnumTest.php | 33 ++++++++++++++ 6 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 app/Enums/BucketTypeEnum.php create mode 100644 tests/Unit/Enums/BucketTypeEnumTest.php diff --git a/app/Enums/BucketTypeEnum.php b/app/Enums/BucketTypeEnum.php new file mode 100644 index 0000000..d7bcc84 --- /dev/null +++ b/app/Enums/BucketTypeEnum.php @@ -0,0 +1,24 @@ + 'Need', + self::WANT => 'Want', + self::OVERFLOW => 'Overflow', + }; + } + + public static function values(): array + { + return array_column(self::cases(), 'value'); + } +} diff --git a/app/Http/Resources/BucketResource.php b/app/Http/Resources/BucketResource.php index 1545180..841d94f 100644 --- a/app/Http/Resources/BucketResource.php +++ b/app/Http/Resources/BucketResource.php @@ -12,6 +12,8 @@ public function toArray(Request $request): array return [ 'id' => $this->uuid, 'name' => $this->name, + 'type' => $this->type, + 'type_label' => $this->type->getLabel(), 'priority' => $this->priority, 'sort_order' => $this->sort_order, 'allocation_type' => $this->allocation_type, diff --git a/app/Models/Bucket.php b/app/Models/Bucket.php index 08ee63d..fadb215 100644 --- a/app/Models/Bucket.php +++ b/app/Models/Bucket.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\BucketAllocationTypeEnum; +use App\Enums\BucketTypeEnum; use App\Models\Traits\HasUuid; use Database\Factories\BucketFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -14,6 +15,7 @@ * @property int $id * @property string $uuid * @property int $scenario_id + * @property BucketTypeEnum $type * @property Scenario $scenario * @property string $name * @property int $priority @@ -31,6 +33,7 @@ class Bucket extends Model protected $fillable = [ 'scenario_id', 'name', + 'type', 'priority', 'sort_order', 'allocation_type', @@ -39,6 +42,7 @@ class Bucket extends Model ]; protected $casts = [ + 'type' => BucketTypeEnum::class, 'priority' => 'integer', 'sort_order' => 'integer', 'allocation_value' => 'decimal:2', diff --git a/database/factories/BucketFactory.php b/database/factories/BucketFactory.php index ceb77ec..93821ab 100644 --- a/database/factories/BucketFactory.php +++ b/database/factories/BucketFactory.php @@ -3,6 +3,7 @@ namespace Database\Factories; use App\Enums\BucketAllocationTypeEnum; +use App\Enums\BucketTypeEnum; use App\Models\Bucket; use App\Models\Scenario; use Illuminate\Database\Eloquent\Factories\Factory; @@ -22,6 +23,11 @@ public function definition(): array return [ 'scenario_id' => Scenario::factory(), + // Overflow excluded — use ->overflow() state modifier + 'type' => $this->faker->randomElement([ + BucketTypeEnum::NEED, + BucketTypeEnum::WANT, + ]), 'name' => $this->faker->randomElement([ 'Monthly Expenses', 'Emergency Fund', @@ -82,13 +88,46 @@ public function unlimited(): Factory } /** - * Create default buckets set (Monthly Expenses, Emergency Fund, Investments). + * Create a need bucket. + */ + public function need(): Factory + { + return $this->state([ + 'type' => BucketTypeEnum::NEED, + ]); + } + + /** + * Create a want bucket. + */ + public function want(): Factory + { + return $this->state([ + 'type' => BucketTypeEnum::WANT, + ]); + } + + /** + * Create an overflow bucket. + */ + public function overflow(): Factory + { + return $this->state([ + 'type' => BucketTypeEnum::OVERFLOW, + 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, + 'allocation_value' => null, + ]); + } + + /** + * Create default buckets set (Monthly Expenses, Emergency Fund, Overflow). */ public function defaultSet(): array { return [ $this->state([ 'name' => 'Monthly Expenses', + 'type' => BucketTypeEnum::NEED, 'priority' => 1, 'sort_order' => 1, 'allocation_type' => BucketAllocationTypeEnum::FIXED_LIMIT, @@ -97,6 +136,7 @@ public function defaultSet(): array ]), $this->state([ 'name' => 'Emergency Fund', + 'type' => BucketTypeEnum::NEED, 'priority' => 2, 'sort_order' => 2, 'allocation_type' => BucketAllocationTypeEnum::FIXED_LIMIT, @@ -104,7 +144,8 @@ public function defaultSet(): array 'starting_amount' => 0, ]), $this->state([ - 'name' => 'Investments', + 'name' => 'Overflow', + 'type' => BucketTypeEnum::OVERFLOW, 'priority' => 3, 'sort_order' => 3, 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, diff --git a/database/migrations/2025_12_29_205724_create_buckets_table.php b/database/migrations/2025_12_29_205724_create_buckets_table.php index 159c7f5..0c90e85 100644 --- a/database/migrations/2025_12_29_205724_create_buckets_table.php +++ b/database/migrations/2025_12_29_205724_create_buckets_table.php @@ -1,5 +1,6 @@ id(); $table->uuid('uuid')->unique(); $table->foreignId('scenario_id')->constrained()->onDelete('cascade'); + $table->enum('type', BucketTypeEnum::values())->default(BucketTypeEnum::NEED->value); $table->string('name'); $table->integer('priority')->comment('Lower number = higher priority, 1 = first'); $table->integer('sort_order')->default(0)->comment('For UI display ordering'); diff --git a/tests/Unit/Enums/BucketTypeEnumTest.php b/tests/Unit/Enums/BucketTypeEnumTest.php new file mode 100644 index 0000000..a777808 --- /dev/null +++ b/tests/Unit/Enums/BucketTypeEnumTest.php @@ -0,0 +1,33 @@ +assertEquals('need', BucketTypeEnum::NEED->value); + $this->assertEquals('want', BucketTypeEnum::WANT->value); + $this->assertEquals('overflow', BucketTypeEnum::OVERFLOW->value); + } + + public function test_has_correct_labels(): void + { + $this->assertEquals('Need', BucketTypeEnum::NEED->getLabel()); + $this->assertEquals('Want', BucketTypeEnum::WANT->getLabel()); + $this->assertEquals('Overflow', BucketTypeEnum::OVERFLOW->getLabel()); + } + + public function test_values_returns_all_string_values(): void + { + $values = BucketTypeEnum::values(); + + $this->assertCount(3, $values); + $this->assertContains('need', $values); + $this->assertContains('want', $values); + $this->assertContains('overflow', $values); + } +}