Skip to content

モデル ​

Lase が提供する Eloquent モデルの一覧です。すべて CodebaseJp\Lase\Models 名前空間に属します。

コアモデル ​

Tenant ​

テナント(組織)を表すモデルです。

カラム説明
id主キー
public_id外部公開用 ID(プレフィックス: tnt_)
codeサブドメインに使用されるユニークコード
nameテナント名
email連絡先メールアドレス
tel電話番号
contact_person担当者名
logo_pathロゴ画像パス
current_subscription_id現在のサブスクリプション ID
suspended_at緊急停止した日時。NULL なら稼働中
suspension_reason緊急停止の理由(運用の記録用。テナント側には出しません)
opening_time / closing_time営業時間(既定は 9:00〜18:00)
business_weekdays営業する曜日(ISO の曜日番号の配列。NULL なら月〜金)

休日は TenantHoliday(tenant_holidays。1日に1つ。is_public は日本の祝日を取り込んだもの)に持ち、$tenant->holidays で引けます。営業日の数え方は BusinessCalendar(サービス)です。

TIP

テナントオブジェクトはキャッシュ(tenant:{code}、TTL 60 分)に保存され、保存・削除時に自動でキャッシュが破棄されます。

緊急停止の状態は suspended_at だけが持ちます(NULL なら稼働中)。状態を表すカラムを別に持つと二重管理になるため、status のような列は設けていません。「誰が停止したか」はアクティビティログ(ADMIN_SUSPEND_TENANT / ADMIN_RESUME_TENANT)が持つため、テナント側には持たせていません。

php
Tenant::query()->active()->get();  // suspended_at が NULL のみ
$tenant->isSuspended();            // 停止中なら true

緊急停止の状態は tenants のカラムに持つ

緊急停止は上記のキャッシュ破棄に相乗りすることで即時に反映されます。別テーブルに持つと Tenant の保存イベントが発火せず、停止が最大 60 分効きません。同じ理由で、 停止はキャッシュを共有するストア(Redis 等)を前提にしています。

User ​

テナントユーザーを表すモデルです。

カラム説明
id主キー
public_id外部公開用 ID(プレフィックス: usr_)
name表示名
emailメールアドレス
statusステータス (UserStatus Enum)
deleted_atソフトデリート

AdminUser ​

管理画面にアクセスできる管理者ユーザーを表すモデルです。

カラム説明
id主キー
public_id外部公開用 ID
name表示名
emailメールアドレス
statusステータス (AdminUserStatus Enum)

TenantUser ​

テナントとユーザーの中間テーブルに対応するモデルです。テナントへの所属情報(ロール、ステータスなど)を保持します。

認証・招待 ​

モデル説明
AdminUserInvitation管理者の招待レコード
TenantUserInvitationテナントユーザーの招待レコード
EmailChangeメールアドレス変更リクエスト

ロール・権限 ​

モデル説明
AdminRole管理者ロール
AdminRolePermission管理者ロールの権限
TenantRoleテナントロール
TenantRolePermissionテナントロールの権限

役割は、テナントユーザー・管理者・パートナー担当者のどれも1人1つです(役割なしもあります)。所属の列(tenant_users.tenant_role_id・admin_users.admin_role_id・partner_users.partner_role_id)で持ち、リレーションは tenantRole() / adminRole() / partnerRole() です。役割なし、または役割が削除済みのときは権限を持ちません。役割を削除すると、その役割を持つ所属は役割なしになります。

複数の職務を兼ねる人には、権限を組み合わせた役割を作って割り当ててください。

サブスクリプション・プラン ​

Plan はテナントをまたぐ共通カタログです(tenant_id を持ちません)。テナントに見せるプランは Plan::selectable(?Subscription $currentSubscription) スコープで絞ります。公開中のノーマルプランは常に対象で、トライアル契約中はトライアルプラン、スペシャルプラン契約中は契約中のプラン自体(非公開でも)が加わります。テナント API の一覧・詳細はどちらもこのスコープを通します。

Plan ──[1:N]── PlanFeature     (機能フラグ)
Plan ──[1:N]── PlanQuota       (利用上限)
Plan ──[N:M]── Option          (PlanOptionGroup を介して)

