authorizeAction('tenants', 'actions')) { return $response; } $updated = $tenant->update(['is_active' => true]); app(TenantLifecycleLogger::class)->record( $tenant, 'activated', actor: auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.activated', $tenant, SuperAdminAuditLogger::fieldsMetadata(['is_active']), source: static::class ); return response()->json(['ok' => $updated]); } public function deactivate(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $updated = $tenant->update(['is_active' => false]); app(TenantLifecycleLogger::class)->record( $tenant, 'deactivated', actor: auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.deactivated', $tenant, SuperAdminAuditLogger::fieldsMetadata(['is_active']), source: static::class ); return response()->json(['ok' => $updated]); } public function suspend(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $updated = $tenant->update(['is_suspended' => true]); app(TenantLifecycleLogger::class)->record( $tenant, 'suspended', actor: auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.suspended', $tenant, SuperAdminAuditLogger::fieldsMetadata(['is_suspended']), source: static::class ); return response()->json(['ok' => $updated]); } public function unsuspend(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $updated = $tenant->update(['is_suspended' => false]); app(TenantLifecycleLogger::class)->record( $tenant, 'unsuspended', actor: auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.unsuspended', $tenant, SuperAdminAuditLogger::fieldsMetadata(['is_suspended']), source: static::class ); return response()->json(['ok' => $updated]); } public function scheduleDeletion(SupportTenantScheduleDeletionRequest $request, Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $plannedDeletion = Carbon::parse($request->string('pending_deletion_at')->value()); $update = [ 'pending_deletion_at' => $plannedDeletion, ]; if ($request->boolean('send_warning', true)) { $email = $tenant->contact_email ?? $tenant->email ?? $tenant->user?->email; if ($email) { NotificationFacade::route('mail', $email) ->notify(new InactiveTenantDeletionWarning($tenant, $plannedDeletion)); $update['deletion_warning_sent_at'] = now(); } else { Notification::make() ->danger() ->title(__('admin.tenants.actions.send_warning_missing_title')) ->body(__('admin.tenants.actions.send_warning_missing_body')) ->send(); } } $tenant->forceFill($update)->save(); app(TenantLifecycleLogger::class)->record( $tenant, 'deletion_scheduled', [ 'pending_deletion_at' => $plannedDeletion->toDateTimeString(), 'send_warning' => $request->boolean('send_warning', true), ], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.deletion_scheduled', $tenant, SuperAdminAuditLogger::fieldsMetadata($request->validated()), source: static::class ); return response()->json(['ok' => true]); } public function cancelDeletion(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $previous = $tenant->pending_deletion_at?->toDateTimeString(); $tenant->forceFill([ 'pending_deletion_at' => null, 'deletion_warning_sent_at' => null, ])->save(); app(TenantLifecycleLogger::class)->record( $tenant, 'deletion_cancelled', ['pending_deletion_at' => $previous], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.deletion_cancelled', $tenant, SuperAdminAuditLogger::fieldsMetadata(['pending_deletion_at', 'deletion_warning_sent_at']), source: static::class ); return response()->json(['ok' => true]); } public function anonymize(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } AnonymizeAccount::dispatch(null, $tenant->id); app(TenantLifecycleLogger::class)->record( $tenant, 'anonymize_requested', actor: auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.anonymize_requested', $tenant, SuperAdminAuditLogger::fieldsMetadata([]), source: static::class ); return response()->json(['ok' => true]); } public function addPackage(SupportTenantAddPackageRequest $request, Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $package = Package::query()->find($request->integer('package_id')); TenantPackage::query()->create([ 'tenant_id' => $tenant->id, 'package_id' => $request->integer('package_id'), 'expires_at' => $request->date('expires_at'), 'active' => true, 'price' => $package?->price ?? 0, 'reason' => $request->string('reason')->value(), ]); PackagePurchase::query()->create([ 'tenant_id' => $tenant->id, 'package_id' => $request->integer('package_id'), 'provider' => 'manual', 'provider_id' => 'manual', 'type' => 'reseller_subscription', 'price' => 0, 'metadata' => ['reason' => $request->string('reason')->value() ?: 'manual assignment'], ]); app(SuperAdminAuditLogger::class)->record( 'tenant.package_added', $tenant, SuperAdminAuditLogger::fieldsMetadata($request->validated()), source: static::class ); return response()->json(['ok' => true]); } public function updateLimits(SupportTenantUpdateLimitsRequest $request, Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $before = [ 'max_photos_per_event' => $tenant->max_photos_per_event, 'max_storage_mb' => $tenant->max_storage_mb, ]; $tenant->forceFill([ 'max_photos_per_event' => $request->integer('max_photos_per_event'), 'max_storage_mb' => $request->integer('max_storage_mb'), ])->save(); $after = [ 'max_photos_per_event' => $tenant->max_photos_per_event, 'max_storage_mb' => $tenant->max_storage_mb, ]; app(TenantLifecycleLogger::class)->record( $tenant, 'limits_updated', [ 'before' => $before, 'after' => $after, 'note' => $request->string('note')->value(), ], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.limits_updated', $tenant, SuperAdminAuditLogger::fieldsMetadata($request->validated()), source: static::class ); return response()->json(['ok' => true]); } public function updateSubscriptionExpiresAt(SupportTenantUpdateSubscriptionRequest $request, Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $before = [ 'subscription_expires_at' => optional($tenant->subscription_expires_at)->toDateTimeString(), ]; $tenant->forceFill([ 'subscription_expires_at' => $request->date('subscription_expires_at'), ])->save(); $after = [ 'subscription_expires_at' => optional($tenant->subscription_expires_at)->toDateTimeString(), ]; app(TenantLifecycleLogger::class)->record( $tenant, 'subscription_expires_at_updated', [ 'before' => $before, 'after' => $after, 'note' => $request->string('note')->value(), ], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.subscription_expires_at_updated', $tenant, SuperAdminAuditLogger::fieldsMetadata($request->validated()), source: static::class ); return response()->json(['ok' => true]); } public function setGracePeriod(SupportTenantSetGracePeriodRequest $request, Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $tenant->forceFill([ 'grace_period_ends_at' => $request->date('grace_period_ends_at'), ])->save(); app(TenantLifecycleLogger::class)->record( $tenant, 'grace_period_set', [ 'grace_period_ends_at' => optional($tenant->grace_period_ends_at)->toDateTimeString(), 'note' => $request->string('note')->value(), ], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.grace_period_set', $tenant, SuperAdminAuditLogger::fieldsMetadata($request->validated()), source: static::class ); return response()->json(['ok' => true]); } public function clearGracePeriod(Tenant $tenant): JsonResponse { if ($response = $this->authorizeAction('tenants', 'actions')) { return $response; } $previous = $tenant->grace_period_ends_at?->toDateTimeString(); $tenant->forceFill([ 'grace_period_ends_at' => null, ])->save(); app(TenantLifecycleLogger::class)->record( $tenant, 'grace_period_cleared', [ 'grace_period_ends_at' => $previous, ], auth()->user() ); app(SuperAdminAuditLogger::class)->record( 'tenant.grace_period_cleared', $tenant, SuperAdminAuditLogger::fieldsMetadata(['grace_period_ends_at']), source: static::class ); return response()->json(['ok' => true]); } private function authorizeAction(string $resource, string $action): ?JsonResponse { return SupportApiAuthorizer::authorizeResource(request(), $resource, $action); } }