Treat created_via as non-blocking analytics data.
Default to web when the value is missing, null, or invalid so post creation never fails over provenance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
459f4dd5a5
commit
a545d29cfb
2 changed files with 46 additions and 16 deletions
|
|
@ -12,7 +12,6 @@
|
|||
use App\Models\Workspace;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class CreatePost
|
||||
{
|
||||
|
|
@ -29,37 +28,30 @@ class CreatePost
|
|||
* works for REST, MCP, and web callers.
|
||||
*
|
||||
* `created_via` records which entry point created the post (web, mcp,
|
||||
* api, or automation). Callers must set it explicitly.
|
||||
* api, or automation). Analytical only — defaults to web when omitted
|
||||
* or invalid, and never blocks creation.
|
||||
*
|
||||
* @param array{
|
||||
* content?: ?string,
|
||||
* media?: array<int, mixed>,
|
||||
* date?: ?string,
|
||||
* scheduled_at?: ?string,
|
||||
* created_via: CreatedVia,
|
||||
* created_via?: CreatedVia,
|
||||
* platforms?: array<int, array{social_account_id: string, content_type?: string, meta?: array<string, mixed>}>,
|
||||
* label_ids?: array<int, string>
|
||||
* } $data
|
||||
*
|
||||
* @throws InvalidArgumentException when created_via is missing or not a CreatedVia case
|
||||
*/
|
||||
public static function execute(Workspace $workspace, User $user, array $data): Post
|
||||
{
|
||||
$createdVia = data_get($data, 'created_via');
|
||||
|
||||
if (! $createdVia instanceof CreatedVia) {
|
||||
throw new InvalidArgumentException('created_via must be a CreatedVia enum case.');
|
||||
}
|
||||
|
||||
$scheduledAt = self::resolveScheduledAt($data);
|
||||
|
||||
$post = DB::transaction(function () use ($workspace, $user, $data, $scheduledAt, $createdVia): Post {
|
||||
$post = DB::transaction(function () use ($workspace, $user, $data, $scheduledAt): Post {
|
||||
$post = $workspace->posts()->create([
|
||||
'user_id' => $user->id,
|
||||
'content' => data_get($data, 'content', ''),
|
||||
'media' => data_get($data, 'media', []),
|
||||
'status' => PostStatus::Draft,
|
||||
'created_via' => $createdVia,
|
||||
'created_via' => self::resolveCreatedVia($data),
|
||||
'scheduled_at' => $scheduledAt,
|
||||
]);
|
||||
|
||||
|
|
@ -105,6 +97,26 @@ public static function execute(Workspace $workspace, User $user, array $data): P
|
|||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analytical only — never fail creation over a missing/invalid value.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
private static function resolveCreatedVia(array $data): CreatedVia
|
||||
{
|
||||
$value = data_get($data, 'created_via');
|
||||
|
||||
if ($value instanceof CreatedVia) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
return CreatedVia::tryFrom($value) ?? CreatedVia::Web;
|
||||
}
|
||||
|
||||
return CreatedVia::Web;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,11 +44,29 @@
|
|||
'automation' => CreatedVia::Automation,
|
||||
]);
|
||||
|
||||
test('execute requires created_via', function () {
|
||||
test('execute defaults created_via to web when omitted', function () {
|
||||
$user = User::factory()->create();
|
||||
$workspace = Workspace::factory()->create(['user_id' => $user->id]);
|
||||
|
||||
CreatePost::execute($workspace, $user, [
|
||||
$post = CreatePost::execute($workspace, $user, [
|
||||
'content' => 'Hello world',
|
||||
]);
|
||||
})->throws(InvalidArgumentException::class, 'created_via must be a CreatedVia enum case.');
|
||||
|
||||
expect($post->fresh()->created_via)->toBe(CreatedVia::Web);
|
||||
});
|
||||
|
||||
test('execute defaults created_via to web when null or invalid', function (mixed $createdVia) {
|
||||
$user = User::factory()->create();
|
||||
$workspace = Workspace::factory()->create(['user_id' => $user->id]);
|
||||
|
||||
$post = CreatePost::execute($workspace, $user, [
|
||||
'content' => 'Hello world',
|
||||
'created_via' => $createdVia,
|
||||
]);
|
||||
|
||||
expect($post->fresh()->created_via)->toBe(CreatedVia::Web);
|
||||
})->with([
|
||||
'null' => null,
|
||||
'invalid string' => 'not-a-channel',
|
||||
'integer' => 1,
|
||||
]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue