{"openapi":"3.1.0","info":{"title":"Weloz API - App Motorista","version":"1.0.0","description":"\nAPI para o aplicativo do **Motorista** - quem realiza as entregas.\n\n## 🔐 Autenticação\n\n1. Faça login no Firebase (Google, Apple, Email)\n2. Envie o `idToken` para `POST /api/auth/firebase/exchange` com role `DRIVER`\n3. Use o `accessToken` no header `Authorization: Bearer {token}`\n\n## 🚗 Cadastro de Motorista\n\nApós o login, complete seu perfil com:\n- `POST /api/auth/add-driver-profile` - Dados do veículo e CNH\n\n## 📍 Fluxo de Entrega\n\n1. Consulte entregas disponíveis: `GET /api/driver/deliveries/available`\n2. Aceite uma entrega: `POST /api/driver/deliveries/{id}/accept`\n3. Ao chegar no ponto de coleta: `PATCH /api/driver/deliveries/{id}/status` com `WAITING_AT_PICKUP`\n4. Envie a foto de coleta: `POST /api/driver/deliveries/{id}/proofs/pickup/photo`\n5. Registre a prova de coleta: `POST /api/driver/deliveries/{id}/proofs/pickup` (photoUrl obrigatório)\n6. Confirme a retirada com o código do remetente: `POST /api/driver/deliveries/{id}/collect`\n7. Inicie o transporte: `PATCH /api/driver/deliveries/{id}/status` com `IN_TRANSIT`\n8. Sem destinatário presente: envie a foto de entrega `POST /api/driver/deliveries/{id}/proofs/delivery/photo` e registre `POST .../proofs/delivery` com a URL retornada\n9. Conclua a entrega: `PATCH /api/driver/deliveries/{id}/status` com `DELIVERED`\n10. Mantenha sua localização atualizada: `PATCH /api/driver/location`\n    "},"servers":[{"url":"http://localhost:3001","description":"Desenvolvimento"},{"url":"https://api.weloz.com.br","description":"Produção"}],"tags":[{"name":"Auth","description":"Autenticação"},{"name":"Profile","description":"Perfil do motorista"},{"name":"Deliveries","description":"Gerenciamento de entregas"},{"name":"Location","description":"Localização"},{"name":"Payouts","description":"Repasses do motorista"},{"name":"Documents","description":"Documentos de onboarding do motorista"},{"name":"Earnings","description":"Resumo de ganhos do motorista"},{"name":"Vehicles","description":"Sugestão de capacidade do veículo"},{"name":"Trips","description":"Trajeto/rota declarada pelo motorista"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"🔐 JWT obtido via `/api/auth/firebase/exchange`"}},"schemas":{"DriverPayoutAccountStatus":{"type":"object","required":["provider","status","canReceiveTransfers","actionRequired","requirements"],"properties":{"provider":{"type":"string","enum":["stripe"]},"status":{"type":"string","enum":["NOT_CREATED","ONBOARDING_PENDING","UNDER_REVIEW","READY","RESTRICTED","DISABLED"]},"canReceiveTransfers":{"type":"boolean"},"actionRequired":{"type":"boolean"},"statusReason":{"type":["string","null"]},"requirements":{"type":"array","items":{"type":"string"}},"lastSyncedAt":{"type":["string","null"],"format":"date-time"}}},"UserRole":{"type":"string","enum":["ADMIN","DRIVER","SENDER","RECIPIENT"],"description":"Papel/perfil do usuário no sistema"},"DeliveryStatus":{"type":"string","enum":["PENDING","ACCEPTED","IN_TRANSIT","DELIVERED","CANCELLED"],"description":"Status da entrega"},"VehicleType":{"type":"string","enum":["MOTORCYCLE","CAR","VAN","TRUCK"],"description":"Tipo de veículo"},"VehicleBodyCategory":{"type":"string","enum":["MOTORCYCLE","HATCH","SEDAN","SUV","VAN","TRUCK"],"description":"Categoria de carroceria para capacidade de porta-malas"},"VehicleCapacitySource":{"type":"string","enum":["CATALOG","CATEGORY_FALLBACK","MANUAL"],"description":"Origem da capacidade sugerida ou persistida"},"ProductType":{"type":"string","enum":["ELECTRONICS","CLOTHING","FOOD","DOCUMENTS","FURNITURE","AUTO_PARTS","BEAUTY","SPORTS","TOYS","BOOKS","MEDICINE","FRAGILE","OTHER"],"description":"Tipo de produto para transporte"},"ItemLabel":{"type":"string","enum":["NO_RESTRICTION","FRAGILE","KEEP_UPRIGHT","DO_NOT_STACK","TEMPERATURE_CTRL","HAZARDOUS","PERISHABLE","HIGH_VALUE","LIQUID","FLAMMABLE","HANDLE_WITH_CARE"],"description":"Etiquetas do item. HAZARDOUS e FLAMMABLE são proibidas. HIGH_VALUE (ou valor >= ITEM_HIGH_VALUE_THRESHOLD) exige motorista profissional verificado."},"ItemStatus":{"type":"string","enum":["DRAFT","PENDING","IN_DELIVERY","DELIVERED","CANCELLED"],"description":"Status do item cadastrado"},"DriverApprovalDocumentNormalizedType":{"type":"string","enum":["DRIVER_LICENSE_FRONT","DRIVER_LICENSE_BACK","SELFIE_WITH_DOCUMENT","DRIVER_LICENSE_COMBINED","VEHICLE_REGISTRATION","PROOF_OF_ADDRESS","PROFILE_PHOTO","INSURANCE","OTHER"],"description":"Tipo normalizado para análise documental no painel admin. DRIVER_LICENSE_COMBINED representa legado onde frente e verso chegaram em um único arquivo."},"DriverApprovalDocument":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"normalizedType":{"$ref":"#/components/schemas/DriverApprovalDocumentNormalizedType"},"fileUrl":{"type":"string","format":"uri"},"fileName":{"type":["string","null"]},"uploadedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"}},"required":["id","type","normalizedType","fileUrl","uploadedAt"]},"PendingDriverApproval":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"approvalStatus":{"type":"string","enum":["PENDING_DOCUMENTS","PENDING_APPROVAL","APPROVED","REJECTED","PERMANENTLY_DENIED","SUSPENDED"]},"approvalNotes":{"type":["string","null"]},"reapplyAvailableAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"},"vehiclePlate":{"type":["string","null"]},"vehicleModel":{"type":["string","null"]},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayName":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["id"]},"documents":{"type":"array","items":{"$ref":"#/components/schemas/DriverApprovalDocument"}}},"required":["id","approvalStatus","createdAt","vehicleType","user","documents"]},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"firebaseUid":{"type":"string"},"email":{"type":"string","format":"email"},"displayName":{"type":"string"},"phone":{"type":"string"},"roles":{"type":"array","items":{"$ref":"#/components/schemas/UserRole"}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"UserProfile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"displayName":{"type":"string"},"phone":{"type":"string"},"roles":{"type":"array","items":{"$ref":"#/components/schemas/UserRole"}},"mobileRoles":{"type":"array","description":"Subset de roles voltadas ao app mobile. Exclui ADMIN e mantém apenas DRIVER, SENDER e RECIPIENT.","items":{"type":"string","enum":["DRIVER","SENDER","RECIPIENT"]}},"activeRole":{"allOf":[{"$ref":"#/components/schemas/UserRole"}],"nullable":true,"description":"Role ativa resolvida para a sessão atual. Vem do access token autenticado da requisição."},"driverProfile":{"$ref":"#/components/schemas/DriverProfile"},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/Address"}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"DriverProfile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"},"vehiclePlate":{"type":"string"},"vehicleBrand":{"type":"string","nullable":true},"vehicleModel":{"type":"string"},"vehicleYear":{"type":"integer"},"vehicleColor":{"type":"string"},"vehicleBodyCategory":{"allOf":[{"$ref":"#/components/schemas/VehicleBodyCategory"}],"nullable":true},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"capacitySource":{"allOf":[{"$ref":"#/components/schemas/VehicleCapacitySource"}],"nullable":true},"capacitySourceLabel":{"type":"string","nullable":true},"driverLicense":{"type":"string"},"licenseExpiry":{"type":"string","format":"date-time"},"currentLatitude":{"type":"number"},"currentLongitude":{"type":"number"},"isAvailable":{"type":"boolean"},"notificationRadiusKm":{"type":"integer","minimum":1,"maximum":30,"default":8},"isDeliveryNotificationPaused":{"type":"boolean","default":false},"notificationPausedAt":{"type":"string","format":"date-time","nullable":true},"totalDeliveries":{"type":"integer"},"completedDeliveries":{"type":"integer","description":"Quantidade de entregas com status DELIVERED. Score complementar de viagens bem-sucedidas; independente de avaliação e de totalDeliveries."},"averageRating":{"type":"number","nullable":true,"description":"Média das avaliações (1 a 5). null quando o motorista ainda não foi avaliado."},"ratingsCount":{"type":"integer","description":"Quantidade de avaliações recebidas. 0 quando ainda não há avaliações."},"isProfessionalVerified":{"type":"boolean","description":"Flag distinta da KYC básica; habilita cargas de alto valor"}}},"DriverNotificationPreferences":{"type":"object","required":["notificationRadiusKm","isDeliveryNotificationPaused","notificationPausedAt","updatedAt"],"properties":{"notificationRadiusKm":{"type":"integer","minimum":1,"maximum":30,"default":8},"isDeliveryNotificationPaused":{"type":"boolean","default":false},"notificationPausedAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"}}},"DriverNotificationPreferencesUpdateRequest":{"type":"object","properties":{"notificationRadiusKm":{"type":"integer","minimum":1,"maximum":30},"isDeliveryNotificationPaused":{"type":"boolean"}},"additionalProperties":false,"description":"Envie pelo menos um campo para atualizar. notificationPausedAt e calculado pelo backend."},"Address":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":"string","description":"Ex: Casa, Trabalho"},"street":{"type":"string"},"number":{"type":"string"},"complement":{"type":"string"},"neighborhood":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipCode":{"type":"string"},"country":{"type":"string","default":"BR"},"latitude":{"type":"number"},"longitude":{"type":"number"},"isDefault":{"type":"boolean"}}},"TokenResponse":{"type":"object","properties":{"accessToken":{"type":"string","description":"JWT de acesso (expira em 15 min)"},"refreshToken":{"type":"string","description":"Token para renovar acesso (30 dias)"},"expiresIn":{"type":"integer","description":"Segundos até expirar","example":900},"user":{"$ref":"#/components/schemas/UserProfile"}}},"Item":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"name":{"type":"string"},"productType":{"$ref":"#/components/schemas/ProductType"},"description":{"type":"string"},"declaredValue":{"type":"number"},"height":{"type":"number","description":"Altura em cm"},"width":{"type":"number","description":"Largura em cm"},"length":{"type":"number","description":"Comprimento em cm"},"weight":{"type":"number","description":"Peso em kg"},"labels":{"type":"array","items":{"$ref":"#/components/schemas/ItemLabel"}},"status":{"$ref":"#/components/schemas/ItemStatus"},"photos":{"type":"array","items":{"$ref":"#/components/schemas/ItemPhoto"}},"documents":{"type":"array","items":{"$ref":"#/components/schemas/ItemDocument"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ItemPhoto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"filename":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer","description":"Tamanho em bytes"},"order":{"type":"integer"}}},"ItemDocument":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["invoice","receipt","other"]},"url":{"type":"string","format":"uri"},"filename":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer"}}},"ItemListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}},"Delivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"senderId":{"type":"string","format":"uuid"},"recipientId":{"type":"string","format":"uuid"},"driverId":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/DeliveryStatus"},"pickupAddress":{"type":"string"},"pickupLatitude":{"type":"number"},"pickupLongitude":{"type":"number"},"pickupContactName":{"type":"string"},"pickupContactPhone":{"type":"string"},"deliveryAddress":{"type":"string"},"deliveryLatitude":{"type":"number"},"deliveryLongitude":{"type":"number"},"deliveryContactName":{"type":"string"},"deliveryContactPhone":{"type":"string"},"itemDescription":{"type":"string"},"itemWeight":{"type":"number"},"itemValue":{"type":"number"},"itemLength":{"type":"number"},"itemWidth":{"type":"number"},"itemHeight":{"type":"number"},"trackingCode":{"type":"string"},"notes":{"type":"string"},"item":{"type":"object","nullable":true,"description":"Item vinculado à entrega (quando existir)","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"order":{"type":"integer"}}}}}},"requiresProfessionalDriver":{"type":"boolean","description":"True quando o item é HIGH_VALUE ou o valor declarado atinge ITEM_HIGH_VALUE_THRESHOLD"},"vehicleTypeNeeded":{"$ref":"#/components/schemas/VehicleType"},"distance":{"type":"number","description":"Distância em km"},"estimatedDuration":{"type":"integer","description":"Duração em minutos"},"basePrice":{"type":"number"},"weightPrice":{"type":"number"},"volumePrice":{"type":"number"},"estimatedPrice":{"type":"number"},"finalPrice":{"type":"number"},"scheduledPickupTime":{"type":"string","format":"date-time"},"pickupTime":{"type":"string","format":"date-time"},"deliveryTime":{"type":"string","format":"date-time"},"recipientConfirmedAt":{"type":"string","format":"date-time"},"estimatedArrivalAt":{"type":"string","format":"date-time"},"possiblyStuckAt":{"type":"string","format":"date-time","nullable":true,"description":"WELOZ-34: set when the driver appears stopped with the package (IN_TRANSIT)"},"stuckDetectedDriverId":{"type":"string","format":"uuid","nullable":true,"description":"Driver who had custody when the stuck signal was raised"},"stuckLatitude":{"type":"number","nullable":true},"stuckLongitude":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"tripId":{"type":"string","format":"uuid"},"stopOrder":{"type":"integer","description":"Ordem de entrega no trajeto ativo"},"tripItinerary":{"$ref":"#/components/schemas/TripItinerary"},"verificationCodes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"purpose":{"type":"string","enum":["PICKUP","DELIVERY"]},"status":{"type":"string","enum":["ACTIVE","VERIFIED","EXPIRED","CANCELLED"]},"expiresAt":{"type":"string","format":"date-time"},"verifiedAt":{"type":"string","format":"date-time"}}}}}},"TrackingHistory":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/DeliveryStatus"},"latitude":{"type":"number"},"longitude":{"type":"number"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"CreateRatingRequest":{"type":"object","required":["rating"],"properties":{"rating":{"type":"integer","minimum":1,"maximum":5,"description":"Nota inteira de 1 a 5 estrelas. A avaliação é opcional."},"comment":{"type":"string","description":"Campo opcional já existente no modelo; não é obrigatório."}}},"CreateRatingResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"rating":{"type":"integer","minimum":1,"maximum":5},"comment":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Rating":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"rating":{"type":"integer","minimum":1,"maximum":5},"comment":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"displayName":{"type":"string"}}}}},"DeliveryListResponse":{"type":"object","required":["items","page","limit","total","hasMore"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"page":{"type":"integer","minimum":1},"limit":{"type":"integer","minimum":1,"maximum":100},"total":{"type":"integer","minimum":0},"hasMore":{"type":"boolean"}}},"DeliveryCustodyRecord":{"type":"object","required":["id","deliveryId","driverId","startedAt"],"properties":{"id":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"},"driverId":{"type":"string","format":"uuid"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","format":"date-time","nullable":true},"reason":{"type":"string","nullable":true,"description":"Motivo do encerramento do período de custódia"}}},"TransferDeliveryRequest":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":5,"maxLength":500,"description":"Motivo pelo qual o motorista atual não consegue continuar a entrega","example":"Imprevisto no trajeto. Não consigo concluir a entrega."}}},"RouteOffer":{"type":"object","description":"Oferta de encomenda compatível com o trajeto do motorista (matching por corredor, WELOZ-25)","properties":{"id":{"type":"string","format":"uuid"},"pickup":{"type":"object","properties":{"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["address","latitude","longitude"]},"dropoff":{"type":"object","properties":{"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["address","latitude","longitude"]},"item":{"type":"object","properties":{"description":{"type":"string"},"weightKg":{"type":"number"},"lengthCm":{"type":"number","nullable":true},"widthCm":{"type":"number","nullable":true},"heightCm":{"type":"number","nullable":true},"volumeLiters":{"type":"number"}},"required":["description","weightKg","volumeLiters"]},"driverEarnings":{"type":"object","properties":{"amount":{"type":"number","description":"Valor que o motorista receberá (BRL)"},"currency":{"type":"string","example":"BRL"}},"required":["amount","currency"]},"packageDistanceKm":{"type":"number","nullable":true},"detourKm":{"type":"number","nullable":true,"description":"Desvio do trajeto (soma das distâncias pickup/dropoff até a polyline)"},"vehicleTypeNeeded":{"$ref":"#/components/schemas/VehicleType","nullable":true}},"required":["id","pickup","dropoff","item","driverEarnings"]},"FreightCalculationRequest":{"type":"object","required":["pickupAddress","deliveryAddress","weight"],"properties":{"pickupAddress":{"type":"string","description":"Endereço de coleta"},"deliveryAddress":{"type":"string","description":"Endereço de entrega"},"weight":{"type":"number","description":"Peso em kg"},"length":{"type":"number","description":"Comprimento em cm"},"width":{"type":"number","description":"Largura em cm"},"height":{"type":"number","description":"Altura em cm"},"declaredValue":{"type":"number","description":"Valor declarado"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"}}},"FreightCalculationResponse":{"type":"object","properties":{"distance":{"type":"number","description":"Distância em km"},"estimatedDuration":{"type":"integer","description":"Duração em minutos"},"basePrice":{"type":"number"},"weightPrice":{"type":"number"},"volumePrice":{"type":"number"},"totalPrice":{"type":"number"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"}}},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Código do erro (fonte única: domain/constants.ts)","enum":["UNAUTHORIZED","INVALID_TOKEN","EMAIL_NOT_VERIFIED","ACCOUNT_LINK_REQUIRED","TOKEN_EXPIRED","FORBIDDEN","USER_NOT_FOUND","USER_ALREADY_EXISTS","USER_INACTIVE","MEMBERSHIP_NOT_FOUND","INVALID_REQUEST","MISSING_REQUIRED_FIELDS","INVALID_FORMAT","INVALID_ROLE","NOT_FOUND","DELIVERY_NOT_FOUND","DELIVERY_ALREADY_ACCEPTED","DELIVERY_PAYMENT_NOT_AUTHORIZED","DELIVERY_PAYMENT_AUTHORIZATION_EXPIRED","DELIVERY_CANNOT_BE_CANCELLED","DELIVERY_CANNOT_BE_TRANSFERRED","DELIVERY_NOT_AVAILABLE_FOR_HANDOFF","DRIVER_CANNOT_REASSUME_TRANSFER","DELIVERY_ALREADY_CONFIRMED","DELIVERY_CANNOT_BE_CONFIRMED","DELIVERY_PROOF_REQUIRED","DELIVERY_VERIFICATION_CODE_REQUIRED","INVALID_DELIVERY_VERIFICATION_CODE","DELIVERY_VERIFICATION_CODE_EXPIRED","REVERSE_DELIVERY_NOT_FOUND","INVALID_DELIVERY_STATUS","INVALID_STATUS_TRANSITION","DRIVER_NOT_FOUND","DRIVER_NOT_AVAILABLE","DRIVER_PROFILE_NOT_FOUND","DRIVER_ROUTE_NOT_FOUND","DRIVER_LOCATION_REQUIRED","TRIP_ALREADY_ACTIVE","TRIP_NOT_FOUND","VEHICLE_CAPACITY_UNAVAILABLE","ACTIVE_TRIP_REQUIRED","CAPACITY_EXCEEDED","TIER_ITEM_LIMIT_EXCEEDED","DRIVER_PAYOUT_ACCOUNT_INCOMPLETE","RATING_ALREADY_EXISTS","PAYMENT_NOT_FOUND","PAYOUT_NOT_FOUND","INCIDENT_NOT_FOUND","CHECKOUT_SESSION_NOT_FOUND","QUOTE_NOT_FOUND","QUOTE_EXPIRED","QUOTE_ALREADY_USED","ITEM_NOT_FOUND","ITEM_ALREADY_IN_DELIVERY","PROHIBITED_ITEM","DRIVER_NOT_PROFESSIONALLY_VERIFIED","DRIVER_NOT_APPROVED","ETA_NOT_AVAILABLE","INTERNAL_ERROR","CONFLICT","SERVICE_UNAVAILABLE"]},"message":{"type":"string","description":"Mensagem de erro"},"details":{"type":"object","additionalProperties":true,"description":"Detalhes adicionais do erro"}},"required":["error","message"]},"ValidationError":{"type":"object","properties":{"error":{"type":"string","enum":["INVALID_REQUEST"],"example":"INVALID_REQUEST"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}}},"City":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","example":"São Paulo"},"state":{"type":"string","minLength":2,"maxLength":2,"example":"SP","description":"UF (sigla de 2 letras maiúsculas)"},"ibgeCode":{"type":"string","nullable":true,"example":"3550308","description":"Código IBGE de 7 dígitos (opcional)"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","state","isActive","createdAt","updatedAt"]},"CreateCityRequest":{"type":"object","required":["name","state"],"properties":{"name":{"type":"string","minLength":2,"maxLength":120},"state":{"type":"string","minLength":2,"maxLength":2},"ibgeCode":{"type":"string","pattern":"^\\d{7}$","nullable":true},"isActive":{"type":"boolean","default":true}}},"UpdateCityRequest":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":120},"state":{"type":"string","minLength":2,"maxLength":2},"ibgeCode":{"type":"string","pattern":"^\\d{7}$","nullable":true},"isActive":{"type":"boolean"}}},"CityListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/City"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"},"totalPages":{"type":"integer"}},"required":["items","total","page","limit","totalPages"]},"CityPricing":{"type":"object","properties":{"id":{"type":"string"},"cityId":{"type":"string"},"pricePerKmCents":{"type":"integer","minimum":1,"description":"Valor por km rodado em centavos"},"minFareCents":{"type":"integer","minimum":0,"description":"Tarifa mínima em centavos"},"baseFareCents":{"type":"integer","minimum":0,"description":"Tarifa fixa de bandeirada em centavos"},"driverShareBps":{"type":"integer","minimum":0,"maximum":10000,"description":"Percentual repassado ao motorista em basis points (8000 = 80%)"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","cityId","pricePerKmCents","minFareCents","baseFareCents","driverShareBps","createdAt","updatedAt"]},"PricingSettings":{"type":"object","properties":{"motorcyclePricePerKm":{"type":"number","example":1.5},"carPricePerKm":{"type":"number","example":2},"vanPricePerKm":{"type":"number","example":3},"truckPricePerKm":{"type":"number","example":4.5},"platformFeeBps":{"type":"integer","minimum":0,"maximum":10000,"example":2000},"insuranceRate":{"type":"number","example":0.02},"isDefault":{"type":"boolean"}},"required":["motorcyclePricePerKm","carPricePerKm","vanPricePerKm","truckPricePerKm","platformFeeBps","insuranceRate","isDefault"]},"UpsertCityPricingRequest":{"type":"object","required":["pricePerKmCents"],"properties":{"pricePerKmCents":{"type":"integer","minimum":1},"minFareCents":{"type":"integer","minimum":0},"baseFareCents":{"type":"integer","minimum":0},"driverShareBps":{"type":"integer","minimum":0,"maximum":10000}}},"DeliveryRecipientRejection":{"type":"object","properties":{"id":{"type":"string"},"deliveryId":{"type":"string","format":"uuid"},"rejectedBy":{"type":"string"},"reason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","deliveryId","rejectedBy","createdAt"]},"DeliveryDriverRejection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"},"driverId":{"type":"string","format":"uuid"},"reason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","deliveryId","driverId","reason","createdAt","updatedAt"]},"DeliveryRescheduleRequest":{"type":"object","properties":{"id":{"type":"string"},"deliveryId":{"type":"string","format":"uuid"},"requestedBy":{"type":"string"},"proposedTime":{"type":"string","format":"date-time"},"reason":{"type":"string","nullable":true},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED","CANCELLED"]},"decidedBy":{"type":"string","nullable":true},"decidedAt":{"type":"string","format":"date-time","nullable":true},"decisionNote":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","deliveryId","requestedBy","proposedTime","status","createdAt","updatedAt"]},"DeliveryAddressChange":{"type":"object","properties":{"id":{"type":"string"},"deliveryId":{"type":"string","format":"uuid"},"requestedBy":{"type":"string"},"proposedAddress":{"type":"string"},"proposedLatitude":{"type":"number"},"proposedLongitude":{"type":"number"},"reason":{"type":"string","nullable":true},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED","CANCELLED"]},"decidedBy":{"type":"string","nullable":true},"decidedAt":{"type":"string","format":"date-time","nullable":true},"decisionNote":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","deliveryId","requestedBy","proposedAddress","proposedLatitude","proposedLongitude","status","createdAt","updatedAt"]},"DeliveryAddressChangeListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryAddressChange"}}},"required":["items"]},"DeliveryRescheduleRequestListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryRescheduleRequest"}}},"required":["items"]},"VehicleModelCapacity":{"type":"object","properties":{"id":{"type":"string"},"brand":{"type":"string"},"model":{"type":"string"},"yearStart":{"type":"integer","nullable":true},"yearEnd":{"type":"integer","nullable":true},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"source":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"confidence":{"type":"string","nullable":true},"isActive":{"type":"boolean"}}},"VehicleCategoryCapacity":{"type":"object","properties":{"id":{"type":"string"},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true}}},"SuggestVehicleCapacityRequest":{"type":"object","required":["vehicleType"],"properties":{"plate":{"type":"string"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"},"brand":{"type":"string"},"model":{"type":"string"},"year":{"type":"integer"},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"trunkLiters":{"type":"number"},"maxWeightKg":{"type":"number"}}},"SuggestVehicleCapacityResponse":{"type":"object","properties":{"brand":{"type":"string","nullable":true},"model":{"type":"string","nullable":true},"year":{"type":"integer","nullable":true},"color":{"type":"string","nullable":true},"bodyCategory":{"allOf":[{"$ref":"#/components/schemas/VehicleBodyCategory"}],"nullable":true},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"source":{"allOf":[{"$ref":"#/components/schemas/VehicleCapacitySource"}],"nullable":true},"sourceLabel":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"needsManualDefinition":{"type":"boolean"},"isEstimate":{"type":"boolean"},"plateLookupUsed":{"type":"boolean"},"plateLookupProvider":{"type":"string","nullable":true},"matchedCatalogId":{"type":"string","nullable":true},"message":{"type":"string"}}},"CreateVehicleModelCapacityRequest":{"type":"object","required":["brand","model","bodyCategory"],"properties":{"brand":{"type":"string"},"model":{"type":"string"},"yearStart":{"type":"integer","nullable":true},"yearEnd":{"type":"integer","nullable":true},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"source":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"confidence":{"type":"string","nullable":true},"isActive":{"type":"boolean"}}},"UpdateVehicleModelCapacityRequest":{"type":"object","properties":{"brand":{"type":"string"},"model":{"type":"string"},"yearStart":{"type":"integer","nullable":true},"yearEnd":{"type":"integer","nullable":true},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"source":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"confidence":{"type":"string","nullable":true},"isActive":{"type":"boolean"}}},"VehicleModelCapacityListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VehicleModelCapacity"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"},"totalPages":{"type":"integer"}}},"UpsertVehicleCategoryCapacityRequest":{"type":"object","properties":{"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true}}},"OverrideDriverVehicleCapacityRequest":{"type":"object","properties":{"trunkLiters":{"type":"number","nullable":true},"maxWeightKg":{"type":"number","nullable":true},"bodyCategory":{"$ref":"#/components/schemas/VehicleBodyCategory"},"brand":{"type":"string"},"model":{"type":"string"},"year":{"type":"integer","nullable":true}}},"TripStop":{"type":"object","properties":{"sequence":{"type":"integer"},"type":{"type":"string","enum":["PICKUP","DROPOFF"]},"deliveryId":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"address":{"type":"string"},"estimatedArrivalAt":{"type":"string","format":"date-time"},"legDurationMinutes":{"type":"integer"}}},"TripItinerary":{"type":"object","description":"Trajeto com N entregas, capacidade restante e paradas recalculadas a cada aceite.","properties":{"tripId":{"type":"string"},"remainingCapacity":{"type":"object","properties":{"weightKg":{"type":"number"},"volumeLiters":{"type":"number"},"items":{"type":"integer"},"itemLimit":{"type":"integer"}}},"stops":{"type":"array","items":{"$ref":"#/components/schemas/TripStop"}},"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/DeliveryStatus"},"stopOrder":{"type":"integer","nullable":true},"estimatedArrivalAt":{"type":"string","format":"date-time","nullable":true}}}}}},"NotificationType":{"type":"string","enum":["DELIVERY_ACCEPTED","DELIVERY_CANCELLED_BY_DRIVER","DELIVERY_WAITING_AT_PICKUP","DELIVERY_IN_TRANSIT","DELIVERY_COMPLETED","PAYMENT_CAPTURED","PAYOUT_SCHEDULED","PAYOUT_PAID","INCIDENT_UPDATED","DRIVER_APPROVED","DRIVER_REJECTED","SYSTEM"]},"PushToken":{"type":"object","required":["id","userId","token","isActive","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"token":{"type":"string"},"platform":{"type":"string","enum":["ios","android","web"],"nullable":true},"deviceId":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RegisterPushTokenRequest":{"type":"object","required":["token"],"properties":{"token":{"type":"string","minLength":20},"platform":{"type":"string","enum":["ios","android","web"]},"deviceId":{"type":"string","maxLength":100}}},"DeactivatePushTokenRequest":{"type":"object","required":["token"],"properties":{"token":{"type":"string","minLength":20}}},"Notification":{"type":"object","required":["id","userId","type","title","body","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/NotificationType"},"title":{"type":"string"},"body":{"type":"string"},"data":{"type":"object","additionalProperties":true,"nullable":true},"readAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"NotificationListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"pagination":{"type":"object","required":["page","limit","total","unreadCount"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"unreadCount":{"type":"integer"}}}}}}},"paths":{"/api/driver/identity-verifications":{"post":{"operationId":"driverStartIdentityVerification","tags":["Identity verification"],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Estado da verificação de identidade"}}}},"/api/driver/identity-verifications/current":{"get":{"operationId":"driverGetCurrentIdentityVerification","tags":["Identity verification"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Estado da verificação de identidade"},"204":{"description":"Ainda não iniciada"}}}},"/api/driver/identity-verifications/current/submit":{"post":{"operationId":"driverSubmitIdentityVerification","tags":["Identity verification"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Estado da verificação de identidade"}}}},"/api/driver/identity-verifications/current/retry":{"post":{"operationId":"driverRetryIdentityVerification","tags":["Identity verification"],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Estado da verificação de identidade"}}}},"/api/driver/payment-account/status":{"get":{"operationId":"driverGetPayoutAccountStatus","tags":["Payouts"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Estado da conta de recebimentos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverPayoutAccountStatus"}}}}}}},"/api/driver/payment-account/onboarding":{"post":{"operationId":"driverStartPayoutAccountOnboarding","tags":["Payouts"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"URL temporária do onboarding Stripe"}}}},"/api/driver/deliveries/{deliveryId}/proofs/return/photo":{"post":{"operationId":"driverUploadReturnProofPhoto","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Foto da devolução enviada"}}}},"/api/driver/deliveries/{deliveryId}/proofs/return":{"post":{"operationId":"driverRegisterReturnProof","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Prova da devolução registrada"}}}},"/api/places/autocomplete":{"get":{"operationId":"placesAutocomplete","summary":"Autocomplete de lugares","tags":["Places"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2}},{"name":"lat","in":"query","required":false,"schema":{"type":"number"}},{"name":"lng","in":"query","required":false,"schema":{"type":"number"}},{"name":"sessionToken","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sugestões de lugares","content":{"application/json":{"schema":{"type":"object","properties":{"predictions":{"type":"array","items":{"type":"object","properties":{"placeId":{"type":"string"},"primaryText":{"type":"string"},"secondaryText":{"type":"string"},"description":{"type":"string"}}}}}}}}},"401":{"description":"Não autenticado"}}}},"/api/places/directions":{"get":{"operationId":"placesDrivingDirections","summary":"Trajeto rodoviário entre dois pontos","tags":["Places"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"originLat","in":"query","required":true,"schema":{"type":"number"}},{"name":"originLng","in":"query","required":true,"schema":{"type":"number"}},{"name":"destinationLat","in":"query","required":true,"schema":{"type":"number"}},{"name":"destinationLng","in":"query","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Geometria do trajeto","content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"array","items":{"type":"object","properties":{"latitude":{"type":"number"},"longitude":{"type":"number"}}}},"distanceKm":{"type":"number"},"durationMinutes":{"type":"number"},"encodedPolyline":{"type":"string"}}}}}},"401":{"description":"Não autenticado"}}}},"/api/places/{placeId}":{"get":{"operationId":"placesGetDetails","summary":"Detalhes de um lugar","tags":["Places"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"placeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Detalhes do lugar","content":{"application/json":{"schema":{"type":"object","properties":{"placeId":{"type":"string"},"name":{"type":"string"},"formattedAddress":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}}}}}},"401":{"description":"Não autenticado"}}}},"/api/auth/firebase/exchange":{"post":{"summary":"Login - Trocar Firebase Token","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["idToken"],"properties":{"idToken":{"type":"string"},"roles":{"type":"array","items":{"type":"string","enum":["DRIVER"]},"default":["DRIVER"]},"displayName":{"type":"string"},"phone":{"type":"string"}}},"examples":{"newDriver":{"summary":"Novo motorista","value":{"idToken":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...","roles":["DRIVER"],"displayName":"João Silva","phone":"+5511999999999"}}}}}},"responses":{"200":{"description":"Login realizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"401":{"description":"Token inválido"}}}},"/api/auth/refresh":{"post":{"summary":"Renovar token","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refreshToken"],"properties":{"refreshToken":{"type":"string"}}}}}},"responses":{"200":{"description":"Token renovado"},"401":{"description":"Token expirado"}}}},"/api/auth/logout":{"post":{"summary":"Logout","tags":["Auth"],"responses":{"200":{"description":"Logout realizado"}}}},"/api/auth/me":{"get":{"summary":"Meu perfil","description":"driverProfile inclui averageRating (null se não houver avaliações), ratingsCount e completedDeliveries (entregas DELIVERED). A resposta também reflete a activeRole da sessão e lista mobileRoles disponíveis para o app.","tags":["Profile"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Dados do perfil","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"description":"Não autenticado"}}}},"/api/auth/add-driver-profile":{"post":{"summary":"Cadastrar dados do veículo","description":"Adiciona veículo (marca, modelo, ano, cor, placa) e capacidade (litros + kg) para completar o cadastro de motorista.","tags":["Profile"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["vehicleType","vehiclePlate","vehicleBrand","vehicleModel","vehicleYear","vehicleColor","trunkLiters","maxWeightKg"],"properties":{"legalName":{"type":"string","example":"Maria da Silva"},"cpf":{"type":"string","example":"52998224725"},"phone":{"type":"string","example":"(44) 99999-9999"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"},"vehiclePlate":{"type":"string","example":"ABC1D23"},"vehicleBrand":{"type":"string","example":"Honda"},"vehicleModel":{"type":"string","example":"CG 160"},"vehicleYear":{"type":"integer","example":2022},"vehicleColor":{"type":"string","example":"Preta"},"trunkLiters":{"type":"number","example":40},"maxWeightKg":{"type":"number","example":20},"driverLicense":{"type":"string","example":"02650306461"},"licenseExpiry":{"type":"string","format":"date-time"}}},"examples":{"motorcycle":{"summary":"Motoboy","value":{"vehicleType":"MOTORCYCLE","vehiclePlate":"ABC1D23","vehicleBrand":"Honda","vehicleModel":"CG 160","vehicleYear":2022,"vehicleColor":"Preta","trunkLiters":40,"maxWeightKg":20,"legalName":"Maria da Silva","cpf":"52998224725","phone":"(44) 99999-9999","driverLicense":"02650306461"}},"car":{"summary":"Motorista de carro","value":{"vehicleType":"CAR","vehiclePlate":"XYZ1A23","vehicleBrand":"Fiat","vehicleModel":"Strada","vehicleYear":2021,"vehicleColor":"Branca","trunkLiters":300,"maxWeightKg":400,"legalName":"Maria da Silva","cpf":"52998224725","phone":"(44) 99999-9999","driverLicense":"02650306461"}}}}}},"responses":{"201":{"description":"Perfil de motorista criado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverProfile"}}}},"400":{"description":"Campos de veículo/capacidade inválidos ou ausentes"},"401":{"description":"Não autenticado"},"409":{"description":"Perfil já existe"}}}},"/api/driver/vehicle":{"patch":{"operationId":"driverUpdateVehicle","summary":"Atualizar veículo e capacidade","description":"Completa ou corrige dados do veículo e capacidade (litros + kg) no perfil de motorista existente. Disponível sem exigir aprovação DRIVER.","tags":["Profile","Drivers"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["vehicleType","vehiclePlate","vehicleBrand","vehicleModel","vehicleYear","vehicleColor","trunkLiters","maxWeightKg"],"properties":{"legalName":{"type":"string","example":"Maria da Silva"},"cpf":{"type":"string","example":"52998224725"},"phone":{"type":"string","example":"(44) 99999-9999"},"vehicleType":{"$ref":"#/components/schemas/VehicleType"},"vehiclePlate":{"type":"string","example":"ABC1D23"},"vehicleBrand":{"type":"string","example":"Fiat"},"vehicleModel":{"type":"string","example":"Argo"},"vehicleYear":{"type":"integer","example":2022},"vehicleColor":{"type":"string","example":"Prata"},"trunkLiters":{"type":"number","example":300},"maxWeightKg":{"type":"number","example":400},"driverLicense":{"type":"string"},"licenseExpiry":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Perfil atualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverProfile"}}}},"400":{"description":"Dados inválidos"},"401":{"description":"Não autenticado"},"403":{"description":"Negado permanentemente (fora da janela de reaplicação)"},"404":{"description":"Perfil de motorista não encontrado"}}}},"/api/auth/add-address":{"post":{"summary":"Adicionar endereço","tags":["Profile"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["street","number","neighborhood","city","state","zipCode"],"properties":{"label":{"type":"string","example":"Ponto de partida"},"street":{"type":"string"},"number":{"type":"string"},"neighborhood":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipCode":{"type":"string"}}}}}},"responses":{"201":{"description":"Endereço adicionado"}}}},"/api/driver/deliveries/available":{"get":{"operationId":"driverListAvailableDeliveries","summary":"Entregas disponíveis","description":"Lista ofertas PENDING cuja coleta está a até `radiusKm` (padrão 100) da localização atual do motorista (`PATCH /location`). Não exige Trip ACTIVE. Corredor WELOZ-25 permanece em GET /compatible. Respeita disponibilidade, pausa de notificações, tipo de veículo, capacidade do perfil e recusas do motorista.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"radiusKm","in":"query","required":false,"schema":{"type":"number","exclusiveMinimum":0,"maximum":200,"default":100},"description":"Raio máximo em km a partir da localização atual do motorista"}],"responses":{"200":{"description":"Lista de ofertas próximas (RouteOffer)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RouteOffer"}}}}},"400":{"description":"Query inválida ou localização do motorista ausente"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"}}}},"/api/driver/trips":{"post":{"summary":"Declarar trajeto","description":"Cria um Trip ACTIVE. Origem = localização atual. Capacidade vem do veículo (mock Card 32). Bloqueia se já houver trajeto ativo. Trajeto sem aceite e sem sair do lugar expira sozinho após 4h (WELOZ-33).","tags":["Trips"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["destinationLat","destinationLng"],"properties":{"destinationLat":{"type":"number","minimum":-90,"maximum":90},"destinationLng":{"type":"number","minimum":-180,"maximum":180}}}}}},"responses":{"201":{"description":"Trajeto criado"},"400":{"description":"Validação ou localização ausente"},"409":{"description":"Trajeto ativo já existe ou capacidade indisponível"}}}},"/api/driver/trips/active":{"get":{"summary":"Consultar trajeto ativo","description":"Retorna o Trip ACTIVE com entregas vinculadas, ordem das paradas, ETAs e capacidade restante (veículo + teto do tier).","tags":["Trips"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Trajeto ACTIVE com itinerário","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"itinerary":{"$ref":"#/components/schemas/TripItinerary"}}}}}},"404":{"description":"Nenhum trajeto ativo"}}}},"/api/driver/deliveries/compatible":{"get":{"summary":"Entregas compatíveis com o trajeto","description":"Matching por corredor de rota. Lista encomendas cuja origem e destino estão ao longo do trajeto. `routeId` é o id do Trip ACTIVE. Sem routeId, use GET /available.","operationId":"listCompatibleDeliveries","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"routeId","in":"query","required":true,"schema":{"type":"string"},"description":"Identificador do trajeto declarado (Card 12). Prefixo mock-route-* no mock atual."}],"responses":{"200":{"description":"Lista de ofertas compatíveis com o corredor","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RouteOffer"}},"examples":{"corridorOffers":{"summary":"Duas encomendas no corredor","value":[{"id":"11111111-1111-1111-1111-111111111111","pickup":{"address":"Rua Augusta, 500 — Consolação","latitude":-23.553,"longitude":-46.662},"dropoff":{"address":"Rua dos Pinheiros, 200","latitude":-23.565,"longitude":-46.681},"item":{"description":"Caixa média","weightKg":4,"lengthCm":40,"widthCm":30,"heightCm":20,"volumeLiters":24},"driverEarnings":{"amount":22.4,"currency":"BRL"},"packageDistanceKm":3.1,"detourKm":0.4,"vehicleTypeNeeded":"MOTORCYCLE"}]}}}}},"400":{"description":"routeId ausente ou inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"404":{"description":"Trajeto não encontrado"}}}},"/api/driver/deliveries":{"get":{"operationId":"driverListMyDeliveries","summary":"Minhas entregas","description":"Lista as entregas que você aceitou. Sem `page` retorna array legado; com `page` retorna envelope paginado. `scope=active` → ACCEPTED|WAITING_AT_PICKUP|IN_TRANSIT; `scope=history` → DELIVERED|CANCELLED.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Um status ou CSV (`DELIVERED,CANCELLED`). Tem prioridade sobre `scope`.","schema":{"type":"string","example":"IN_TRANSIT"}},{"name":"scope","in":"query","required":false,"description":"Atalho semântico. `active` / `history` / `all`. Motorista: active = ACCEPTED|WAITING_AT_PICKUP|IN_TRANSIT. Cliente: active inclui PENDING.","schema":{"type":"string","enum":["active","history","all"]}},{"name":"from","in":"query","required":false,"description":"Filtro inclusive por createdAt (ISO date-time).","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Filtro inclusive por createdAt (ISO date-time).","schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","required":false,"description":"Quando presente, a resposta usa envelope paginado. Sem `page`, retorna array legado (compat).","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Itens por página (só com `page`). Default 20, máx 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Array legado (sem page) ou DeliveryListResponse (com page)","content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},{"$ref":"#/components/schemas/DeliveryListResponse"}]}}}},"400":{"description":"Query inválida"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/accept":{"post":{"operationId":"driverAcceptDelivery","summary":"Aceitar entrega","description":"Aceita uma entrega no trajeto ACTIVE. Um Trip pode ter N entregas com status independente. Recusa com mensagem clara se peso/volume do veículo ou teto de itens do tier estourarem. Recalcula paradas e ETA de todos os destinatários vinculados.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Entrega aceita, com itinerário do trajeto quando houver Trip ACTIVE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Motorista indisponível ou entrega não disponível"},"401":{"description":"Não autenticado"},"403":{"description":"Motorista não aprovado"},"404":{"description":"Perfil de motorista ou entrega não encontrada"},"409":{"description":"Sem trajeto ativo, capacidade do veículo/tier esgotada, pagamento sem autorização/reserva vencida, ou entrega aceita por outro motorista","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","enum":["ACTIVE_TRIP_REQUIRED","CAPACITY_EXCEEDED","TIER_ITEM_LIMIT_EXCEEDED","DELIVERY_ALREADY_ACCEPTED","DELIVERY_PAYMENT_NOT_AUTHORIZED","DELIVERY_PAYMENT_AUTHORIZATION_EXPIRED"]},"message":{"type":"string"}}},"examples":{"capacityExceeded":{"summary":"Capacidade da trip excedida após revalidação transacional","value":{"error":"CAPACITY_EXCEEDED","message":"Esta entrega (10kg) ultrapassa a capacidade restante do veículo (5kg de 100kg)."}}}}}},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/collect":{"post":{"summary":"Confirmar coleta com código de retirada","description":"Valida o código informado pelo remetente, exige prova de coleta com foto e move a entrega para IN_TRANSIT.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["verificationCode"],"properties":{"verificationCode":{"type":"string","pattern":"^\\d{4,8}$","description":"Código de retirada gerado na criação da entrega"}}}}}},"responses":{"200":{"description":"Coleta confirmada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Transição inválida"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista da entrega"},"404":{"description":"Entrega não encontrada"},"409":{"description":"Código inválido/ausente ou foto de coleta pendente"}}}},"/api/driver/deliveries/{deliveryId}/proofs/pickup/photo":{"post":{"summary":"Upload da foto de coleta","description":"Envia a foto obrigatória da retirada. Retorna a URL pública para usar em `POST .../proofs/pickup`.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["photo"],"properties":{"photo":{"type":"string","format":"binary","description":"Foto JPEG/PNG/WebP (máx. 10MB)"}}}}}},"responses":{"201":{"description":"Foto enviada","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"storagePath":{"type":"string"},"filename":{"type":"string"},"size":{"type":"integer"}}}}}},"400":{"description":"Arquivo inválido ou status da entrega incompatível"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista da entrega"},"404":{"description":"Entrega não encontrada"}}}},"/api/driver/deliveries/{deliveryId}/proofs/pickup":{"post":{"operationId":"driverRegisterPickupProof","summary":"Registrar prova de coleta","description":"Registra a prova operacional de retirada. `photoUrl` é obrigatório (envie a foto em `.../proofs/pickup/photo` antes).","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["photoUrl"],"properties":{"photoUrl":{"type":"string","format":"uri"},"notes":{"type":"string"},"contactName":{"type":"string"},"contactDocument":{"type":"string"}}}}}},"responses":{"201":{"description":"Prova registrada"},"400":{"description":"Foto ausente ou dados inválidos"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista da entrega"},"404":{"description":"Entrega não encontrada"}}}},"/api/driver/deliveries/{deliveryId}/status":{"patch":{"operationId":"driverUpdateDeliveryStatus","summary":"Atualizar status","description":"\nAtualiza o status da entrega. Transições permitidas:\n- ACCEPTED → WAITING_AT_PICKUP (chegou no ponto de coleta)\n- WAITING_AT_PICKUP → IN_TRANSIT (iniciou o transporte; exige prova de coleta e coleta confirmada via `/collect`)\n- IN_TRANSIT → DELIVERED (entrega concluída; exige prova de entrega)\n        ","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["WAITING_AT_PICKUP","IN_TRANSIT","DELIVERED"],"description":"Próximo status permitido no fluxo do motorista"},"latitude":{"type":"number"},"longitude":{"type":"number"},"notes":{"type":"string"}}},"examples":{"waitingAtPickup":{"summary":"Chegou no ponto de coleta","value":{"status":"WAITING_AT_PICKUP"}},"inTransit":{"summary":"Iniciando transporte","value":{"status":"IN_TRANSIT","notes":"Coletei o pacote"}},"delivered":{"summary":"Finalizando entrega","value":{"status":"DELIVERED","notes":"Entregue ao porteiro"}}}}}},"responses":{"200":{"description":"Status atualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Transição inválida ou payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista desta entrega"},"404":{"description":"Entrega não encontrada"},"409":{"description":"Falta prova de coleta antes de IN_TRANSIT ou prova de entrega antes de DELIVERED"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/proofs/delivery":{"post":{"operationId":"driverRegisterDeliveryProof","summary":"Registrar prova de entrega","description":"Registra prova de entrega com OTP do destinatário (`verificationCode`) ou, quando o destinatário está ausente, com `photoUrl` (envie a foto em `.../proofs/delivery/photo` antes).","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"photoUrl":{"type":"string","format":"uri"},"notes":{"type":"string"},"contactName":{"type":"string"},"contactDocument":{"type":"string"},"verificationCode":{"type":"string","pattern":"^\\d{4,8}$","description":"OTP do destinatário, 4 a 8 dígitos; exigido pelo use case"}}}}}},"responses":{"201":{"description":"Prova de entrega registrada","content":{"application/json":{"schema":{"type":"object","required":["id","deliveryId","type","createdAt"],"properties":{"id":{"type":"string"},"deliveryId":{"type":"string"},"type":{"type":"string","enum":["DELIVERY"],"example":"DELIVERY"},"photoUrl":{"type":["string","null"]},"notes":{"type":["string","null"]},"contactName":{"type":["string","null"]},"contactDocument":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"uploadedBy":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":["string","null"]},"phone":{"type":["string","null"]}}}}}}}},"400":{"description":"Payload inválido ou prova não permitida no status atual"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista desta entrega"},"404":{"description":"Entrega não encontrada"},"409":{"description":"OTP ausente, expirado, já utilizado ou inválido"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/incidents":{"post":{"operationId":"driverCreateDeliveryIncident","summary":"Registrar ocorrência da entrega","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","title","description"],"properties":{"type":{"type":"string","enum":["PICKUP_ISSUE","DELIVERY_DELAY","ITEM_DAMAGED","RECIPIENT_UNAVAILABLE","DELIVERY_DISPUTE","RETURN_REQUEST","OTHER"]},"requestedAction":{"type":"string","enum":["NONE","REFUND","RETURN_TO_SENDER","REDISPATCH"]},"title":{"type":"string","minLength":3,"maxLength":191},"description":{"type":"string","minLength":5}}}}}},"responses":{"201":{"description":"Ocorrência registrada","content":{"application/json":{"schema":{"type":"object","required":["id","deliveryId","type","status","requestedAction","title","description","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"deliveryId":{"type":"string"},"type":{"type":"string","enum":["PICKUP_ISSUE","DELIVERY_DELAY","ITEM_DAMAGED","RECIPIENT_UNAVAILABLE","DELIVERY_DISPUTE","RETURN_REQUEST","OTHER"]},"status":{"type":"string","enum":["OPEN","IN_REVIEW","RESOLVED","CANCELLED"]},"requestedAction":{"type":"string","enum":["NONE","REFUND","RETURN_TO_SENDER","REDISPATCH"]},"title":{"type":"string"},"description":{"type":"string"},"resolutionNotes":{"type":["string","null"]},"resolvedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"reportedBy":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":["string","null"]},"phone":{"type":["string","null"]}}}}}}}},"400":{"description":"Payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista desta entrega"},"404":{"description":"Entrega não encontrada"},"500":{"description":"Erro interno do servidor"}}},"get":{"operationId":"driverListDeliveryIncidents","summary":"Listar ocorrências da entrega","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Lista de ocorrências","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","deliveryId","type","status","requestedAction","title","description","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"deliveryId":{"type":"string"},"type":{"type":"string","enum":["PICKUP_ISSUE","DELIVERY_DELAY","ITEM_DAMAGED","RECIPIENT_UNAVAILABLE","DELIVERY_DISPUTE","RETURN_REQUEST","OTHER"]},"status":{"type":"string","enum":["OPEN","IN_REVIEW","RESOLVED","CANCELLED"]},"requestedAction":{"type":"string","enum":["NONE","REFUND","RETURN_TO_SENDER","REDISPATCH"]},"title":{"type":"string"},"description":{"type":"string"},"resolutionNotes":{"type":["string","null"]},"resolvedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"reportedBy":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":["string","null"]},"phone":{"type":["string","null"]}}}}}}}}},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista desta entrega"},"404":{"description":"Entrega não encontrada"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/cancel":{"post":{"operationId":"driverCancelDelivery","summary":"Liberar entrega aceita","description":"O motorista só pode cancelar entrega atribuída a ele nos status ACCEPTED ou WAITING_AT_PICKUP. A entrega volta para PENDING e o motorista fica disponível novamente.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":5,"maxLength":500}}}}}},"responses":{"200":{"description":"Entrega liberada e devolvida para PENDING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Payload inválido ou status que não permite cancelamento"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista desta entrega"},"404":{"description":"Entrega não encontrada"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/transfer":{"post":{"operationId":"transferDeliveryByDriver","summary":"Solicitar repasse da entrega","description":"O motorista atual informa que não consegue concluir a entrega e registra o motivo do repasse. `deliveryId` vai no path; o motorista autenticado é o solicitante.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferDeliveryRequest"},"examples":{"unableToContinue":{"summary":"Motorista não consegue concluir","value":{"reason":"Imprevisto no trajeto. Não consigo concluir a entrega."}}}}}},"responses":{"200":{"description":"Solicitação de repasse aceita","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Payload inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Não autenticado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Não é o motorista desta entrega","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Entrega não encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/driver/deliveries/{deliveryId}/handoff":{"post":{"operationId":"assumeTransferredDelivery","summary":"Assumir entrega após repasse","description":"O novo motorista assume uma entrega liberada para repasse. O pacote já foi coletado, então o status volta para IN_TRANSIT e a cadeia de custódia registra o sucessor. Sem body: o motorista autenticado é o sucessor.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Entrega assumida em trânsito","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}}},"400":{"description":"Payload inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Não autenticado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Motorista não habilitado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Entrega ou perfil de motorista não encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Handoff inválido (mesmo motorista, já assumida ou pacote não coletado)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/driver/deliveries/{deliveryId}/custody":{"get":{"operationId":"getDeliveryCustodyHistory","summary":"Consultar cadeia de custódia","description":"Lista os períodos de custódia da entrega em ordem cronológica. Só o motorista atual ou quem já teve custódia desta entrega pode consultar por esta rota.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cadeia de custódia","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryCustodyRecord"}}}}},"401":{"description":"Não autenticado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Sem permissão para consultar a cadeia","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Entrega não encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/driver/location":{"patch":{"operationId":"driverUpdateLocation","summary":"Atualizar localização","description":"Atualiza a localização atual do motorista. Envie periodicamente durante entregas.","tags":["Location"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["latitude","longitude"],"properties":{"latitude":{"type":"number","example":-23.561684},"longitude":{"type":"number","example":-46.655981},"isAvailable":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Localização atualizada","content":{"application/json":{"schema":{"type":"object","required":["id","vehicleType","isAvailable"],"properties":{"id":{"type":"string"},"vehicleType":{"type":"string","enum":["MOTORCYCLE","CAR","VAN","TRUCK"]},"vehiclePlate":{"type":["string","null"]},"vehicleModel":{"type":["string","null"]},"vehicleYear":{"type":["integer","null"]},"vehicleColor":{"type":["string","null"]},"currentLatitude":{"type":["string","null"]},"currentLongitude":{"type":["string","null"]},"isAvailable":{"type":"boolean"},"totalDeliveries":{"type":"integer"},"averageRating":{"type":["number","null"]},"approvalStatus":{"type":"string"},"approvalNotes":{"type":["string","null"]}}}}}},"400":{"description":"Payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/payouts":{"get":{"operationId":"driverListPayouts","summary":"Listar meus repasses","tags":["Payouts"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lista de repasses do motorista autenticado","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","amount","status","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"amount":{"type":"string"},"status":{"type":"string","enum":["PENDING","SCHEDULED","PAID","FAILED","CANCELLED"]},"reference":{"type":["string","null"]},"scheduledAt":{"type":["string","null"],"format":"date-time"},"paidAt":{"type":["string","null"],"format":"date-time"},"failedAt":{"type":["string","null"],"format":"date-time"},"cancelledAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"payee":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":["string","null"]},"email":{"type":["string","null"]}}},"payment":{"type":"object","properties":{"id":{"type":"string"},"deliveryId":{"type":"string"},"status":{"type":"string","enum":["PENDING","RESERVED","AUTHORIZED","CAPTURED","FAILED","REFUNDED","CANCELLED"]},"amount":{"type":"string"},"currency":{"type":"string"}}}}}}}}},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/availability":{"patch":{"operationId":"driverUpdateAvailability","summary":"Atualizar disponibilidade","tags":["Profile"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["isAvailable"],"properties":{"isAvailable":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Disponibilidade atualizada","content":{"application/json":{"schema":{"type":"object","required":["id","vehicleType","isAvailable"],"properties":{"id":{"type":"string"},"vehicleType":{"type":"string","enum":["MOTORCYCLE","CAR","VAN","TRUCK"]},"vehiclePlate":{"type":["string","null"]},"vehicleModel":{"type":["string","null"]},"vehicleYear":{"type":["integer","null"]},"vehicleColor":{"type":["string","null"]},"currentLatitude":{"type":["string","null"]},"currentLongitude":{"type":["string","null"]},"isAvailable":{"type":"boolean"},"totalDeliveries":{"type":"integer"},"averageRating":{"type":["number","null"]},"approvalStatus":{"type":"string"},"approvalNotes":{"type":["string","null"]}}}}}},"400":{"description":"Payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/preferences":{"get":{"operationId":"driverGetPreferences","summary":"Obter preferencias do motorista","description":"Retorna configuracao de raio de notificacao e estado de pausa para novas ofertas.","tags":["Profile"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Preferencias atuais do motorista","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverNotificationPreferences"}}}},"401":{"description":"Nao autenticado"},"403":{"description":"Nao e motorista"},"404":{"description":"Perfil de motorista nao encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Erro interno do servidor"}}},"patch":{"operationId":"driverUpdatePreferences","summary":"Atualizar preferencias do motorista","description":"Atualiza raio de notificacao e/ou pausa de notificacoes para novas ofertas.","tags":["Profile"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverNotificationPreferencesUpdateRequest"}}}},"responses":{"200":{"description":"Preferencias atualizadas","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriverNotificationPreferences"}}}},"400":{"description":"Payload invalido"},"401":{"description":"Nao autenticado"},"403":{"description":"Nao e motorista"},"404":{"description":"Perfil de motorista nao encontrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/deliveries/{deliveryId}/reject":{"post":{"operationId":"driverRejectAvailableDelivery","summary":"Recusar oferta de entrega","description":"Registra a recusa da oferta pelo motorista autenticado para que a entrega não reapareça no pool dele enquanto permanecer pendente.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":500}}}}}},"responses":{"200":{"description":"Oferta recusada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryDriverRejection"}}}},"400":{"description":"Payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"404":{"description":"Entrega não encontrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Entrega não está mais disponível","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/driver/documents":{"get":{"operationId":"driverListDocuments","summary":"Listar documentos do motorista","description":"Endpoint transversal do app: requer autenticação, mas não exige activeRole DRIVER.","tags":["Documents"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Documentos e status de aprovação","content":{"application/json":{"schema":{"type":"object","required":["approvalStatus","approvalNotes","documents"],"properties":{"approvalStatus":{"type":"string"},"approvalNotes":{"type":["string","null"]},"documents":{"type":"array","items":{"type":"object","required":["id","type","fileUrl","uploadedAt"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"fileUrl":{"type":"string"},"uploadedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"clientPreflight":{"type":["object","null"],"description":"Triagem declarada pelo dispositivo; deve ser confirmada na revisão administrativa."}}}}}}}}},"401":{"description":"Não autenticado"},"404":{"description":"Perfil de motorista não encontrado"},"500":{"description":"Erro interno do servidor"}}},"post":{"operationId":"driverUploadDocument","summary":"Enviar documento do motorista","description":"Endpoint transversal do app (não exige activeRole DRIVER). Upload multipart. MIME permitidos: image/jpeg, image/png, image/webp, application/pdf. Máximo 20 MB. Para o fluxo atual, envie DRIVER_LICENSE_FRONT, DRIVER_LICENSE_BACK e SELFIE_WITH_DOCUMENT. Tipos legados continuam aceitos por compatibilidade.","tags":["Documents"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","type"],"properties":{"file":{"type":"string","format":"binary","description":"Arquivo do documento (máx. 20 MB)"},"type":{"type":"string","enum":["DRIVER_LICENSE_FRONT","DRIVER_LICENSE_BACK","SELFIE_WITH_DOCUMENT","DRIVER_LICENSE","VEHICLE_REGISTRATION","DRIVER_PHOTO","INSURANCE","PROOF_OF_ADDRESS","PROFILE_PHOTO"]},"expiresAt":{"type":"string","format":"date-time"},"localPreflight":{"type":"string","description":"JSON da triagem on-device. É evidência auxiliar não confiável e nunca aprova identidade isoladamente."}}}}}},"responses":{"201":{"description":"Documento enviado","content":{"application/json":{"schema":{"type":"object","required":["id","type","fileUrl","uploadedAt","approvalStatus"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"fileUrl":{"type":"string"},"uploadedAt":{"type":"string","format":"date-time"},"clientPreflight":{"type":["object","null"],"description":"Triagem declarada pelo dispositivo; deve ser confirmada na revisão administrativa."},"approvalStatus":{"type":"string"}}}}}},"400":{"description":"Arquivo ausente ou payload inválido"},"401":{"description":"Não autenticado"},"404":{"description":"Perfil de motorista não encontrado"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/documents/{documentId}":{"delete":{"operationId":"driverDeleteDocument","summary":"Remover documento do motorista","description":"Endpoint transversal do app: requer autenticação, mas não exige activeRole DRIVER.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"documentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Documento removido","content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","example":"Documento removido com sucesso"}}}}}},"401":{"description":"Não autenticado"},"404":{"description":"Perfil de motorista ou documento não encontrado"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/earnings/summary":{"get":{"operationId":"driverGetEarningsSummary","summary":"Obter resumo de ganhos","description":"period inválido cai no default 30d (não retorna 400). totalGross usa payouts PAID; totalPending usa PENDING ou SCHEDULED. warning fica true com pelo menos 5 entregas e taxa de cancelamento pelo motorista acima de 15%.","tags":["Earnings"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","enum":["7d","30d","90d","all"],"default":"30d"}}],"responses":{"200":{"description":"Resumo de ganhos do período","content":{"application/json":{"schema":{"type":"object","required":["period","deliveries","earnings","ratings","cancellations"],"properties":{"period":{"type":"object","required":["from","to"],"properties":{"from":{"type":["string","null"],"format":"date-time"},"to":{"type":"string","format":"date-time"}}},"deliveries":{"type":"object","required":["total","completed","cancelled","completionRate"],"properties":{"total":{"type":"integer"},"completed":{"type":"integer"},"cancelled":{"type":"integer"},"completionRate":{"type":"number","description":"Percentual de entregas concluídas"}}},"earnings":{"type":"object","required":["totalGross","totalPending","currency"],"properties":{"totalGross":{"type":"number"},"totalPending":{"type":"number"},"currency":{"type":"string","example":"BRL"}}},"ratings":{"type":"object","required":["average","count"],"properties":{"average":{"type":["number","null"]},"count":{"type":"integer"}}},"cancellations":{"type":"object","required":["byDriver","warning"],"properties":{"byDriver":{"type":"integer"},"warning":{"type":"boolean"}}}}}}}},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"},"404":{"description":"Perfil de motorista não encontrado"},"500":{"description":"Erro interno do servidor"}}}},"/api/driver/incidents/{incidentId}/not-received-response":{"post":{"operationId":"respondDriverItemNotReceived","summary":"Responder reporte de item não recebido","description":"Motorista explica o ocorrido antes do prazo. Após a resposta, a ocorrência segue em análise.","tags":["Deliveries"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"incidentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["notes"],"properties":{"notes":{"type":"string","minLength":5,"maxLength":2000}}}}}},"responses":{"200":{"description":"Resposta registrada"},"400":{"description":"Ocorrência inválida ou já respondida/escalada"},"401":{"description":"Não autenticado"},"403":{"description":"Não é o motorista da entrega"},"404":{"description":"Ocorrência não encontrada"}}}},"/api/driver/vehicles/catalog":{"get":{"operationId":"getDriverVehicleCatalog","summary":"Consultar catálogo encadeado de veículos","description":"Retorna marcas para o tipo informado, modelos após a marca, anos após o modelo e as cores veiculares aceitas.","tags":["Vehicles"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"vehicleType","in":"query","required":true,"schema":{"$ref":"#/components/schemas/VehicleType"}},{"name":"brand","in":"query","schema":{"type":"string"}},{"name":"model","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Opções disponíveis para a seleção atual","content":{"application/json":{"schema":{"type":"object","required":["brands","models","years","colors"],"properties":{"brands":{"type":"array","items":{"type":"string"}},"models":{"type":"array","items":{"type":"string"}},"years":{"type":"array","items":{"type":"integer"}},"colors":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Consulta inválida"},"401":{"description":"Não autenticado"}}}},"/api/driver/vehicles/capacity-suggestion":{"post":{"operationId":"suggestVehicleCapacity","summary":"Sugerir capacidade do veículo","description":"Consulta tabela de modelos (e opcionalmente placa) para sugerir litros/kg do porta-malas. Não converte litros em kg.","tags":["Vehicles"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestVehicleCapacityRequest"}}}},"responses":{"200":{"description":"Sugestão de capacidade","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestVehicleCapacityResponse"}}}},"400":{"description":"Payload inválido"},"401":{"description":"Não autenticado"},"403":{"description":"Não é motorista"}}}}}}