Compare commits
No commits in common. "feat/validate-invitation-token-format" and "dev" have entirely different histories.
feat/valid
...
dev
6 changed files with 6 additions and 153 deletions
|
|
@ -102,7 +102,7 @@ class EntitlementApiController extends Controller
|
||||||
$workspace = Workspace::create([
|
$workspace = Workspace::create([
|
||||||
'name' => $user->name."'s Workspace",
|
'name' => $user->name."'s Workspace",
|
||||||
'slug' => Str::slug($user->name).'-'.Str::random(6),
|
'slug' => Str::slug($user->name).'-'.Str::random(6),
|
||||||
'domain' => 'hub.'.config('app.base_domain', 'host.uk.com'),
|
'domain' => 'hub.host.uk.com',
|
||||||
'type' => 'custom',
|
'type' => 'custom',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class WorkspaceController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default domain
|
// Set default domain
|
||||||
$validated['domain'] = 'hub.'.config('app.base_domain', 'host.uk.com');
|
$validated['domain'] = 'hub.host.uk.com';
|
||||||
$validated['type'] = $validated['type'] ?? 'custom';
|
$validated['type'] = $validated['type'] ?? 'custom';
|
||||||
|
|
||||||
$workspace = Workspace::create($validated);
|
$workspace = Workspace::create($validated);
|
||||||
|
|
@ -261,7 +261,7 @@ class WorkspaceController extends Controller
|
||||||
->whereIn('workspace_id', function ($query) {
|
->whereIn('workspace_id', function ($query) {
|
||||||
$query->select('id')
|
$query->select('id')
|
||||||
->from('workspaces')
|
->from('workspaces')
|
||||||
->where('domain', 'hub.'.config('app.base_domain', 'host.uk.com'));
|
->where('domain', 'hub.host.uk.com');
|
||||||
})
|
})
|
||||||
->update(['is_default' => false]);
|
->update(['is_default' => false]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Add foreign key constraints on feature_code columns to prevent orphaned records.
|
|
||||||
*
|
|
||||||
* Fixes #12: feature_code in usage_alert_history not constrained to entitlement_features.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::table('entitlement_usage_alert_history', function (Blueprint $table) {
|
|
||||||
$table->foreign('feature_code', 'usage_alert_feature_code_fk')
|
|
||||||
->references('code')
|
|
||||||
->on('entitlement_features')
|
|
||||||
->cascadeOnUpdate()
|
|
||||||
->restrictOnDelete();
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::table('entitlement_boosts', function (Blueprint $table) {
|
|
||||||
$table->foreign('feature_code', 'boosts_feature_code_fk')
|
|
||||||
->references('code')
|
|
||||||
->on('entitlement_features')
|
|
||||||
->cascadeOnUpdate()
|
|
||||||
->restrictOnDelete();
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::table('entitlement_usage_records', function (Blueprint $table) {
|
|
||||||
$table->foreign('feature_code', 'usage_records_feature_code_fk')
|
|
||||||
->references('code')
|
|
||||||
->on('entitlement_features')
|
|
||||||
->cascadeOnUpdate()
|
|
||||||
->restrictOnDelete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::table('entitlement_usage_alert_history', function (Blueprint $table) {
|
|
||||||
$table->dropForeign('usage_alert_feature_code_fk');
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::table('entitlement_boosts', function (Blueprint $table) {
|
|
||||||
$table->dropForeign('boosts_feature_code_fk');
|
|
||||||
});
|
|
||||||
|
|
||||||
Schema::table('entitlement_usage_records', function (Blueprint $table) {
|
|
||||||
$table->dropForeign('usage_records_feature_code_fk');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Change namespaces.workspace_id FK from nullOnDelete to cascadeOnDelete.
|
|
||||||
*
|
|
||||||
* Fixes #10 — namespaces were orphaned with null workspace_id when
|
|
||||||
* the parent workspace was deleted.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::table('namespaces', function (Blueprint $table) {
|
|
||||||
$table->dropForeign(['workspace_id']);
|
|
||||||
|
|
||||||
$table->foreign('workspace_id')
|
|
||||||
->references('id')
|
|
||||||
->on('workspaces')
|
|
||||||
->cascadeOnDelete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::table('namespaces', function (Blueprint $table) {
|
|
||||||
$table->dropForeign(['workspace_id']);
|
|
||||||
|
|
||||||
$table->foreign('workspace_id')
|
|
||||||
->references('id')
|
|
||||||
->on('workspaces')
|
|
||||||
->nullOnDelete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Change parent_feature_id FK from nullOnDelete to cascadeOnDelete.
|
|
||||||
*
|
|
||||||
* nullOnDelete orphans child features when a parent is removed — they lose
|
|
||||||
* their hierarchy but still exist with a null parent_feature_id. Children
|
|
||||||
* that belong to a pool have no meaning without their parent, so cascade
|
|
||||||
* deletion is the correct behaviour.
|
|
||||||
*
|
|
||||||
* Fixes #40
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::table('entitlement_features', function (Blueprint $table) {
|
|
||||||
$table->dropForeign(['parent_feature_id']);
|
|
||||||
|
|
||||||
$table->foreign('parent_feature_id')
|
|
||||||
->references('id')
|
|
||||||
->on('entitlement_features')
|
|
||||||
->cascadeOnDelete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revert to the original nullOnDelete behaviour.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::table('entitlement_features', function (Blueprint $table) {
|
|
||||||
$table->dropForeign(['parent_feature_id']);
|
|
||||||
|
|
||||||
$table->foreign('parent_feature_id')
|
|
||||||
->references('id')
|
|
||||||
->on('entitlement_features')
|
|
||||||
->nullOnDelete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -26,12 +26,10 @@ use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::prefix('account')->name('account.')->group(function () {
|
Route::prefix('account')->name('account.')->group(function () {
|
||||||
Route::get('/delete/{token}', ConfirmDeletion::class)
|
Route::get('/delete/{token}', ConfirmDeletion::class)
|
||||||
->name('delete.confirm')
|
->name('delete.confirm');
|
||||||
->where('token', '[a-zA-Z0-9]{64}');
|
|
||||||
|
|
||||||
Route::get('/delete/{token}/cancel', CancelDeletion::class)
|
Route::get('/delete/{token}/cancel', CancelDeletion::class)
|
||||||
->name('delete.cancel')
|
->name('delete.cancel');
|
||||||
->where('token', '[a-zA-Z0-9]{64}');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -45,8 +43,7 @@ Route::prefix('account')->name('account.')->group(function () {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::get('/workspace/invitation/{token}', WorkspaceInvitationController::class)
|
Route::get('/workspace/invitation/{token}', WorkspaceInvitationController::class)
|
||||||
->name('workspace.invitation.accept')
|
->name('workspace.invitation.accept');
|
||||||
->where('token', '[a-zA-Z0-9]{64}');
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue