{"openapi":"3.0.0","paths":{"/api/v1/statistics":{"get":{"operationId":"StatisticsController_getOverview","summary":"Platform overview statistics built from outbox-synchronized projections","parameters":[],"responses":{"200":{"description":""}},"tags":["Statistics"]}},"/api/v1/users/me":{"get":{"operationId":"UsersController_getMe","summary":"Get current user profile","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"patch":{"operationId":"UsersController_updateMe","summary":"Update current user profile preferences","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMeUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"delete":{"operationId":"UsersController_deleteMe","summary":"Delete current user account (GDPR self-delete)","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/me/vehicles":{"get":{"operationId":"UsersController_getMyVehicles","summary":"List current user vehicles","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"post":{"operationId":"UsersController_createMyVehicle","summary":"Create current user vehicle","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVehicleDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/me/vehicles/{id}":{"patch":{"operationId":"UsersController_updateMyVehicle","summary":"Update current user vehicle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVehicleDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"delete":{"operationId":"UsersController_deleteMyVehicle","summary":"Delete current user vehicle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/confirm-email":{"get":{"operationId":"UsersController_confirmEmailByQuery","summary":"Confirm email address using token from email link","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmEmailResponseDto"}}}}},"tags":["Users"]}},"/api/v1/users":{"get":{"operationId":"UsersController_listUsers","summary":"List users (filter by query userType)","parameters":[{"name":"userType","required":false,"in":"query","description":"Filter by user category: client/partner/internal.","schema":{"enum":["client","partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/{id}":{"get":{"operationId":"UsersController_getUser","summary":"Get user by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"userType","required":false,"in":"query","description":"Filter by user category: client/partner/internal.","schema":{"enum":["client","partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/{id}/vehicles":{"get":{"operationId":"UsersController_getUserVehicles","summary":"Get vehicles for user by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"userType","required":false,"in":"query","description":"Filter by user category: client/partner/internal.","schema":{"enum":["client","partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/{userType}":{"post":{"operationId":"UsersController_createUser","summary":"Create user by path userType","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["client","partner"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProvisioningResponseDto"}}}}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/{userType}/invite":{"post":{"operationId":"UsersController_inviteUser","summary":"Invite user by path userType","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["client","partner"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProvisioningResponseDto"}}}}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/{userType}/{id}":{"patch":{"operationId":"UsersController_updateUser","summary":"Update user by id and path userType","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["client","partner"],"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"delete":{"operationId":"UsersController_deleteUser","summary":"Delete user by id and path userType","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["client","partner"],"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/client/me":{"get":{"operationId":"ClientUsersController_getMe","summary":"Get current client profile","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"patch":{"operationId":"ClientUsersController_updateMe","summary":"Update current client profile preferences","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMeUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/client/me/export":{"get":{"operationId":"ClientUsersController_exportMyData","summary":"NF-04: export full personal data package (JSON)","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/client/me/consents":{"get":{"operationId":"ClientUsersController_getMyConsents","summary":"NF-04: list my consent history + current status","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/client/me/consents/{consentType}":{"post":{"operationId":"ClientUsersController_updateMyConsent","summary":"NF-04: grant/revoke consent for current user","parameters":[{"name":"consentType","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertUserConsentDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/client/me/dsar/requests":{"post":{"operationId":"ClientUsersController_createMyDsarRequest","summary":"GDPR/MD: submit data-subject request (DSAR)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDsarRequestDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"get":{"operationId":"ClientUsersController_listMyDsarRequests","summary":"GDPR/MD: list my DSAR requests","parameters":[{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal":{"get":{"operationId":"InternalUsersController_listUsers","summary":"List users (internal admin)","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"post":{"operationId":"InternalUsersController_createUser","summary":"Create user (internal admin)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/{id}":{"get":{"operationId":"InternalUsersController_getUser","summary":"Get user by id (internal admin)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"patch":{"operationId":"InternalUsersController_updateUser","summary":"Update user by id (internal admin)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"delete":{"operationId":"InternalUsersController_deleteUser","summary":"Delete user by id (internal admin)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/{id}/export":{"get":{"operationId":"InternalUsersController_exportUserData","summary":"NF-04: internal full user data export (audit/compliance)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/{id}/sensitive-access-logs":{"get":{"operationId":"InternalUsersController_listSensitiveAccessLogs","summary":"NF-04: list sensitive data access logs for user","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/{id}/dsar-requests":{"get":{"operationId":"InternalUsersController_listDsarRequestsForUser","summary":"GDPR/MD: list DSAR requests for target user","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/dsar-requests/{id}":{"patch":{"operationId":"InternalUsersController_updateDsarRequest","summary":"GDPR/MD: update/execute DSAR request","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDsarRequestDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/retention/run":{"post":{"operationId":"InternalUsersController_runRetentionPolicy","summary":"GDPR/MD: run retention policy enforcement (dry-run/default)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRetentionPolicyDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/retention/runs":{"get":{"operationId":"InternalUsersController_listRetentionRuns","summary":"GDPR/MD: list retention policy execution history","parameters":[{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/privacy/breaches":{"post":{"operationId":"InternalUsersController_createPrivacyBreach","summary":"GDPR/MD: create privacy/data-breach incident","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePrivacyBreachDto"}}}},"responses":{"201":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"get":{"operationId":"InternalUsersController_listPrivacyBreaches","summary":"GDPR/MD: list privacy/data-breach incidents","parameters":[{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/internal/privacy/breaches/{id}":{"get":{"operationId":"InternalUsersController_getPrivacyBreach","summary":"GDPR/MD: get privacy/data-breach incident details","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"patch":{"operationId":"InternalUsersController_updatePrivacyBreach","summary":"GDPR/MD: update privacy/data-breach incident + notifications","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrivacyBreachDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/users/partner/me":{"get":{"operationId":"PartnerUsersController_getMe","summary":"Get current partner profile","parameters":[],"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]},"patch":{"operationId":"PartnerUsersController_updateMe","summary":"Update current partner profile preferences","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMeUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["Users"],"security":[{"bearer":[]}]}},"/api/v1/auth/register":{"post":{"operationId":"AuthController_register","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"},"examples":{"client":{"summary":"Client register","value":{"name":"Ion Popescu","email":"ion@example.com","password":"Secret123!","phone":"+37360123456","country":"moldova","city":"chisinau","language":"ro","currency":"MDL"}}}}}},"responses":{"201":{"description":"Client user registration result (email confirmation required by policy)","content":{"application/json":{"schema":{"example":{"user":{"id":"11111111-1111-1111-1111-111111111111","name":"Ion Popescu","email":"ion@example.com","phone":"+37360123456","country":"moldova","city":"chisinau","language":"ro","currency":"MDL","role":"client"},"confirmation":{"required":true,"emailSent":true,"status":"pending","expiresAt":"2026-03-10T10:00:00.000Z"}}}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/login":{"post":{"operationId":"AuthController_login","summary":"Credentials login (PRD alias)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"},"examples":{"email":{"summary":"Email login","value":{"email":"ion@example.com","password":"Secret123!"}},"phone":{"summary":"Phone login","value":{"phoneNumber":"+37360123456","password":"Secret123!"}}}}}},"responses":{"200":{"schema":{"example":{"accessToken":"<jwt-access-token>","refreshToken":"<jwt-refresh-token>"}},"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/refresh":{"post":{"operationId":"AuthController_refreshByToken","summary":"Refresh token pair by refresh token (PRD alias)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshAccessTokenDto"},"examples":{"refresh":{"summary":"Refresh token payload","value":{"refreshToken":"<jwt-refresh-token>"}}}}}},"responses":{"200":{"schema":{"example":{"accessToken":"<jwt-access-token>","refreshToken":"<jwt-refresh-token-rotated>"}},"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/forgot-password":{"post":{"operationId":"AuthController_forgotPassword","summary":"Issue password reset token and send reset email","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"},"examples":{"email":{"summary":"Forgot password","value":{"email":"ion@example.com"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"example":{"received":true,"emailSent":true,"expiresInMinutes":15}}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","summary":"Reset password with reset token","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"},"examples":{"reset":{"summary":"Reset password payload","value":{"token":"<password-reset-token>","password":"NewSecret123!"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"example":{"updated":true,"message":"Password reset successful"}}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/oauth/google":{"post":{"operationId":"AuthController_oauthGoogle","summary":"Google OAuth login (PRD alias)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OauthProviderLoginDto"},"examples":{"oauth":{"summary":"Google OAuth payload","value":{"idToken":"<google-id-token>","oauthEmail":"ion@example.com","name":"Ion Popescu"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/oauth/apple":{"post":{"operationId":"AuthController_oauthApple","summary":"Apple OAuth login (PRD alias)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OauthProviderLoginDto"},"examples":{"oauth":{"summary":"Apple OAuth payload","value":{"idToken":"<apple-id-token>","oauthEmail":"ion@example.com","name":"Ion Popescu"}}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/{userType}/login":{"post":{"operationId":"AuthController_loginByUserType","summary":"Credentials login by userType","parameters":[{"name":"userType","required":true,"in":"path","description":"Select login target type.","schema":{"enum":["client","partner","internal"],"type":"string"}}],"requestBody":{"required":true,"description":"Credentials payload for auth/{userType}/login. All user types use email + password.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthLoginCredentialsDto"}}}},"responses":{"200":{"description":"JWT token pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/refreshToken":{"post":{"operationId":"AuthController_refreshLegacy","summary":"Refresh token pair by refreshToken","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenDto"}}}},"responses":{"200":{"description":""},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/auth/logout":{"post":{"operationId":"AuthController_logout","summary":"Logout (invalidate refresh token)","parameters":[],"responses":{"200":{"description":""},"400":{"description":"Bad Request (validation or domain rule error)","schema":{"example":{"statusCode":400,"error":"Bad Request","message":["email must be an email"],"timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"401":{"description":"Unauthorized","schema":{"example":{"statusCode":401,"error":"Unauthorized","message":"Invalid credentials","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"403":{"description":"Forbidden","schema":{"example":{"statusCode":403,"error":"Forbidden","message":"Forbidden resource","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"404":{"description":"Not Found","schema":{"example":{"statusCode":404,"error":"Not Found","message":"Resource not found","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}},"500":{"description":"Internal Server Error","schema":{"example":{"statusCode":500,"error":"Internal Server Error","message":"Internal server error","timestamp":"2026-03-09T10:30:00.000Z","path":"/api/v1/resource"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponseDto"}}}}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/api/v1/oauth/client/login":{"post":{"operationId":"OauthController_clientOauthLogin","summary":"Client OAuth login","parameters":[],"requestBody":{"required":true,"description":"OAuth payload for client login. Provide provider and either idToken or explicit provider account fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthLoginOauthDto"}}}},"responses":{"200":{"description":"JWT token pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokenPairResponseDto"}}}}},"tags":["Auth"]}},"/api/v1/sso/{userType}/authorize":{"get":{"operationId":"SsoController_authorize","summary":"Build SSO authorize URL for partner/internal","parameters":[{"name":"redirectUri","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}},{"name":"codeChallenge","required":true,"in":"query","schema":{"type":"string"}},{"name":"codeChallengeMethod","required":true,"in":"query","schema":{"type":"string"}},{"name":"userType","required":true,"in":"path","schema":{"enum":["partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SSO"]}},"/api/v1/sso/{userType}/callback":{"get":{"operationId":"SsoController_callback","summary":"Handle SSO callback (code exchange handled by edge/IdP integration layer)","parameters":[{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}},{"name":"userType","required":true,"in":"path","schema":{"enum":["partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SSO"]}},"/api/v1/sso/{userType}/metadata":{"get":{"operationId":"SsoController_metadata","summary":"Read public SSO metadata for partner/internal","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["partner","internal"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SSO"]}},"/api/v1/sso/{userType}/logout":{"post":{"operationId":"SsoController_logout","summary":"Local SSO logout for partner/internal user","parameters":[{"name":"userType","required":true,"in":"path","schema":{"enum":["partner","internal"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SsoLogoutDto"}}}},"responses":{"201":{"description":""}},"tags":["SSO"],"security":[{"bearer":[]}]}},"/api/v1/partners":{"post":{"operationId":"PartnersRegistrationController_createPartnerOrganization","summary":"Register partner organization and owner user","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePartnerOrganizationDto"}}}},"responses":{"201":{"description":"Partner organization registered with owner user provisioning payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrganizationDto"}}}}},"tags":["Partners"],"security":[{"bearer":[]}]}},"/api/v1/vehicles":{"get":{"operationId":"VehiclesController_listVehicles","summary":"List vehicles (client/partner: mine, internal: requires userId query)","parameters":[{"name":"userId","required":false,"in":"query","description":"Internal only: list vehicles for this userId.","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]},"post":{"operationId":"VehiclesController_createVehicle","summary":"Create vehicle (client/partner: mine, internal: provide userId in request body)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVehicleDto"}}}},"responses":{"201":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]}},"/api/v1/vehicles/{id}":{"get":{"operationId":"VehiclesController_getVehicle","summary":"Get vehicle by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]},"patch":{"operationId":"VehiclesController_updateVehicle","summary":"Update vehicle by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVehicleDto"}}}},"responses":{"200":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]},"delete":{"operationId":"VehiclesController_deleteVehicle","summary":"Delete vehicle by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]}},"/api/v1/vehicles/{id}/primary":{"patch":{"operationId":"VehiclesController_setPrimaryVehicle","summary":"Set vehicle as primary","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Vehicles"],"security":[{"bearer":[]}]}},"/health":{"get":{"operationId":"HealthController_getHealth","summary":"Service health checks (API/DB/Redis)","parameters":[],"responses":{"200":{"description":""}},"tags":["Health"]}}},"info":{"title":"WashPass Statistics","description":"Statistics service API","version":"0.1.0+038d699","contact":{}},"tags":[{"name":"Statistics","description":"api/v1/statistics"}],"servers":[{"url":"http://localhost:3000","description":"Gateway (localhost)"},{"url":"http://127.0.0.1:3000","description":"Gateway (127.0.0.1)"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"UserMeUpdateDto":{"type":"object","properties":{"name":{"type":"string","example":"Ion Popescu"},"email":{"type":"string","example":"ion@example.com"},"phone":{"type":"object","example":"+37360123456"},"city":{"type":"string","enum":["chisinau","balti","bucuresti","cluj","kiev","odesa"]},"country":{"type":"string","example":"moldova"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL"},"firebaseToken":{"type":"object"}}},"CreateVehicleDto":{"type":"object","properties":{"userId":{"type":"string","description":"Internal only: target user id for vehicle creation. Ignored for client/partner.","format":"uuid"},"plateNumber":{"type":"string","example":"ABC 123","maxLength":20},"make":{"type":"string","maxLength":50},"model":{"type":"string","maxLength":50},"type":{"type":"string","enum":["motorcycle","sedan","hatchback","suv","bus","van","truck"]},"color":{"type":"string"},"isPrimary":{"type":"boolean","default":false}},"required":["plateNumber"]},"UpdateVehicleDto":{"type":"object","properties":{"plateNumber":{"type":"string","example":"ABC 123","maxLength":20},"make":{"type":"string","maxLength":50},"model":{"type":"string","maxLength":50},"type":{"type":"string","enum":["motorcycle","sedan","hatchback","suv","bus","van","truck"]},"color":{"type":"string"},"isPrimary":{"type":"boolean"}}},"SharedSubscriptionUserRefDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}},"required":["userId"]},"UserEmailConfirmationDto":{"type":"object","properties":{"required":{"type":"boolean","example":true},"emailSent":{"type":"boolean","example":false},"status":{"type":"string","example":"pending","enum":["pending","confirmed","not_required"]},"expiresAt":{"type":"string","example":"2026-02-22T12:00:00.000Z"},"confirmedAt":{"type":"string","example":"2026-02-22T12:05:10.000Z"}},"required":["required","emailSent","status"]},"ConfirmEmailResponseDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Ion Popescu"},"email":{"type":"string","example":"ion@example.com"},"phone":{"type":"object","example":"+37360123456"},"country":{"type":"string","example":"moldova"},"city":{"type":"string","example":"chisinau"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL"},"partnerId":{"type":"string","format":"uuid","nullable":true,"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"active":{"type":"boolean","example":false},"vehicles":{"example":[],"type":"array","items":{"type":"object"}},"subscription":{"type":"object","nullable":true,"example":null},"sharedSubscriptionWith":{"example":[{"userId":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"type":"array","items":{"$ref":"#/components/schemas/SharedSubscriptionUserRefDto"}},"confirmation":{"$ref":"#/components/schemas/UserEmailConfirmationDto"},"message":{"type":"string","example":"Email confirmed successfully"}},"required":["userId","name","email","country","city","language","active","confirmation","message"]},"UserCreateDto":{"type":"object","properties":{"name":{"type":"string","example":"Ion Popescu"},"email":{"type":"string","example":"ion@example.com"},"password":{"type":"string","example":"Secret123!"},"phone":{"type":"string","example":"+37360123456"},"city":{"type":"string","enum":["chisinau","balti","bucuresti","cluj","kiev","odesa"],"example":"chisinau"},"country":{"type":"string","example":"moldova"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL","description":"Optional. Used for client users; partner/internal use country default."},"partnerId":{"type":"string","format":"uuid"}},"required":["name","email","password"]},"UserProvisioningResponseDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Ion Popescu"},"email":{"type":"string","example":"ion@example.com"},"phone":{"type":"object","example":"+37360123456"},"country":{"type":"string","example":"moldova"},"city":{"type":"string","example":"chisinau"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL"},"partnerId":{"type":"string","format":"uuid","nullable":true,"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"active":{"type":"boolean","example":false},"vehicles":{"example":[],"type":"array","items":{"type":"object"}},"subscription":{"type":"object","nullable":true,"example":null},"sharedSubscriptionWith":{"example":[{"userId":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"type":"array","items":{"$ref":"#/components/schemas/SharedSubscriptionUserRefDto"}},"confirmation":{"$ref":"#/components/schemas/UserEmailConfirmationDto"}},"required":["userId","name","email","country","city","language","active","confirmation"]},"UserUpdateDto":{"type":"object","properties":{"name":{"type":"string","example":"Ion Popescu"},"email":{"type":"string","example":"ion@example.com"},"password":{"type":"string","example":"Secret123!"},"phone":{"type":"object","example":"+37360123456"},"city":{"type":"string","enum":["chisinau","balti","bucuresti","cluj","kiev","odesa"]},"country":{"type":"string","example":"moldova"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL","description":"Optional. For partner/internal userType routes, currency updates are ignored."},"partnerId":{"type":"string","format":"uuid"},"isActive":{"type":"boolean"},"firebaseToken":{"type":"object"}}},"UpsertUserConsentDto":{"type":"object","properties":{"granted":{"type":"boolean","example":true,"description":"Set consent status to granted/revoked (true = granted, false = revoked)."},"source":{"type":"string","example":"client_app","description":"Origin of consent update (client_app/internal_console/support)."},"policyVersion":{"type":"string","example":"privacy-policy-2026-03-01","description":"Policy document version accepted/revoked by the user."},"metadata":{"type":"object","example":{"locale":"ro","device":"ios"},"description":"Optional metadata for compliance/audit context."}},"required":["granted"]},"CreateDsarRequestDto":{"type":"object","properties":{"requestType":{"type":"string","enum":["access_export","portability_export","erasure","rectification","restriction","objection"]},"reason":{"type":"string","maxLength":2000},"metadata":{"type":"object","description":"Optional context for compliance workflow."}},"required":["requestType"]},"UpdateDsarRequestDto":{"type":"object","properties":{"status":{"type":"string","enum":["submitted","in_review","approved","rejected","processing","fulfilled","cancelled"]},"assignedToUserId":{"type":"string"},"resolutionSummary":{"type":"string","maxLength":4000},"executeNow":{"type":"boolean","description":"Execute requested action now (export/anonymize/delete)."},"metadata":{"type":"object"}}},"RunRetentionPolicyDto":{"type":"object","properties":{"policyCode":{"type":"string","enum":["inactive_client_anonymization","unconfirmed_client_delete"],"default":"inactive_client_anonymization"},"dryRun":{"type":"boolean","default":true},"olderThanDays":{"type":"number","default":365},"limit":{"type":"number","default":200}}},"CreatePrivacyBreachDto":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["low","medium","high","critical"]},"detectedAt":{"type":"string"},"occurredAt":{"type":"string"},"ownerUserId":{"type":"string"},"affectedSubjectsCount":{"type":"number"},"affectedRecordsCount":{"type":"number"},"likelyHighRisk":{"type":"boolean"},"metadata":{"type":"object"}},"required":["title","description"]},"UpdatePrivacyBreachDto":{"type":"object","properties":{"severity":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","triage","contained","notified_authority","notified_subjects","resolved","closed"]},"ownerUserId":{"type":"string"},"affectedSubjectsCount":{"type":"number"},"affectedRecordsCount":{"type":"number"},"likelyHighRisk":{"type":"boolean"},"authorityNotifiedAt":{"type":"string"},"subjectsNotifiedAt":{"type":"string"},"resolutionSummary":{"type":"string","maxLength":6000},"metadata":{"type":"object"}}},"ApiErrorResponseDto":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"error":{"type":"string","example":"Bad Request"},"message":{"oneOf":[{"type":"string","example":"Validation failed"},{"type":"array","items":{"type":"string"}}],"example":["email must be an email"]},"timestamp":{"type":"string","example":"2026-03-09T10:30:00.000Z"},"path":{"type":"string","example":"/api/v1/auth/login"}},"required":["statusCode","error","message","timestamp","path"]},"RegisterDto":{"type":"object","properties":{}},"LoginDto":{"type":"object","properties":{"email":{"type":"string","example":"ion@example.com","description":"Account email. Provide this or phoneNumber."},"phoneNumber":{"type":"string","example":"+37360123456","description":"Account phone number. Provide this or email."}}},"AuthTokenPairResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","example":"yourAccessTokenHere"},"refreshToken":{"type":"string","example":"yourRefreshTokenHere"}},"required":["accessToken","refreshToken"]},"RefreshAccessTokenDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Refresh token JWT used to rotate access/refresh token pair."}},"required":["refreshToken"]},"ForgotPasswordDto":{"type":"object","properties":{"email":{"type":"string","example":"ion@example.com"}},"required":["email"]},"ResetPasswordDto":{"type":"object","properties":{"token":{"type":"string","description":"Password reset token received by email."},"password":{"type":"string","description":"New account password. Must contain at least one uppercase letter, one lowercase letter, and one digit.","minLength":8}},"required":["token","password"]},"OauthProviderLoginDto":{"type":"object","properties":{"method":{"type":"string","enum":["oauth"],"description":"Optional marker for oauth flow.","default":"oauth"},"providerUserId":{"type":"string","example":"provider-user-subject","description":"Optional when idToken contains subject (sub) claim."},"oauthEmail":{"type":"string","example":"ion@example.com","description":"Optional when idToken contains email claim."},"name":{"type":"string","example":"Ion Popescu","description":"Optional when idToken contains name claims."},"phone":{"type":"string","example":"+37360123456"},"country":{"type":"string","example":"moldova"},"city":{"type":"string","example":"chisinau"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL"},"idToken":{"type":"string"}}},"AuthLoginCredentialsDto":{"type":"object","properties":{"email":{"type":"string","example":"yourEmail@example.com"},"password":{"type":"string","example":"yourPassword123!"}},"required":["email","password"]},"RefreshTokenDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"refreshToken":{"type":"string"}},"required":["userId","refreshToken"]},"AuthLoginOauthDto":{"type":"object","properties":{"method":{"type":"string","enum":["oauth"],"description":"Optional marker for oauth flow.","default":"oauth"},"provider":{"type":"string","enum":["google","apple","facebook"]},"providerUserId":{"type":"string","example":"provider-user-subject","description":"Optional when idToken contains subject (sub) claim."},"oauthEmail":{"type":"string","example":"ion@example.com","description":"Optional when idToken contains email claim."},"name":{"type":"string","example":"Ion Popescu","description":"Optional when idToken contains name claims."},"phone":{"type":"string","example":"+37360123456"},"country":{"type":"string","example":"moldova"},"city":{"type":"string","example":"chisinau"},"language":{"type":"string","example":"ro"},"currency":{"type":"string","example":"MDL"},"idToken":{"type":"string"}},"required":["provider"]},"SsoLogoutDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"}},"required":["userId"]},"CreatePartnerOrganizationDto":{"type":"object","properties":{"organizationName":{"type":"string","example":"WashPoint Botanica"},"address":{"type":"string","example":"Str. Stefan cel Mare 42, Chisinau"},"city":{"type":"string","example":"chisinau"},"lat":{"type":"number","example":47.0245},"lng":{"type":"number","example":28.8322},"phone":{"type":"string","example":"+37322123456"},"contactEmail":{"type":"string","example":"partner@washpoint.md"},"bankIban":{"type":"string","example":"MD24AG000225100013104168"},"capacityPerHour":{"type":"number","example":4,"minimum":1,"maximum":1000,"description":"Maximum vehicles that can be processed simultaneously at this location per booking slot."},"hours":{"type":"object","description":"Working hours per weekday. Bookings availability depends on this schedule (e.g. monday, tuesday, ...).","additionalProperties":{"type":"object","properties":{"open":{"type":"string","example":"08:00"},"close":{"type":"string","example":"20:00"}},"required":["open","close"]},"example":{"monday":{"open":"08:00","close":"20:00"},"tuesday":{"open":"08:00","close":"20:00"},"wednesday":{"open":"08:00","close":"20:00"},"thursday":{"open":"08:00","close":"20:00"},"friday":{"open":"08:00","close":"20:00"},"saturday":{"open":"09:00","close":"18:00"}}},"services":{"example":["exterior","interior"],"type":"array","items":{"type":"string"}},"photos":{"example":["https://cdn.washpass.md/partners/washpoint-1.jpg"],"type":"array","items":{"type":"string"}},"ownerName":{"type":"string","example":"Ion Popescu"},"ownerEmail":{"type":"string","example":"ion.partner@example.com"},"ownerPhone":{"type":"string","example":"+37360123456"},"ownerPassword":{"type":"string","example":"Secret123!"},"ownerCountry":{"type":"string","example":"moldova"},"ownerLanguage":{"type":"string","example":"ro"},"ownerCurrency":{"type":"string","example":"MDL"}},"required":["organizationName","address","city","lat","lng","ownerName","ownerEmail","ownerPassword","ownerCountry","ownerLanguage","ownerCurrency"]},"PartnerOrganizationSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"WashPoint Botanica"},"address":{"type":"string","example":"Str. Stefan cel Mare 42, Chisinau"},"city":{"type":"string","example":"chisinau"},"lat":{"type":"number","example":47.0245},"lng":{"type":"number","example":28.8322},"phone":{"type":"string","example":"+37322123456"},"contactEmail":{"type":"string","example":"partner@washpoint.md"},"bankIban":{"type":"string","example":"MD24AG000225100013104168"},"capacityPerHour":{"type":"number","example":4},"hours":{"type":"object","additionalProperties":{"type":"object","properties":{"open":{"type":"string","example":"08:00"},"close":{"type":"string","example":"20:00"}}}},"services":{"example":["exterior","interior"],"type":"array","items":{"type":"string"}},"photos":{"example":["https://cdn.washpass.md/partners/washpoint-1.jpg"],"type":"array","items":{"type":"string"}}},"required":["id","name","address","city","lat","lng"]},"PartnerOrganizationDto":{"type":"object","properties":{"partnerId":{"type":"string","format":"uuid","description":"Partner organization identifier (UUID/GUID).","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"partner":{"$ref":"#/components/schemas/PartnerOrganizationSummaryDto"},"owner":{"description":"Provisioning response for the partner owner user.","allOf":[{"$ref":"#/components/schemas/UserProvisioningResponseDto"}]}},"required":["partnerId","partner","owner"]}}}}