$payload site_code, code, name, username, password, email?, status?, profile fields * @return array{site: AdminSite, agent_node: AgentNode} */ public function createRootAgent(AdminUser $actor, array $payload): array { $siteCode = strtolower(trim((string) ($payload['site_code'] ?? ''))); $code = strtolower(trim((string) ($payload['code'] ?? ''))); $name = trim((string) ($payload['name'] ?? '')); $username = trim((string) ($payload['username'] ?? '')); $password = (string) ($payload['password'] ?? ''); $email = isset($payload['email']) ? trim((string) $payload['email']) : null; $status = (int) ($payload['status'] ?? 1); if ($siteCode === '' || $code === '' || $name === '' || $username === '' || $password === '') { throw ValidationException::withMessages([ 'site_code' => $siteCode === '' ? ['required'] : [], 'code' => $code === '' ? ['required'] : [], 'name' => $name === '' ? ['required'] : [], 'username' => $username === '' ? ['required'] : [], 'password' => $password === '' ? ['required'] : [], ]); } $site = AdminSite::query()->where('code', $siteCode)->first(); if ($site === null) { throw ValidationException::withMessages(['site_code' => ['exists']]); } if (AgentNode::query()->where('code', $code)->exists()) { throw ValidationException::withMessages(['code' => ['unique']]); } if (AdminUser::query()->where('username', $username)->exists()) { throw ValidationException::withMessages(['username' => ['unique']]); } $existingRoot = AgentNode::query() ->where('admin_site_id', $site->id) ->where('depth', 0) ->first(); if ($existingRoot !== null) { throw ValidationException::withMessages([ 'site_code' => ['site_root_exists'], ]); } return DB::transaction(function () use ($actor, $site, $code, $name, $username, $password, $email, $status, $payload): array { $node = AgentNode::query()->create([ 'admin_site_id' => $site->id, 'parent_id' => null, 'path' => '/', 'depth' => 0, 'code' => $code, 'name' => $name, 'status' => $status === 0 ? 0 : 1, 'created_by' => $actor->id, 'extra_json' => null, ]); $node->path = '/'.$node->id.'/'; $node->save(); AgentPlatformRole::resolve(); $user = AdminUser::query()->create([ 'username' => $username, 'name' => $name, 'email' => $email !== '' ? $email : null, 'password' => $password, 'status' => AdminUserStatus::fromAgentNodeStatus($status === 0 ? 0 : 1), ]); DB::table('admin_user_agents')->insert([ 'admin_user_id' => $user->id, 'agent_node_id' => $node->id, 'is_primary' => true, 'granted_at' => now(), ]); AgentPlatformRole::assignPrimaryOperator($user, $node); $defaults = config('agent_line_defaults', []); $this->agentProfileService->upsertForNode($node, [ 'total_share_rate' => (float) ($payload['total_share_rate'] ?? $defaults['total_share_rate'] ?? 100), 'credit_limit' => (int) ($payload['credit_limit'] ?? $defaults['credit_limit'] ?? 0), 'rebate_limit' => (float) ($payload['rebate_limit'] ?? $defaults['rebate_limit'] ?? 0), 'default_player_rebate' => (float) ($payload['default_player_rebate'] ?? $defaults['default_player_rebate'] ?? 0), 'settlement_cycle' => (string) ($payload['settlement_cycle'] ?? $defaults['settlement_cycle'] ?? 'weekly'), 'can_grant_extra_rebate' => (bool) ($payload['can_grant_extra_rebate'] ?? true), 'can_create_child_agent' => (bool) ($payload['can_create_child_agent'] ?? true), 'can_create_player' => (bool) ($payload['can_create_player'] ?? true), ]); return [ 'site' => $site->fresh(), 'agent_node' => $node->fresh(['adminSite']), ]; }); } }