{"openapi":"3.1.0","info":{"title":"Black Swan API","version":"2.0.0"},"paths":{"/api/dealers":{"get":{"summary":"List Dealers","description":"Public list of dealers (used by the signup form).","operationId":"list_dealers_api_dealers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"summary":"Create Dealer","description":"Register a new dealer on the platform. Requires authentication.","operationId":"create_dealer_api_dealers_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DealerCreateBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dealers/{username}":{"delete":{"summary":"Delete Dealer","description":"Remove a dealer. Cars and customers linked to this dealer are reassigned or left unlinked.","operationId":"delete_dealer_api_dealers__username__delete","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/token":{"post":{"tags":["auth"],"summary":"Issue Token","description":"Exchange a username + password for a bearer token.\n\nAccepts the standard OAuth2 password grant (form-encoded).\nThe role is detected automatically: platform admin → dealer → customer.","operationId":"issue_token_api_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_issue_token_api_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/login":{"post":{"summary":"Login","operationId":"login_api_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin-login":{"post":{"summary":"Admin Login","description":"Dedicated super-admin login. The `role` field is ignored here.","operationId":"admin_login_api_auth_admin_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/signup":{"post":{"summary":"Signup","description":"Self sign-up - always creates a user-role account, assigned to the chosen dealer.","operationId":"signup_api_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/logout":{"post":{"summary":"Logout","operationId":"logout_api_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/auth/me":{"get":{"summary":"Me","operationId":"me_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/me/admin":{"get":{"summary":"Get Admin Profile","description":"Return the logged-in admin's own profile (no password hash).","operationId":"get_admin_profile_api_me_admin_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"patch":{"summary":"Update Admin Profile","description":"Update the admin's username and/or password. Requires current_password for re-auth.","operationId":"update_admin_profile_api_me_admin_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/me/profile":{"get":{"summary":"Get My Profile","description":"Return the full profile of the logged-in user.","operationId":"get_my_profile_api_me_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"patch":{"summary":"Update My Profile","description":"Update the logged-in user's own profile fields. All fields are optional.","operationId":"update_my_profile_api_me_profile_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/state":{"get":{"summary":"Get State","operationId":"get_state_api_state_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/cars/{vin}/owner":{"patch":{"summary":"Set Car Owner","operationId":"set_car_owner_api_cars__vin__owner_patch","parameters":[{"name":"vin","in":"path","required":true,"schema":{"type":"string","title":"Vin"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerAssignBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Clear Car Owner","operationId":"clear_car_owner_api_cars__vin__owner_delete","parameters":[{"name":"vin","in":"path","required":true,"schema":{"type":"string","title":"Vin"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cars/{vin}/state":{"patch":{"summary":"Update Car State","operationId":"update_car_state_api_cars__vin__state_patch","parameters":[{"name":"vin","in":"path","required":true,"schema":{"type":"string","title":"Vin"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarStateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/customers":{"get":{"summary":"List Customers","description":"All customers for the logged-in dealer (or all if super-admin).","operationId":"list_customers_api_customers_get","parameters":[{"name":"include_password","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Password"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/customers/{username}":{"get":{"summary":"Get Customer","operationId":"get_customer_api_customers__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}},{"name":"include_password","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Password"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cars":{"get":{"summary":"List All Cars","description":"List all vehicles in the system.","operationId":"list_all_cars_api_cars_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/cars/add-to-fleet":{"post":{"summary":"Add Car To Fleet","description":"Add a vehicle to a dealer's fleet by VIN.","operationId":"add_car_to_fleet_api_cars_add_to_fleet_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCarBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/reset":{"post":{"summary":"Admin Reset","description":"Reset the demo database to its seeded state.","operationId":"admin_reset_api_admin_reset_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AddCarBody":{"properties":{"vin":{"type":"string","minLength":1,"title":"Vin"},"dealer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dealer"}},"type":"object","required":["vin"],"title":"AddCarBody"},"AdminUpdateBody":{"properties":{"current_password":{"type":"string","title":"Current Password"},"username":{"anyOf":[{"type":"string","maxLength":32,"minLength":3,"pattern":"^[a-z0-9_]+$"},{"type":"null"}],"title":"Username"},"new_password":{"anyOf":[{"type":"string","minLength":4},{"type":"null"}],"title":"New Password"}},"type":"object","required":["current_password"],"title":"AdminUpdateBody"},"Body_issue_token_api_token_post":{"properties":{"grant_type":{"anyOf":[{"type":"string","pattern":"password"},{"type":"null"}],"title":"Grant Type"},"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"},"scope":{"type":"string","title":"Scope","default":""},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"}},"type":"object","required":["username","password"],"title":"Body_issue_token_api_token_post"},"CarStateBody":{"properties":{"locked":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Locked"},"climate":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Climate"},"charging":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Charging"}},"type":"object","title":"CarStateBody"},"DealerCreateBody":{"properties":{"username":{"type":"string","maxLength":20,"minLength":3,"pattern":"^[a-z0-9_]+$","title":"Username"},"password":{"type":"string","minLength":3,"title":"Password"},"name":{"type":"string","minLength":1,"title":"Name"},"city":{"type":"string","minLength":1,"title":"City"}},"type":"object","required":["username","password","name","city"],"title":"DealerCreateBody"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginBody":{"properties":{"role":{"type":"string","title":"Role"},"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"}},"type":"object","required":["role","username","password"],"title":"LoginBody"},"OwnerAssignBody":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"since":{"type":"string","title":"Since"}},"type":"object","required":["email","since"],"title":"OwnerAssignBody"},"ProfileUpdateBody":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"personnummer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Personnummer"},"home_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Home Lat"},"home_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Home Lng"},"work_lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Work Lat"},"work_lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Work Lng"},"emergency_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emergency Contact"},"emergency_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emergency Phone"},"insurance_policy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Insurance Policy"},"iban":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Iban"},"charging_card_rfid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Charging Card Rfid"},"dealer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dealer"}},"type":"object","title":"ProfileUpdateBody"},"SignupBody":{"properties":{"name":{"type":"string","minLength":1,"title":"Name"},"username":{"type":"string","maxLength":20,"minLength":3,"pattern":"^[a-z0-9_]+$","title":"Username"},"password":{"type":"string","minLength":4,"title":"Password"},"email":{"type":"string","format":"email","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","default":""},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address","default":""},"dealer":{"type":"string","minLength":1,"title":"Dealer"}},"type":"object","required":["name","username","password","email","dealer"],"title":"SignupBody"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"BearerAuth":{"type":"oauth2","description":"Sign in with your platform credentials.","flows":{"password":{"tokenUrl":"/api/token","scopes":{}}}}}},"security":[{"BearerAuth":[]}]}