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.
61 lines
1.8 KiB
PHP
61 lines
1.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Mail;
|
|
|
|
use App\Enums\PostPlatform\Status;
|
|
use App\Models\Post;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Mail\Mailable;
|
|
use Illuminate\Mail\Mailables\Content;
|
|
use Illuminate\Mail\Mailables\Envelope;
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
class PostPublishFailed extends Mailable implements ShouldQueue
|
|
{
|
|
use Queueable, SerializesModels;
|
|
|
|
public function __construct(
|
|
public Post $post
|
|
) {}
|
|
|
|
public function envelope(): Envelope
|
|
{
|
|
return new Envelope(
|
|
subject: "Your post failed to publish in {$this->post->workspace->name}",
|
|
);
|
|
}
|
|
|
|
public function content(): Content
|
|
{
|
|
$failedPlatforms = $this->post->postPlatforms()
|
|
->with('socialAccount')
|
|
->where('enabled', true)
|
|
->get()
|
|
->filter(fn ($pp) => $pp->status === Status::Failed)
|
|
->map(fn ($pp) => [
|
|
'name' => $pp->platform->label().' (@'.data_get($pp, 'socialAccount.username', data_get($pp, 'socialAccount.display_name', '')).')',
|
|
'error' => $pp->error_message,
|
|
])
|
|
->values()
|
|
->all();
|
|
|
|
return new Content(
|
|
view: 'mail.post-publish-failed',
|
|
with: [
|
|
'title' => 'Your post failed to publish',
|
|
'previewText' => 'One or more platforms failed to publish your post.',
|
|
'body' => "Your scheduled post in the {$this->post->workspace->name} workspace failed to publish on one or more platforms.",
|
|
'failedPlatforms' => $failedPlatforms,
|
|
'url' => route('app.posts.edit', $this->post),
|
|
],
|
|
);
|
|
}
|
|
|
|
public function attachments(): array
|
|
{
|
|
return [];
|
|
}
|
|
}
|