{"openapi":"3.1.0","info":{"title":"MockData","version":"1.0.0","description":"Fake REST APIs with live JSON. Public resources need no keys. Auth demo: any seeded username + password `password`. Persian text: pass query `lang=fa` (English is default).","contact":{"name":"MockData"}},"servers":[{"url":"https://mockdata.ir","description":"Current deployment"},{"url":"http://localhost:3000","description":"Local development"}],"tags":[{"name":"Auth","description":"Mock login and current user"},{"name":"Users","description":"CRUD users with search and filters"},{"name":"Posts","description":"CRUD blog posts linked to users"},{"name":"Comments","description":"CRUD comments on posts"},{"name":"Albums","description":"CRUD photo albums linked to users"},{"name":"Photos","description":"CRUD photos grouped by albumId"},{"name":"Todos","description":"CRUD todos linked to users"},{"name":"Products","description":"CRUD catalog products"},{"name":"Notifications","description":"CRUD user notifications"},{"name":"Countries","description":"CRUD country records"},{"name":"Admin","description":"Protected ops (ADMIN_SECRET)"}],"paths":{"/api/admin/reset":{"post":{"tags":["Admin"],"summary":"Reset seed data","description":"Wipes seed tables and reloads default data. Requires ADMIN_SECRET via x-admin-key or Bearer.","operationId":"resetSeed","security":[{"adminKey":[]}],"parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Seed reloaded","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["reset","users","posts","comments","albums","photos","todos","products","notifications","countries"],"properties":{"reset":{"type":"boolean","example":true},"users":{"type":"integer","example":24},"posts":{"type":"integer","example":24},"comments":{"type":"integer","example":24},"albums":{"type":"integer","example":8},"photos":{"type":"integer","example":24},"todos":{"type":"integer","example":24},"products":{"type":"integer","example":24},"notifications":{"type":"integer","example":24},"countries":{"type":"integer","example":24}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (per IP)","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the window resets"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix timestamp (seconds)"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"ADMIN_SECRET not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Login","description":"Returns a Bearer token when username exists and password is `password`.","operationId":"login","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"},"example":{"username":"avachen","password":"password"}}}},"responses":{"200":{"description":"Authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Current user","operationId":"getMe","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current user","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/User"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/users":{"get":{"tags":["Users"],"summary":"List users","operationId":"listUsers","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"role","in":"query","schema":{"type":"string","enum":["admin","member","guest"]}},{"name":"country","in":"query","schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","name","username"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated users","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Users"],"summary":"Create user","operationId":"createUser","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/users/{id}":{"get":{"tags":["Users"],"summary":"Get user","operationId":"getUser","parameters":[{"name":"id","in":"path","required":true,"description":"User UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"User","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Users"],"summary":"Update user","operationId":"updateUser","parameters":[{"name":"id","in":"path","required":true,"description":"User UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}}},"responses":{"200":{"description":"Updated user","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Users"],"summary":"Delete user","operationId":"deleteUser","parameters":[{"name":"id","in":"path","required":true,"description":"User UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts":{"get":{"tags":["Posts"],"summary":"List posts","operationId":"listPosts","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"published","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","title"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated posts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Posts"],"summary":"Create post","operationId":"createPost","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/posts/{id}":{"get":{"tags":["Posts"],"summary":"Get post","operationId":"getPost","parameters":[{"name":"id","in":"path","required":true,"description":"Post UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Post","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Posts"],"summary":"Update post","operationId":"updatePost","parameters":[{"name":"id","in":"path","required":true,"description":"Post UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostUpdate"}}}},"responses":{"200":{"description":"Updated post","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Post"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Posts"],"summary":"Delete post","operationId":"deletePost","parameters":[{"name":"id","in":"path","required":true,"description":"Post UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/comments":{"get":{"tags":["Comments"],"summary":"List comments","operationId":"listComments","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"postId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","name"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated comments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Comments"],"summary":"Create comment","operationId":"createComment","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/comments/{id}":{"get":{"tags":["Comments"],"summary":"Get comment","operationId":"getComment","parameters":[{"name":"id","in":"path","required":true,"description":"Comment UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Comment","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Comments"],"summary":"Update comment","operationId":"updateComment","parameters":[{"name":"id","in":"path","required":true,"description":"Comment UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentUpdate"}}}},"responses":{"200":{"description":"Updated comment","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Comments"],"summary":"Delete comment","operationId":"deleteComment","parameters":[{"name":"id","in":"path","required":true,"description":"Comment UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/albums":{"get":{"tags":["Albums"],"summary":"List albums","operationId":"listAlbums","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","title","id"],"default":"id"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated albums","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Albums"],"summary":"Create album","operationId":"createAlbum","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Album"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/albums/{id}":{"get":{"tags":["Albums"],"summary":"Get album","operationId":"getAlbum","parameters":[{"name":"id","in":"path","required":true,"description":"Album integer id","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Album","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Album"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Albums"],"summary":"Update album","operationId":"updateAlbum","parameters":[{"name":"id","in":"path","required":true,"description":"Album integer id","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlbumUpdate"}}}},"responses":{"200":{"description":"Updated album","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Album"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Albums"],"summary":"Delete album","operationId":"deleteAlbum","parameters":[{"name":"id","in":"path","required":true,"description":"Album integer id","schema":{"type":"integer","minimum":1}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","example":1}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/photos":{"get":{"tags":["Photos"],"summary":"List photos","operationId":"listPhotos","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"albumId","in":"query","schema":{"type":"integer","minimum":1}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","title","albumId"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated photos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Photos"],"summary":"Create photo","operationId":"createPhoto","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Photo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/photos/{id}":{"get":{"tags":["Photos"],"summary":"Get photo","operationId":"getPhoto","parameters":[{"name":"id","in":"path","required":true,"description":"Photo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Photo","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Photo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Photos"],"summary":"Update photo","operationId":"updatePhoto","parameters":[{"name":"id","in":"path","required":true,"description":"Photo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhotoUpdate"}}}},"responses":{"200":{"description":"Updated photo","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Photo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Photos"],"summary":"Delete photo","operationId":"deletePhoto","parameters":[{"name":"id","in":"path","required":true,"description":"Photo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/todos":{"get":{"tags":["Todos"],"summary":"List todos","operationId":"listTodos","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"completed","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","title"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated todos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Todos"],"summary":"Create todo","operationId":"createTodo","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Todo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/todos/{id}":{"get":{"tags":["Todos"],"summary":"Get todo","operationId":"getTodo","parameters":[{"name":"id","in":"path","required":true,"description":"Todo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Todo","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Todo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Todos"],"summary":"Update todo","operationId":"updateTodo","parameters":[{"name":"id","in":"path","required":true,"description":"Todo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoUpdate"}}}},"responses":{"200":{"description":"Updated todo","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Todo"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Todos"],"summary":"Delete todo","operationId":"deleteTodo","parameters":[{"name":"id","in":"path","required":true,"description":"Todo UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products":{"get":{"tags":["Products"],"summary":"List products","operationId":"listProducts","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","name","price","stock"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated products","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Products"],"summary":"Create product","operationId":"createProduct","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products/{id}":{"get":{"tags":["Products"],"summary":"Get product","operationId":"getProduct","parameters":[{"name":"id","in":"path","required":true,"description":"Product UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Product","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Products"],"summary":"Update product","operationId":"updateProduct","parameters":[{"name":"id","in":"path","required":true,"description":"Product UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductUpdate"}}}},"responses":{"200":{"description":"Updated product","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Product"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Products"],"summary":"Delete product","operationId":"deleteProduct","parameters":[{"name":"id","in":"path","required":true,"description":"Product UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/notifications":{"get":{"tags":["Notifications"],"summary":"List notifications","operationId":"listNotifications","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"type","in":"query","schema":{"type":"string","enum":["info","success","warning","error"]}},{"name":"read","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","title"],"default":"createdAt"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated notifications","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Notifications"],"summary":"Create notification","operationId":"createNotification","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Notification"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/notifications/{id}":{"get":{"tags":["Notifications"],"summary":"Get notification","operationId":"getNotification","parameters":[{"name":"id","in":"path","required":true,"description":"Notification UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Notification","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Notification"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Notifications"],"summary":"Update notification","operationId":"updateNotification","parameters":[{"name":"id","in":"path","required":true,"description":"Notification UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationUpdate"}}}},"responses":{"200":{"description":"Updated notification","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Notification"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Notifications"],"summary":"Delete notification","operationId":"deleteNotification","parameters":[{"name":"id","in":"path","required":true,"description":"Notification UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/countries":{"get":{"tags":["Countries"],"summary":"List countries","operationId":"listCountries","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"region","in":"query","schema":{"type":"string"}},{"name":"code","in":"query","schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"sort","in":"query","schema":{"type":"string","enum":["createdAt","name","population"],"default":"name"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Paginated countries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Countries"],"summary":"Create country","operationId":"createCountry","parameters":[{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryCreate"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Country"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/countries/{id}":{"get":{"tags":["Countries"],"summary":"Get country","operationId":"getCountry","parameters":[{"name":"id","in":"path","required":true,"description":"Country UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Country","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Country"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Countries"],"summary":"Update country","operationId":"updateCountry","parameters":[{"name":"id","in":"path","required":true,"description":"Country UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryUpdate"}}}},"responses":{"200":{"description":"Updated country","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Country"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Countries"],"summary":"Delete country","operationId":"deleteCountry","parameters":[{"name":"id","in":"path","required":true,"description":"Country UUID","schema":{"type":"string","format":"uuid"}},{"name":"lang","in":"query","required":false,"description":"Pass fa for Persian (Iranian) text in the response. Omit for English (default).","schema":{"type":"string","enum":["fa"],"example":"fa"}},{"name":"delay","in":"query","required":false,"description":"Artificial response delay in milliseconds (0–5000).","schema":{"type":"integer","minimum":0,"maximum":5000}},{"name":"status","in":"query","required":false,"description":"Force an error response with this HTTP status (400–599). Useful for UI error states.","schema":{"type":"integer","minimum":400,"maximum":599,"example":500}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"mock.<userId>","description":"Token from POST /api/auth/login (`mock.<uuid>`)."},"adminKey":{"type":"apiKey","in":"header","name":"x-admin-key","description":"Same value as ADMIN_SECRET (or use Bearer)."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR","enum":["VALIDATION_ERROR","NOT_FOUND","UNAUTHORIZED","RATE_LIMITED","NOT_CONFIGURED","INTERNAL_ERROR"]},"message":{"type":"string","example":"Invalid request"},"details":{}}}}},"Pagination":{"type":"object","required":["page","limit","total","totalPages"],"properties":{"page":{"type":"integer","minimum":1,"example":1},"limit":{"type":"integer","minimum":1,"maximum":50,"example":12},"total":{"type":"integer","minimum":0,"example":24},"totalPages":{"type":"integer","minimum":1,"example":2}}},"User":{"type":"object","required":["id","name","username","email","avatarUrl","role","city","country","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Ava Chen"},"username":{"type":"string","example":"avachen"},"email":{"type":"string","format":"email","example":"ava.chen@example.com"},"avatarUrl":{"type":"string","format":"uri"},"phone":{"type":["string","null"]},"company":{"type":["string","null"]},"role":{"type":"string","enum":["admin","member","guest"]},"city":{"type":"string","example":"San Francisco"},"country":{"type":"string","example":"United States"},"bio":{"type":["string","null"]},"website":{"type":["string","null"],"format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"UserCreate":{"type":"object","required":["name","username","email","avatarUrl","city","country"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"username":{"type":"string","minLength":2,"maxLength":50,"pattern":"^[a-zA-Z0-9._-]+$"},"email":{"type":"string","format":"email","maxLength":255},"avatarUrl":{"type":"string","format":"uri","maxLength":2000},"phone":{"type":["string","null"],"maxLength":40},"company":{"type":["string","null"],"maxLength":120},"role":{"type":"string","enum":["admin","member","guest"],"default":"member"},"city":{"type":"string","minLength":1,"maxLength":100},"country":{"type":"string","minLength":1,"maxLength":100},"bio":{"type":["string","null"],"maxLength":1000},"website":{"type":["string","null"],"format":"uri","maxLength":500}}},"UserUpdate":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"username":{"type":"string","minLength":2,"maxLength":50,"pattern":"^[a-zA-Z0-9._-]+$"},"email":{"type":"string","format":"email","maxLength":255},"avatarUrl":{"type":"string","format":"uri","maxLength":2000},"phone":{"type":["string","null"],"maxLength":40},"company":{"type":["string","null"],"maxLength":120},"role":{"type":"string","enum":["admin","member","guest"],"default":"member"},"city":{"type":"string","minLength":1,"maxLength":100},"country":{"type":"string","minLength":1,"maxLength":100},"bio":{"type":["string","null"],"maxLength":1000},"website":{"type":["string","null"],"format":"uri","maxLength":500}},"description":"Partial user fields; at least one required."},"UserListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/User"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Post":{"type":"object","required":["id","userId","title","body","tags","published","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","example":"Why fake APIs speed up frontend work"},"body":{"type":"string"},"tags":{"type":"array","items":{"type":"string"},"example":["dx","mock"]},"published":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PostCreate":{"type":"object","required":["userId","title","body"],"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"body":{"type":"string","minLength":1,"maxLength":10000},"tags":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":40},"default":[]},"published":{"type":"boolean","default":true}}},"PostUpdate":{"type":"object","minProperties":1,"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"body":{"type":"string","minLength":1,"maxLength":10000},"tags":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":40},"default":[]},"published":{"type":"boolean","default":true}},"description":"Partial post fields; at least one required."},"PostListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Post"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Comment":{"type":"object","required":["id","postId","name","email","body","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"postId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Alex Rivera"},"email":{"type":"string","format":"email"},"body":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CommentCreate":{"type":"object","required":["postId","name","email","body"],"properties":{"postId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":255},"body":{"type":"string","minLength":1,"maxLength":2000}}},"CommentUpdate":{"type":"object","minProperties":1,"properties":{"postId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":255},"body":{"type":"string","minLength":1,"maxLength":2000}},"description":"Partial comment fields; at least one required."},"CommentListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Album":{"type":"object","required":["id","userId","title","createdAt","updatedAt"],"properties":{"id":{"type":"integer","example":1},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","example":"Desk & tools"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AlbumCreate":{"type":"object","required":["userId","title"],"properties":{"id":{"type":"integer","minimum":1,"maximum":10000},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200}}},"AlbumUpdate":{"type":"object","minProperties":1,"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200}},"description":"Partial album fields; at least one required."},"AlbumListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Album"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Photo":{"type":"object","required":["id","albumId","title","url","thumbnailUrl","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"albumId":{"type":"integer","example":1},"title":{"type":"string","example":"Morning desk setup"},"url":{"type":"string","format":"uri"},"thumbnailUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PhotoCreate":{"type":"object","required":["albumId","title","url","thumbnailUrl"],"properties":{"albumId":{"type":"integer","minimum":1,"maximum":100},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri","maxLength":2000},"thumbnailUrl":{"type":"string","format":"uri","maxLength":2000}}},"PhotoUpdate":{"type":"object","minProperties":1,"properties":{"albumId":{"type":"integer","minimum":1,"maximum":100},"title":{"type":"string","minLength":1,"maxLength":200},"url":{"type":"string","format":"uri","maxLength":2000},"thumbnailUrl":{"type":"string","format":"uri","maxLength":2000}},"description":"Partial photo fields; at least one required."},"PhotoListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Photo"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Todo":{"type":"object","required":["id","userId","title","completed","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","example":"Ship Posts docs page"},"completed":{"type":"boolean","example":false},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TodoCreate":{"type":"object","required":["userId","title"],"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"completed":{"type":"boolean","default":false}}},"TodoUpdate":{"type":"object","minProperties":1,"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"completed":{"type":"boolean","default":false}},"description":"Partial todo fields; at least one required."},"TodoListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Todo"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Product":{"type":"object","required":["id","name","description","price","stock","category","imageUrl","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Nordic Desk Lamp"},"description":{"type":"string"},"price":{"type":"number","example":49.99},"stock":{"type":"integer","example":120},"category":{"type":"string","example":"home"},"imageUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ProductCreate":{"type":"object","required":["name","description","price","category","imageUrl"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","minLength":1,"maxLength":2000},"price":{"type":"number","minimum":0},"stock":{"type":"integer","minimum":0,"default":0},"category":{"type":"string","minLength":1,"maxLength":100},"imageUrl":{"type":"string","format":"uri","maxLength":2000}}},"ProductUpdate":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","minLength":1,"maxLength":2000},"price":{"type":"number","minimum":0},"stock":{"type":"integer","minimum":0,"default":0},"category":{"type":"string","minLength":1,"maxLength":100},"imageUrl":{"type":"string","format":"uri","maxLength":2000}},"description":"Partial product fields; at least one required."},"ProductListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Notification":{"type":"object","required":["id","userId","title","message","type","read","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","example":"Welcome to MockData"},"message":{"type":"string"},"type":{"type":"string","enum":["info","success","warning","error"],"example":"info"},"read":{"type":"boolean","example":false},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"NotificationCreate":{"type":"object","required":["userId","title","message"],"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"message":{"type":"string","minLength":1,"maxLength":2000},"type":{"type":"string","enum":["info","success","warning","error"],"default":"info"},"read":{"type":"boolean","default":false}}},"NotificationUpdate":{"type":"object","minProperties":1,"properties":{"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"message":{"type":"string","minLength":1,"maxLength":2000},"type":{"type":"string","enum":["info","success","warning","error"],"default":"info"},"read":{"type":"boolean","default":false}},"description":"Partial notification fields; at least one required."},"NotificationListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Country":{"type":"object","required":["id","name","code","capital","region","population","currency","flagUrl","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Iran"},"code":{"type":"string","example":"IR"},"capital":{"type":"string","example":"Tehran"},"region":{"type":"string","example":"Asia"},"population":{"type":"integer","example":83992949},"currency":{"type":"string","example":"IRR"},"flagUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CountryCreate":{"type":"object","required":["name","code","capital","region","population","currency","flagUrl"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"code":{"type":"string","minLength":2,"maxLength":2,"example":"PT"},"capital":{"type":"string","minLength":1,"maxLength":120},"region":{"type":"string","minLength":1,"maxLength":80},"population":{"type":"integer","minimum":0},"currency":{"type":"string","minLength":1,"maxLength":10},"flagUrl":{"type":"string","format":"uri","maxLength":2000}}},"CountryUpdate":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"code":{"type":"string","minLength":2,"maxLength":2,"example":"PT"},"capital":{"type":"string","minLength":1,"maxLength":120},"region":{"type":"string","minLength":1,"maxLength":80},"population":{"type":"integer","minimum":0},"currency":{"type":"string","minLength":1,"maxLength":10},"flagUrl":{"type":"string","format":"uri","maxLength":2000}},"description":"Partial country fields; at least one required."},"CountryListResponse":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Country"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"LoginRequest":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string","minLength":1,"maxLength":50},"password":{"type":"string","minLength":1,"maxLength":200}}},"LoginResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["token","tokenType","expiresIn","user"],"properties":{"token":{"type":"string","example":"mock.550e8400-e29b-41d4-a716-446655440000"},"tokenType":{"type":"string","example":"Bearer"},"expiresIn":{"type":"integer","example":3600},"user":{"$ref":"#/components/schemas/User"}}}}}}}}