Skip to content

Commit 1363cd4

Browse files
author
Ronald A Richardson
committed
refactor: store invite role_uuid in meta JSON via HasMetaAttributes
Instead of a dedicated role_uuid column, use a generic meta JSON column on the invites table. This keeps the schema clean and extensible — any future invite-time data (e.g. custom permissions, onboarding flags) can be stored in meta without additional migrations. Changes: - Migration: adds nullable json 'meta' column instead of char 'role_uuid' - Invite model: uses HasMetaAttributes trait; 'meta' added to fillable and cast via Json::class - UserController: Invite::create() now passes meta => ['role_uuid' => ...] (array_filter drops it when no role is selected); acceptCompanyInvite() reads the role via $invite->getMeta('role_uuid', 'Administrator')
1 parent c0e1df6 commit 1363cd4

3 files changed

Lines changed: 17 additions & 12 deletions

File tree

migrations/2026_04_21_000001_add_role_uuid_to_invites_table.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88
/**
99
* Run the migrations.
1010
*
11-
* Adds a nullable `role_uuid` column to the `invites` table so that the
12-
* intended role for an invited user can be stored on the invite record and
13-
* applied when the user accepts the invitation.
11+
* Adds a nullable JSON `meta` column to the `invites` table so that
12+
* arbitrary key-value data (e.g. role_uuid for user invitations) can be
13+
* stored on an invite record without requiring dedicated columns for each
14+
* use-case. The HasMetaAttributes trait is used to read and write values.
1415
*
1516
* @return void
1617
*/
1718
public function up()
1819
{
1920
Schema::table('invites', function (Blueprint $table) {
20-
$table->char('role_uuid', 36)->nullable()->after('reason');
21+
$table->json('meta')->nullable()->after('reason');
2122
});
2223
}
2324

@@ -29,7 +30,7 @@ public function up()
2930
public function down()
3031
{
3132
Schema::table('invites', function (Blueprint $table) {
32-
$table->dropColumn('role_uuid');
33+
$table->dropColumn('meta');
3334
});
3435
}
3536
};

src/Http/Controllers/Internal/v1/UserController.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ public function inviteUser(InviteUserRequest $request)
346346
'protocol' => 'email',
347347
'recipients' => [$user->email],
348348
'reason' => 'join_company',
349-
'role_uuid' => $request->input('user.role_uuid') ?? $request->input('user.role'),
349+
'meta' => array_filter(['role_uuid' => $request->input('user.role_uuid') ?? $request->input('user.role')]),
350350
]);
351351

352352
$user->notify(new UserInvited($invitation));
@@ -389,7 +389,7 @@ private function inviteExistingUser(User $user, Request $request): \Illuminate\H
389389
'protocol' => 'email',
390390
'recipients' => [$user->email],
391391
'reason' => 'join_company',
392-
'role_uuid' => $request->input('user.role_uuid') ?? $request->input('user.role'),
392+
'meta' => array_filter(['role_uuid' => $request->input('user.role_uuid') ?? $request->input('user.role')]),
393393
]);
394394

395395
$user->notify(new UserInvited($invitation));
@@ -470,18 +470,19 @@ public function acceptCompanyInvite(AcceptCompanyInvite $request)
470470

471471
if (!$alreadyMember) {
472472
// Use Company::addUser() so that role assignment is handled in
473-
// one place. The role stored on the invite takes precedence;
473+
// one place. The role stored in the invite meta takes precedence;
474474
// if none was set the default 'Administrator' role is used.
475-
$roleIdentifier = $invite->role_uuid ?? 'Administrator';
475+
$roleIdentifier = $invite->getMeta('role_uuid', 'Administrator');
476476
$companyUser = $company->addUser($user, $roleIdentifier);
477477
$user->setRelation('companyUser', $companyUser);
478478
} else {
479479
// User is already a member — ensure the companyUser relation is
480480
// loaded so that role assignment below can still be applied if
481481
// the invite carries a role (e.g. re-sent invite with a new role).
482482
$user->loadCompanyUser();
483-
if ($user->companyUser && $invite->role_uuid) {
484-
$user->companyUser->assignSingleRole($invite->role_uuid);
483+
$roleUuid = $invite->getMeta('role_uuid');
484+
if ($user->companyUser && $roleUuid) {
485+
$user->companyUser->assignSingleRole($roleUuid);
485486
}
486487
}
487488

src/Models/Invite.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Fleetbase\Casts\Json;
66
use Fleetbase\Traits\Expirable;
77
use Fleetbase\Traits\HasApiModelBehavior;
8+
use Fleetbase\Traits\HasMetaAttributes;
89
use Fleetbase\Traits\HasPublicId;
910
use Fleetbase\Traits\HasUuid;
1011
use Illuminate\Support\Carbon;
@@ -16,6 +17,7 @@ class Invite extends Model
1617
use HasPublicId;
1718
use Expirable;
1819
use HasApiModelBehavior;
20+
use HasMetaAttributes;
1921

2022
/**
2123
* The database table used by the model.
@@ -81,7 +83,7 @@ public function getConnectionName(): string
8183
'protocol',
8284
'recipients',
8385
'reason',
84-
'role_uuid',
86+
'meta',
8587
];
8688

8789
/**
@@ -105,6 +107,7 @@ public function getConnectionName(): string
105107
*/
106108
protected $casts = [
107109
'recipients' => Json::class,
110+
'meta' => Json::class,
108111
];
109112

110113
/**

0 commit comments

Comments
 (0)