Files
portal-api/app/Support/Markables.php
T
baodev0andClaude Opus 5.5 40bf6b54f9 feat(admin): star/tags marks, service product-type filter, campaign bulk actions, SMTP test
- Star (is_starred) and colored tags for services, customers, orders, invoices:
  Markable trait, tags/taggables tables, PATCH administrator/marks/{type}/{key},
  tag CRUD, list filters starred / tag_ids[]
- GET administrator/services accepts product_type (falls back to product type
  for legacy rows without services.type)
- Mail campaigns: bulk cancel / retry failed / delete; cancelled campaigns are
  skipped by SendMailCampaignRecipient
- POST administrator/settings/test-smtp sends a test email through the saved
  mail transport

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 21:53:41 +07:00

32 lines
976 B
PHP

<?php
declare(strict_types=1);
namespace App\Support;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Order;
use App\Models\Service;
use Illuminate\Database\Eloquent\Model;
final class Markables
{
/**
* @var array<string, array{model: class-string<Model>, key: string, permission: string}>
*/
public const TYPES = [
'services' => ['model' => Service::class, 'key' => 'id', 'permission' => 'customer.edit'],
'customers' => ['model' => Customer::class, 'key' => 'uuid', 'permission' => 'customer.edit'],
'orders' => ['model' => Order::class, 'key' => 'id', 'permission' => 'order.edit'],
'invoices' => ['model' => Invoice::class, 'key' => 'id', 'permission' => 'invoice.edit'],
];
public static function find(string $type, string $key): Model
{
$definition = self::TYPES[$type];
return $definition['model']::query()->where($definition['key'], $key)->firstOrFail();
}
}