refactor: align codebase with EventCrew domain and trim legacy band stack

- Update API: events, users, policies, routes, resources, migrations
- Remove deprecated models/resources (customers, setlists, invitations, etc.)
- Refresh admin app and docs; remove apps/band

Made-with: Cursor
This commit is contained in:
2026-03-29 23:19:06 +02:00
parent 34e12e00b3
commit 1cb7674d52
1034 changed files with 7453 additions and 8743 deletions

View File

@@ -1,57 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\Customer;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Customer>
*/
final class CustomerFactory extends Factory
{
protected $model = Customer::class;
public function definition(): array
{
$type = fake()->randomElement(['individual', 'company']);
return [
'name' => fake()->name(),
'company_name' => $type === 'company' ? fake()->company() : null,
'type' => $type,
'email' => fake()->optional()->safeEmail(),
'phone' => fake()->optional()->phoneNumber(),
'address' => fake()->optional()->streetAddress(),
'city' => fake()->optional()->city(),
'postal_code' => fake()->optional()->postcode(),
'country' => 'NL',
'notes' => fake()->optional()->paragraph(),
'is_portal_enabled' => fake()->boolean(20),
];
}
public function individual(): static
{
return $this->state(fn () => [
'type' => 'individual',
'company_name' => null,
]);
}
public function company(): static
{
return $this->state(fn () => [
'type' => 'company',
'company_name' => fake()->company(),
]);
}
public function withPortal(): static
{
return $this->state(fn () => ['is_portal_enabled' => true]);
}
}

View File

@@ -4,100 +4,32 @@ declare(strict_types=1);
namespace Database\Factories;
use App\Enums\EventStatus;
use App\Enums\EventVisibility;
use App\Models\Customer;
use App\Models\Event;
use App\Models\Location;
use App\Models\User;
use App\Models\Organisation;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Event>
*/
/** @extends Factory<Event> */
final class EventFactory extends Factory
{
protected $model = Event::class;
/** @return array<string, mixed> */
public function definition(): array
{
$startTime = fake()->time('H:i');
$endTime = fake()->optional()->time('H:i');
$name = fake()->unique()->words(3, true);
$startDate = fake()->dateTimeBetween('+1 week', '+3 months');
return [
'title' => fake()->sentence(3),
'description' => fake()->optional()->paragraph(),
'event_date' => fake()->dateTimeBetween('+1 week', '+6 months'),
'start_time' => $startTime,
'end_time' => $endTime,
'fee' => fake()->optional()->randomFloat(2, 100, 5000),
'currency' => 'EUR',
'status' => fake()->randomElement(EventStatus::cases()),
'visibility' => EventVisibility::Members,
'notes' => fake()->optional()->paragraph(),
'created_by' => User::factory(),
'organisation_id' => Organisation::factory(),
'name' => ucfirst($name),
'slug' => str($name)->slug()->toString(),
'start_date' => $startDate,
'end_date' => fake()->dateTimeBetween($startDate, (clone $startDate)->modify('+3 days')),
'timezone' => 'Europe/Amsterdam',
'status' => 'draft',
];
}
public function draft(): static
public function published(): static
{
return $this->state(fn () => ['status' => EventStatus::Draft]);
}
public function pending(): static
{
return $this->state(fn () => ['status' => EventStatus::Pending]);
}
public function confirmed(): static
{
return $this->state(fn () => ['status' => EventStatus::Confirmed]);
}
public function completed(): static
{
return $this->state(fn () => ['status' => EventStatus::Completed]);
}
public function cancelled(): static
{
return $this->state(fn () => ['status' => EventStatus::Cancelled]);
}
public function withLocation(): static
{
return $this->state(fn () => ['location_id' => Location::factory()]);
}
public function withCustomer(): static
{
return $this->state(fn () => ['customer_id' => Customer::factory()]);
}
public function upcoming(): static
{
return $this->state(fn () => [
'event_date' => fake()->dateTimeBetween('+1 day', '+1 month'),
'status' => EventStatus::Confirmed,
]);
}
public function past(): static
{
return $this->state(fn () => [
'event_date' => fake()->dateTimeBetween('-6 months', '-1 day'),
'status' => EventStatus::Completed,
]);
}
public function privateEvent(): static
{
return $this->state(fn () => ['visibility' => EventVisibility::Private]);
}
public function publicEvent(): static
{
return $this->state(fn () => ['visibility' => EventVisibility::Public]);
return $this->state(fn () => ['status' => 'published']);
}
}

View File

@@ -1,65 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Enums\RsvpStatus;
use App\Models\Event;
use App\Models\EventInvitation;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<EventInvitation>
*/
final class EventInvitationFactory extends Factory
{
protected $model = EventInvitation::class;
public function definition(): array
{
return [
'event_id' => Event::factory(),
'user_id' => User::factory(),
'rsvp_status' => RsvpStatus::Pending,
'rsvp_note' => null,
'rsvp_responded_at' => null,
'invited_at' => now(),
];
}
public function pending(): static
{
return $this->state(fn () => [
'rsvp_status' => RsvpStatus::Pending,
'rsvp_responded_at' => null,
]);
}
public function available(): static
{
return $this->state(fn () => [
'rsvp_status' => RsvpStatus::Available,
'rsvp_responded_at' => now(),
]);
}
public function unavailable(): static
{
return $this->state(fn () => [
'rsvp_status' => RsvpStatus::Unavailable,
'rsvp_responded_at' => now(),
]);
}
public function tentative(): static
{
return $this->state(fn () => [
'rsvp_status' => RsvpStatus::Tentative,
'rsvp_responded_at' => now(),
'rsvp_note' => fake()->sentence(),
]);
}
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\Location;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Location>
*/
final class LocationFactory extends Factory
{
protected $model = Location::class;
public function definition(): array
{
return [
'name' => fake()->company() . ' ' . fake()->randomElement(['Theater', 'Hall', 'Arena', 'Club', 'Venue']),
'address' => fake()->streetAddress(),
'city' => fake()->city(),
'postal_code' => fake()->postcode(),
'country' => 'NL',
'latitude' => fake()->optional()->latitude(),
'longitude' => fake()->optional()->longitude(),
'capacity' => fake()->optional()->numberBetween(50, 2000),
'contact_name' => fake()->optional()->name(),
'contact_email' => fake()->optional()->safeEmail(),
'contact_phone' => fake()->optional()->phoneNumber(),
'notes' => fake()->optional()->paragraph(),
];
}
}

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\Organisation;
use Illuminate\Database\Eloquent\Factories\Factory;
/** @extends Factory<Organisation> */
final class OrganisationFactory extends Factory
{
/** @return array<string, mixed> */
public function definition(): array
{
$name = fake()->unique()->company();
return [
'name' => $name,
'slug' => str($name)->slug()->toString(),
'billing_status' => 'active',
'settings' => [],
];
}
}

View File

@@ -1,26 +1,20 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
/** @extends Factory<User> */
final class UserFactory extends Factory
{
/**
* The current password being used by the factory.
*/
protected static ?string $password;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
/** @return array<string, mixed> */
public function definition(): array
{
return [
@@ -28,17 +22,14 @@ class UserFactory extends Factory
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'timezone' => 'Europe/Amsterdam',
'locale' => 'nl',
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
return $this->state(fn () => ['email_verified_at' => null]);
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\Organisation;
use App\Models\User;
use App\Models\UserInvitation;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/** @extends Factory<UserInvitation> */
final class UserInvitationFactory extends Factory
{
/** @return array<string, mixed> */
public function definition(): array
{
return [
'email' => fake()->unique()->safeEmail(),
'invited_by_user_id' => User::factory(),
'organisation_id' => Organisation::factory(),
'event_id' => null,
'role' => 'org_member',
'token' => strtolower((string) Str::ulid()),
'status' => 'pending',
'expires_at' => now()->addDays(7),
];
}
}