trypost/database/factories/PostPlatformFactory.php
Paulo Castellano ceb7b92b74 feat: PostPlatform enum, failure email, DB indexes, rate limiting, tests
Publishing improvements:
- Create PostPlatformStatus enum (Pending, Publishing, Published, Failed)
- Update PostPlatform model, jobs, factories to use enum
- Add PostPublishFailed email notification when post fails to publish
- Maizzle template + blade for failure email with platform details
- PublishPost job: add $tries=3, $backoff=30, failed() method
- Fix broadcast event to serialize enum status value

Security:
- Add rate limiting (throttle:6,1) on social connect endpoints
- Fix MediaController::reorder IDOR vulnerability
- Fix Connect.vue broken import (storeStep2 -> storeConnect)
- Fix UpdatePost data_get() consistency

Database:
- Add composite index on post_platforms (post_id, enabled)
- Add index on post_platforms (social_account_id)

Tests:
- Add 3 tests for profile photo upload/delete
- Add 2 tests for media reorder (including IDOR check)
- Fix publish tests for PostPlatformStatus enum
- Add Mail::fake() to publish tests

Cleanup:
- Remove unused AppHeader.vue and AppHeaderLayout.vue
- Remove dead BillingController methods

All 733 tests passing.
2026-03-30 16:11:38 -03:00

173 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Enums\PostPlatform\ContentType;
use App\Enums\PostPlatform\Status;
use App\Enums\SocialAccount\Platform;
use App\Models\Post;
use App\Models\PostPlatform;
use App\Models\SocialAccount;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<PostPlatform>
*/
class PostPlatformFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'post_id' => Post::factory(),
'social_account_id' => SocialAccount::factory(),
'enabled' => true,
'platform' => Platform::LinkedIn,
'content' => $this->faker->paragraph(),
'content_type' => ContentType::LinkedInPost,
'status' => Status::Pending,
'meta' => [],
];
}
public function disabled(): static
{
return $this->state(fn (array $attributes) => [
'enabled' => false,
]);
}
public function published(): static
{
return $this->state(fn (array $attributes) => [
'status' => Status::Published,
'platform_post_id' => $this->faker->uuid(),
'platform_url' => $this->faker->url(),
'published_at' => now(),
]);
}
public function failed(): static
{
return $this->state(fn (array $attributes) => [
'status' => Status::Failed,
'error_message' => 'Failed to publish',
]);
}
public function linkedin(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::LinkedIn,
]);
}
public function x(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::X,
'content_type' => ContentType::XPost,
]);
}
public function instagram(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Instagram,
]);
}
public function bluesky(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Bluesky,
'content_type' => ContentType::BlueskyPost,
]);
}
public function mastodon(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Mastodon,
'content_type' => ContentType::MastodonPost,
]);
}
public function threads(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Threads,
'content_type' => ContentType::ThreadsPost,
]);
}
public function tiktok(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::TikTok,
'content_type' => ContentType::TikTokVideo,
]);
}
public function youtube(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::YouTube,
'content_type' => ContentType::YouTubeShort,
]);
}
public function pinterest(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Pinterest,
'content_type' => ContentType::PinterestPin,
]);
}
public function pinterestVideoPin(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Pinterest,
'content_type' => ContentType::PinterestVideoPin,
]);
}
public function pinterestCarousel(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Pinterest,
'content_type' => ContentType::PinterestCarousel,
]);
}
public function facebook(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Facebook,
'content_type' => ContentType::FacebookPost,
]);
}
public function facebookReel(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Facebook,
'content_type' => ContentType::FacebookReel,
]);
}
public function facebookStory(): static
{
return $this->state(fn (array $attributes) => [
'platform' => Platform::Facebook,
'content_type' => ContentType::FacebookStory,
]);
}
}