5 Commits

Author SHA1 Message Date
arvanitakis cd9632a6bf Feature: Creating Skeleton for import command, interfaces, shopify importer 2026-07-06 03:42:24 +03:00
arvanitakis 677b240a8d Feature: Adding shipping options to Core 2026-07-06 03:10:34 +03:00
arvanitakis ab213f69ec Feat: Adding Migration for otp to lunar_customers 2026-07-03 17:16:30 +03:00
arvanitakis ebe905acfa Bump composer.json version to 0.0.2
Composer's VCS driver cross-checks the tag against the version field
in composer.json and skips tags that disagree, so this must match
the v0.0.2 tag for it to resolve.
2026-07-03 15:09:28 +03:00
arvanitakis d35dff3731 Fix: remove hardcoded Lucent nav item from CorePlugin
CorePlugin registered a "Lucent" navigation item pointing at /lucent
unconditionally, coupling the core package to a specific CMS that
consuming apps may not install.
2026-07-03 15:08:05 +03:00
10 changed files with 175 additions and 11 deletions
+3 -2
View File
@@ -2,7 +2,7 @@
"name": "boboko/core",
"description": "Core module — authentication and shared panel behaviour",
"type": "library",
"version": "0.0.1",
"version": "0.0.2",
"autoload": {
"psr-4": {
"Modules\\Core\\": "src/"
@@ -13,7 +13,8 @@
"lunarphp/lunar": "1.3.0",
"laravel/framework": "^12.0",
"laravel/tinker": "^3.0",
"symfony/yaml": "^7.0"
"symfony/yaml": "^7.0",
"lunarphp/table-rate-shipping": "^1.3"
},
"require-dev": {
"fakerphp/faker": "^1.23",
@@ -0,0 +1,23 @@
<?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('lunar_customers', function (Blueprint $table) {
$table->string('otp_code', 6)->nullable()->after('meta');
$table->timestamp('otp_expires_at')->nullable()->after('otp_code');
});
}
public function down(): void
{
Schema::table('lunar_customers', function (Blueprint $table) {
$table->dropColumn(['otp_code', 'otp_expires_at']);
});
}
};
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace Modules\Core\Command;
use Illuminate\Console\Command;
use Modules\Core\MigrateImport\ImportSpec;
use Modules\Core\MigrateImport\RunMigrateImportJob;
class MigrateImportCommand extends Command
{
protected $signature = "boboko:migrate:import
{--source= : The source platform to import from}
{--type= : The import mechanism for the chosen source}
{--file= : Path to the export file (when type is export)}";
protected $description = "Migrate data (products, customers, etc.) from an external source";
// Supported sources. Only "shopify" is wired up for now.
private const SOURCES = [
"shopify",
// "woocommerce",
];
// Supported import types per source. Only "export" is wired up for now.
private const TYPES = [
"export",
// "api",
];
public function handle(): void
{
$source = $this->option("source")
?? $this->choice("Select a source:", self::SOURCES, 0);
$type = $this->option("type")
?? $this->choice("Select an import type:", self::TYPES, 0);
if ($type === "api") {
$credentials = [
"api_key" => $this->secret("API key:"),
"api_secret" => $this->secret("API secret:"),
];
$filePath = null;
} else {
$filePath = $this->option("file")
?? $this->ask("Path to the export file:");
$credentials = null;
}
$spec = new ImportSpec(
source: $source,
type: $type,
filePath: $filePath,
credentials: $credentials,
);
RunMigrateImportJob::dispatch($spec);
$this->info("Import queued.");
}
}
+2 -8
View File
@@ -3,12 +3,12 @@
namespace Modules\Core;
use Filament\Contracts\Plugin;
use Filament\Navigation\NavigationItem;
use Filament\Panel;
use Illuminate\Support\Facades\Mail;
use Lunar\Admin\Filament\Resources\StaffResource;
use Lunar\Admin\Models\Staff as LunarStaff;
use Lunar\Admin\Support\Facades\LunarPanel;
use Lunar\Shipping\ShippingPlugin;
use Modules\Core\Auth\Extensions\StaffResourceExtension;
use Modules\Core\Auth\Filament\Pages\Login;
use Modules\Core\Auth\Mail\InviteMail;
@@ -27,13 +27,7 @@ class CorePlugin implements Plugin
->brandLogo(asset('static/logos/core/boboko-logo.svg'))
->darkModeBrandLogo(asset('static/logos/core/boboko-logo-white.svg'))
->login(Login::class)
->navigationItems([
NavigationItem::make("Lucent")
->url("/lucent")
->icon("heroicon-o-sun")
->group("Content")
->sort(1),
]);
->plugin(ShippingPlugin::make());
LunarPanel::extensions([
StaffResource::class => StaffResourceExtension::class,
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace Modules\Core\MigrateImport;
class ImportSpec
{
public function __construct(
public readonly string $source,
public readonly string $type,
public readonly ?string $filePath = null,
public readonly ?array $credentials = null,
) {
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace Modules\Core\MigrateImport;
interface Importer
{
public function import(ImportSpec $spec): void;
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Modules\Core\MigrateImport;
use Modules\Core\MigrateImport\Shopify\ShopifyExportImporter;
class ImporterFactory
{
public static function make(ImportSpec $spec): Importer
{
return match ([$spec->source, $spec->type]) {
["shopify", "export"] => new ShopifyExportImporter(),
// ["shopify", "api"] => new ShopifyApiImporter(),
// ["woocommerce", "export"] => new WooCommerceExportImporter(),
// ["woocommerce", "api"] => new WooCommerceApiImporter(),
default => throw new \InvalidArgumentException(
"No importer available for source \"{$spec->source}\" with type \"{$spec->type}\".",
),
};
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace Modules\Core\MigrateImport;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class RunMigrateImportJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public function __construct(
public readonly ImportSpec $spec,
) {
}
public function handle(): void
{
$importer = ImporterFactory::make($this->spec);
$importer->import($this->spec);
}
}
@@ -0,0 +1,13 @@
<?php
namespace Modules\Core\MigrateImport\Shopify;
use Modules\Core\MigrateImport\ImportSpec;
use Modules\Core\MigrateImport\Importer;
class ShopifyExportImporter implements Importer
{
public function import(ImportSpec $spec): void
{
}
}
+2 -1
View File
@@ -8,6 +8,7 @@ use Modules\Core\Command\AnonymizeCommand;
use Modules\Core\Command\ExportCleanupCommand;
use Modules\Core\Command\ExportCommand;
use Modules\Core\Command\ImportCommand;
use Modules\Core\Command\MigrateImportCommand;
class CoreServiceProvider extends ServiceProvider
{
@@ -32,7 +33,7 @@ class CoreServiceProvider extends ServiceProvider
], 'core-assets');
if ($this->app->runningInConsole()) {
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class]);
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class, MigrateImportCommand::class]);
}
}
}