feat: Reinitialize frontend with SvelteKit and TypeScript
- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
This commit is contained in:
28
backend/database/factories/ActualFactory.php
Normal file
28
backend/database/factories/ActualFactory.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Actual;
|
||||
use App\Models\Project;
|
||||
use App\Models\TeamMember;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\Actual>
|
||||
*/
|
||||
class ActualFactory extends Factory
|
||||
{
|
||||
protected $model = Actual::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) Str::uuid(),
|
||||
'project_id' => Project::factory(),
|
||||
'team_member_id' => TeamMember::factory(),
|
||||
'month' => fake()->dateTimeBetween('-6 months', 'now')->format('Y-m-01'),
|
||||
'hours_logged' => fake()->randomFloat(2, 0, 160),
|
||||
];
|
||||
}
|
||||
}
|
||||
28
backend/database/factories/AllocationFactory.php
Normal file
28
backend/database/factories/AllocationFactory.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Allocation;
|
||||
use App\Models\Project;
|
||||
use App\Models\TeamMember;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\Allocation>
|
||||
*/
|
||||
class AllocationFactory extends Factory
|
||||
{
|
||||
protected $model = Allocation::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) Str::uuid(),
|
||||
'project_id' => Project::factory(),
|
||||
'team_member_id' => TeamMember::factory(),
|
||||
'month' => fake()->dateTimeBetween('-6 months', '+6 months')->format('Y-m-01'),
|
||||
'allocated_hours' => fake()->randomFloat(2, 0, 160),
|
||||
];
|
||||
}
|
||||
}
|
||||
42
backend/database/factories/ProjectFactory.php
Normal file
42
backend/database/factories/ProjectFactory.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectStatus;
|
||||
use App\Models\ProjectType;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\Project>
|
||||
*/
|
||||
class ProjectFactory extends Factory
|
||||
{
|
||||
protected $model = Project::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) Str::uuid(),
|
||||
'code' => strtoupper(fake()->unique()->bothify('PRJ-####')),
|
||||
'title' => fake()->sentence(3),
|
||||
'status_id' => ProjectStatus::factory(),
|
||||
'type_id' => ProjectType::factory(),
|
||||
'approved_estimate' => null,
|
||||
'forecasted_effort' => null,
|
||||
];
|
||||
}
|
||||
|
||||
public function approved(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'approved_estimate' => fake()->randomFloat(2, 5000, 50000),
|
||||
'forecasted_effort' => [
|
||||
'frontend' => fake()->numberBetween(40, 200),
|
||||
'backend' => fake()->numberBetween(60, 300),
|
||||
'qa' => fake()->numberBetween(20, 100),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
24
backend/database/factories/ProjectStatusFactory.php
Normal file
24
backend/database/factories/ProjectStatusFactory.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use App\Models\ProjectStatus;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\ProjectStatus>
|
||||
*/
|
||||
class ProjectStatusFactory extends Factory
|
||||
{
|
||||
protected $model = ProjectStatus::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->unique()->words(2, true),
|
||||
'order' => fake()->numberBetween(1, 20),
|
||||
'is_active' => fake()->boolean(),
|
||||
'is_billable' => fake()->boolean(),
|
||||
];
|
||||
}
|
||||
}
|
||||
22
backend/database/factories/ProjectTypeFactory.php
Normal file
22
backend/database/factories/ProjectTypeFactory.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use App\Models\ProjectType;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\ProjectType>
|
||||
*/
|
||||
class ProjectTypeFactory extends Factory
|
||||
{
|
||||
protected $model = ProjectType::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->unique()->word(),
|
||||
'description' => fake()->sentence(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
backend/database/factories/RoleFactory.php
Normal file
23
backend/database/factories/RoleFactory.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Role;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\Role>
|
||||
*/
|
||||
class RoleFactory extends Factory
|
||||
{
|
||||
protected $model = Role::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->unique()->jobTitle(),
|
||||
'description' => fake()->sentence(),
|
||||
];
|
||||
}
|
||||
}
|
||||
34
backend/database/factories/TeamMemberFactory.php
Normal file
34
backend/database/factories/TeamMemberFactory.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\TeamMember;
|
||||
use App\Models\Role;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory\u003c\App\Models\TeamMember>
|
||||
*/
|
||||
class TeamMemberFactory extends Factory
|
||||
{
|
||||
protected $model = TeamMember::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) Str::uuid(),
|
||||
'name' => fake()->name(),
|
||||
'role_id' => Role::factory(),
|
||||
'hourly_rate' => fake()->randomFloat(2, 20, 150),
|
||||
'active' => true,
|
||||
];
|
||||
}
|
||||
|
||||
public function inactive(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'active' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
45
backend/database/factories/UserFactory.php
Normal file
45
backend/database/factories/UserFactory.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
protected static ?string $password;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'role' => fake()->randomElement(['superuser', 'manager', 'developer', 'top_brass']),
|
||||
'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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user