validated('token')); // Artist portal token lives on artist_engagements (per RFC-TIMETABLE // v0.2 §5.3); join to artists for the master name. $row = DB::table('artist_engagements') ->join('artists', 'artists.id', '=', 'artist_engagements.artist_id') ->where('artist_engagements.portal_token', $hashedToken) ->select( 'artist_engagements.id as id', 'artist_engagements.event_id as event_id', 'artist_engagements.booking_status as booking_status', 'artists.name as name', ) ->first(); if ($row) { $event = Event::withoutGlobalScope(OrganisationScope::class)->find($row->event_id); return response()->json([ 'context' => 'artist', 'data' => [ 'id' => $row->id, 'name' => $row->name, 'booking_status' => $row->booking_status, ], 'event' => $event ? new PortalEventResource($event) : null, ]); } // Try production_requests table (may not exist yet) try { $productionRequest = DB::table('production_requests')->where('token', $hashedToken)->first(); if ($productionRequest) { $event = Event::withoutGlobalScope(OrganisationScope::class)->find($productionRequest->event_id); return response()->json([ 'context' => 'supplier', 'data' => [ 'id' => $productionRequest->id, 'name' => $productionRequest->name ?? null, ], 'event' => $event ? new PortalEventResource($event) : null, ]); } } catch (\Illuminate\Database\QueryException) { // Table doesn't exist yet — skip } return response()->json([ 'message' => 'Invalid or expired portal token', ], 401); } }