Subscription ──[N:1]── Plan
Subscription ──[N:M]── Option  (SubscriptionOption)
Subscription ──[1:N]── SubscriptionFeature
Subscription ──[1:N]── SubscriptionQuota
Subscription ──[1:N]── SubscriptionUsage

Tenant ──[1:1]── Subscription  (current_subscription_id)
Tenant ──[1:N]── GrantedFeature
Tenant ──[1:N]── GrantedQuota
Tenant ──[1:N]── GrantedUsage
モデル説明
Plan料金プラン
PlanFeatureプランの機能フラグ
PlanQuotaプランの利用上限
Optionオプション機能
OptionFeatureオプションの機能フラグ
OptionQuotaオプションの利用上限
Addonアドオン
AddonFeatureアドオンの機能フラグ
AddonQuotaアドオンの利用上限
Subscriptionサブスクリプション
SubscriptionFeatureサブスクリプションの機能フラグ
SubscriptionQuotaサブスクリプションの利用上限
SubscriptionUsageサブスクリプションの利用量
TenantAddonテナントのアドオン紐付け
GrantedFeatureテナントに直接付与された機能フラグ(テーブル: granted_features)
GrantedQuotaテナントに直接付与された利用上限(テーブル: granted_quotas)
GrantedUsageテナントの利用量(テーブル: granted_usages)
RegistrationPlanRule登録時のプランの規則。申込みフォームから登録したテナントに、トライアルの代わりに付けるプランを決める(テーブル: registration_plan_rules。運用)

統計・利用量 ​

モデル説明
DailyUsage日次利用量
MonthlyUsage月次利用量

コンテンツ ​

モデル説明
Announcement運営からのお知らせ。published() で利用者に見せるもの(公開で、日付が今日まで)、urgent() で緊急表示の期限(urgent_until)の内のものに絞る
AdminImage管理者がアップロードした画像
AdminMail管理者が作成したメール
AdminMailDeliveryメール配信記録
Inquiryお問い合わせ
BlockedDomain禁止ドメイン
BlockedTenantCodeテナントコードとして使用不可の予約語(テーブル: blocked_tenant_codes、初期データはマイグレーションで投入)
ActivityLog操作ログ
TenantScreeningテナント登録時の生成AIによる審査結果(テーブル: tenant_screenings)。再審査を積み重ねられるよう tenant_id に unique は張らない。reviewed_at は運営が確認を済ませたかの状態で、誰が確認したかはアクティビティログ(ADMIN_REVIEW_TENANT_SCREENING)が持つ。Tenant::screenings() / Tenant::latestScreening() から引ける

Concerns (Trait) ​

BelongsToTenant ​

テナントに属するモデル(tenant_id を持つモデル)に付与します。テナントのコンテキスト配下では、自テナントのレコードだけを対象にするグローバルスコープ(tenant)が適用されます。

php
class Subscription extends Model
{
    use HasFactory, HasUlids, SoftDeletes, BelongsToTenant;
}

コンテキストの有無は IdentifyTenant が現在のテナントを解決したかどうかで決まります。

実行文脈スコープ
テナント API(routes/api/tenant.php)適用される
管理画面・公開ページ適用されない(IdentifyTenant を通らないため)
コンソール・キュー適用されない(HTTP リクエストがないため)

これにより、ルートモデルバインディングが他テナントのレコードを解決しなくなります(404 になります)。テナント API で ID を受け取るエンドポイントの多くはこの経路を通るため、テナント境界の一次防御として機能します。

意図的にテナントをまたいで参照する場合は、標準のグローバルスコープの外し方を使います。

php
Subscription::withoutGlobalScope('tenant')->findOrFail($id);

特定のテナントを明示して絞る場合は forTenant() を使います(スコープの有無に関わらず動作します)。

php
Subscription::forTenant($tenantId)->get();

WARNING

tenant_id を持っていても、テナントに属さないモデルには付与しません。User(tenant_id_to_be_deleted は移行前の残骸)、AdminMail(送信先テナントを持つ管理側のエンティティ)、MCP の OAuth 認可コード・トークン(認可サーバーがテナントのコンテキスト外で参照する)が該当します。

HasPublicId ​

public_id カラムを持つモデルに付与します。作成時に自動で {prefix}_{nanoid} 形式の ID が生成されます。

php
protected string $publicIdPrefix = 'tnt_';