Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save freekmurze/020507c15ef7d0f8b75fe03f74e38fd4 to your computer and use it in GitHub Desktop.
Save freekmurze/020507c15ef7d0f8b75fe03f74e38fd4 to your computer and use it in GitHub Desktop.
Migrating Flare from Spark classic to Spark Next
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
$this
->createNewTables()
->dropUnusedTables()
->createSubscriptionTables()
->updateTeamsTable()
->updateInvoicesTable()
->dropOldColumnsFromUsersTable()
->dropOldColumnsFromInvoicesTable();
}
protected function dropUnusedTables(): self
{
Schema::drop('announcements');
return $this;
}
protected function createSubscriptionTables(): self
{
Schema::drop('subscriptions');
Schema::create('subscriptions', function (Blueprint $table): void {
$table->id();
$table->foreignId('team_id');
$table->string('name');
$table->string('stripe_id');
$table->string('stripe_status');
$table->string('stripe_plan')->nullable();
$table->integer('quantity')->nullable();
$table->timestamp('trial_ends_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->timestamps();
$table->index(['team_id', 'stripe_status']);
});
Schema::drop('subscription_items');
Schema::create('subscription_items', function (Blueprint $table): void {
$table->id();
$table->foreignId('subscription_id');
$table->string('stripe_id')->index();
$table->string('stripe_plan');
$table->integer('quantity');
$table->timestamps();
$table->unique(['subscription_id', 'stripe_plan']);
});
return $this;
}
protected function createNewTables(): self
{
Schema::dropIfExists('receipts');
Schema::create('receipts', function (Blueprint $table): void {
$table->id();
$table->foreignId('team_id')->index();
$table->string('provider_id')->index();
$table->string('amount');
$table->string('tax');
$table->timestamp('paid_at');
$table->timestamps();
});
Schema::create('tax_rates', function (Blueprint $table): void {
$table->id();
$table->string('stripe_id')->index();
$table->double('percentage')->index();
$table->timestamps();
});
return $this;
}
protected function updateTeamsTable(): self
{
Schema::table('teams', function (Blueprint $table): void {
$table->renameColumn('billing_zip', 'billing_postal_code');
});
Schema::table('teams', function (Blueprint $table): void {
$table->string('card_expiration')->nullable();
});
Schema::table('teams', function (Blueprint $table): void {
$table->text('receipt_emails')->nullable();
});
return $this;
}
protected function updateInvoicesTable(): self
{
Schema::table('invoices', function (Blueprint $table): void {
$table->renameColumn('provider_id', 'stripe_id');
});
Schema::table('invoices', function (Blueprint $table): void {
$table->renameColumn('billing_zip', 'billing_postal_code');
});
Schema::table('invoices', function (Blueprint $table): void {
$table->string('team_name');
$table->string('owner_email');
$table->string('owner_name');
});
return $this;
}
protected function dropOldColumnsFromUsersTable(): self
{
Schema::table('users', function (Blueprint $table): void {
$table->dropColumn([
'current_billing_plan',
'card_brand',
'card_last_four',
'card_country',
'billing_address',
'billing_address_line_2',
'billing_city',
'billing_state',
'billing_zip',
'billing_country',
'vat_id',
'extra_billing_information',
'trial_ends_at',
'last_read_announcements_at',
'stripe_id',
]);
});
return $this;
}
protected function dropOldColumnsFromInvoicesTable(): self
{
Schema::table('invoices', function (Blueprint $table): void {
$table->dropColumn('user_id');
});
return $this;
}
};
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
$this
->migrateSubscriptionData()
->dropOldSubscriptionTables();
}
protected function migrateSubscriptionData(): self
{
DB::table('team_subscriptions')
->orderBy('id')
->each(function (stdClass $teamSubscriptionData): void {
$teamSubscriptionData = get_object_vars($teamSubscriptionData);
DB::table('subscriptions')->insert($teamSubscriptionData);
});
DB::table('team_subscription_items')
->orderBy('id')
->each(function (stdClass $teamSubscriptionItemData): void {
$teamSubscriptionItemData = get_object_vars($teamSubscriptionItemData);
DB::table('subscription_items')->insert($teamSubscriptionItemData);
});
return $this;
}
protected function dropOldSubscriptionTables(): self
{
Schema::drop('team_subscriptions');
Schema::drop('team_subscription_items');
return $this;
}
};
<?php
use App\Domain\Subscription\Models\Invoice;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
Invoice::each(function (Invoice $invoice): void {
DB::table('receipts')->insert([
'team_id' => $invoice->team_id,
'provider_id' => $invoice->stripe_id,
'amount' => $invoice->total ?? 0,
'tax' => $invoice->tax ?? 0,
'paid_at' => $invoice->created_at,
'created_at' => $invoice->created_at,
'updated_at' => $invoice->updated_at,
]);
});
}
};
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
DB::table('teams')->update(['card_expiration' => 'xx/xxxx']);
}
};
<?php
use App\Domain\Subscription\Models\Invoice;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
DB::statement('UPDATE invoices set team_name = billing_company');
Invoice::each(function (Invoice $invoice): void {
try {
$owner = $invoice->team->owner;
$invoice->update([
'owner_email' => $owner->email,
'owner_name' => $owner->name,
]);
} catch (Exception) {
echo "Could not update owner data for invoice `{$invoice->id}`" . PHP_EOL;
}
});
}
};
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::table('invoices', function (Blueprint $table): void {
$table->dropColumn('billing_company');
});
}
};
<?php
use App\Domain\Team\Models\Token;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Token::each(function (Token $token): void {
$token->update(['token' => hash('sha256', $token->token)]);
});
}
};
<?php
use App\Domain\Team\Models\Team;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Team::each(function (Team $team): void {
$billingEmails = $team->billing_emails ?? $team->owner?->email;
$billingEmails = str_replace(['`', '[', ']', '"'], '', $billingEmails);
if (is_null($billingEmails)) {
return;
}
$team->receipt_emails = collect($billingEmails)
->flatMap(fn (string $email) => explode(',', $email))
->each(fn (string $email) => trim($email))
->toArray();
$team->save();
});
Schema::table('teams', function (Blueprint $table): void {
$table->dropColumn('billing_emails');
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment