{"openapi":"3.0.0","info":{"title":"ALL OVER APPS - ADMIN API","description":"Centralized administration API for all ALL OVER APPS applications. Manages multiple Shopify apps from a unified admin panel.","version":"1.0.0","contact":{"name":"ALL OVER APPS Team","email":"support@alloverapps.com"}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token obtained from /auth/login endpoint. Used for admin panel authentication."},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key for backend-to-backend authentication. Format: sk_appId_randomhex. Create keys via POST /api-keys endpoint."}},"schemas":{}},"paths":{"/health":{"get":{"summary":"Server health check","tags":["Health"],"description":"Check server status, database connections, and memory usage","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"timestamp":{"type":"string","format":"date-time"},"uptime":{"type":"number","description":"Server uptime in seconds"},"memory":{"type":"object","properties":{"rss":{"type":"string","description":"Resident Set Size","example":"128MB"},"heapUsed":{"type":"string","description":"Heap memory used","example":"64MB"},"heapTotal":{"type":"string","description":"Total heap size","example":"128MB"},"external":{"type":"string","description":"External memory (C++ objects)","example":"2MB"},"arrayBuffers":{"type":"string","description":"ArrayBuffers memory","example":"1MB"}}},"databases":{"type":"object","properties":{"connected":{"type":"integer","description":"Number of connected DBs"},"total":{"type":"integer","description":"Total number of configured DBs"},"failed":{"type":"integer","description":"Number of failed DBs"}}}}}}}}}}},"/auth/login":{"post":{"summary":"Back Office team login","tags":["Auth"],"description":"Authentication for internal team users using email and password","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","example":"admin@bannersallover.com"},"password":{"type":"string","format":"password","example":"password123"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"token":{"type":"string","description":"JWT token for authentication"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","example":"admin"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/auth/refresh":{"post":{"summary":"Refresh JWT token","tags":["Auth"],"description":"Generate a new JWT token from an existing one","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"token":{"type":"string","description":"New JWT token"},"user":{"type":"object"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/auth/hash-password":{"post":{"summary":"[DEV] Generate password hash","tags":["Auth"],"description":"Development endpoint to generate bcrypt hashes for passwords","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","example":"mypassword123"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"hash":{"type":"string","description":"Bcrypt hash of the password"}}}}}}}}},"/auth/me":{"get":{"summary":"Current user information","tags":["Auth"],"description":"Get authenticated user information","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/magic-link/":{"post":{"summary":"Send magic link","tags":["Magic Link"],"description":"Send a passwordless authentication link to the given email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","appId"],"properties":{"email":{"type":"string","format":"email"},"appId":{"type":"string","example":"banners-all-over"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/magic-link/verify":{"post":{"summary":"Verify magic link token","tags":["Magic Link"],"description":"Verify a magic link token and receive an end-user JWT","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"token":{"type":"string","description":"End user JWT"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"appId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/webhooks/resend":{"post":{"summary":"Resend email webhook receiver","tags":["Webhooks"],"description":"Receives email lifecycle events from Resend (sent, delivered, bounced, etc.). Verified by HMAC signature.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"processed":{"type":"boolean"},"eventId":{"type":"string","nullable":true}}}}}}}}},"/webhooks/cold-provider":{"post":{"summary":"Cold email provider webhook (stub)","tags":["Webhooks"],"description":"Placeholder endpoint for future cold-email provider integration.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}}}}},"/t/o/{token}":{"get":{"summary":"Open tracking pixel","tags":["Email Tracking"],"description":"Returns a 1x1 transparent GIF and records an \"opened\" event. Always returns 200.","parameters":[{"schema":{"type":"string"},"in":"path","name":"token","required":true,"description":"Signed tracking token (may end with .gif)"}],"responses":{"200":{"description":"1x1 transparent GIF","content":{"application/json":{"schema":{"type":"string","description":"1x1 transparent GIF"}}}}}}},"/t/c/{token}":{"get":{"summary":"Click tracking redirect","tags":["Email Tracking"],"description":"Records a \"clicked\" event and 302-redirects to the original URL.","parameters":[{"schema":{"type":"string"},"in":"path","name":"token","required":true,"description":"Signed tracking token"}],"responses":{"302":{"description":"Redirect to target URL","content":{"application/json":{"schema":{"type":"string","description":"Redirect to target URL"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/wants/":{"get":{"summary":"List wants","tags":["Wants"],"description":"Get paginated list of wants for an app. If authenticated, includes hasVoted status.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["feature","improvement","integration"]},"in":"query","name":"category","required":false,"description":"Filter by category"},{"schema":{"type":"string","enum":["newest","oldest","most_voted"],"default":"newest"},"in":"query","name":"sort","required":false,"description":"Sort order"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"voteCount":{"type":"integer","description":"Total number of votes"},"hasVoted":{"type":"boolean","description":"Whether the current user has voted"},"authorEmail":{"type":"string","description":"Email of the submitter"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Submit a want","tags":["Wants"],"description":"Submit a new want. Requires end-user authentication. Rate limited to 10 per hour.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","description","category"],"properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"Feature request title"},"description":{"type":"string","minLength":1,"maxLength":2000,"description":"Detailed description"},"category":{"type":"string","enum":["feature","improvement","integration"],"description":"Category"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"apiKeyAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"voteCount":{"type":"integer","description":"Total number of votes"},"hasVoted":{"type":"boolean","description":"Whether the current user has voted"},"authorEmail":{"type":"string","description":"Email of the submitter"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/wants/{id}":{"get":{"summary":"Get want by ID","tags":["Wants"],"description":"Get a single want. If authenticated, includes hasVoted status.","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"voteCount":{"type":"integer","description":"Total number of votes"},"hasVoted":{"type":"boolean","description":"Whether the current user has voted"},"authorEmail":{"type":"string","description":"Email of the submitter"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/wants/{id}/vote":{"post":{"summary":"Vote on a want","tags":["Wants"],"description":"Toggle vote on a want. Requires end-user authentication. Rate limited to 30 per hour.","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"voteCount":{"type":"integer","description":"Updated vote count"},"hasVoted":{"type":"boolean","description":"Whether the user now has an active vote"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/apps":{"get":{"summary":"List of available applications","tags":["Apps"],"description":"Get the list of all Shopify applications configured in the Back Office","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"banners-all-over"},"name":{"type":"string","example":"Banners All Over"},"features":{"type":"object","properties":{"canEditTemplates":{"type":"boolean"},"canEditUsers":{"type":"boolean"},"canViewMetrics":{"type":"boolean"}}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/metrics/aggregate/dashboard":{"get":{"summary":"Aggregated dashboard from all apps","tags":["Metrics"],"description":"Get combined metrics from all configured applications","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"aggregate":{"type":"object","description":"Aggregated totals from all apps","properties":{"shops":{"type":"object","properties":{"total":{"type":"integer","example":300},"active":{"type":"integer","example":250},"inactive":{"type":"integer","example":50},"newToday":{"type":"integer","example":5},"newThisWeek":{"type":"integer","example":42},"newThisMonth":{"type":"integer","example":180},"byPlan":{"type":"object"}}}}},"byApp":{"type":"array","description":"Individual dashboard for each app","items":{"type":"object"}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/metrics/aggregate/shops-over-time":{"get":{"summary":"Shops over time (all apps)","tags":["Metrics"],"description":"Get statistics of registered shops per day, aggregated from all applications","parameters":[{"schema":{"type":"integer","default":30},"in":"query","name":"days","required":false,"description":"Number of days to query"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"aggregate":{"type":"array","description":"Aggregated data by date","items":{"type":"object","properties":{"date":{"type":"string","example":"2024-01-15"},"total":{"type":"integer","example":25},"byApp":{"type":"object"}}}},"byApp":{"type":"array","description":"Individual data for each app","items":{"type":"object"}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/metrics/aggregate/top-shops":{"get":{"summary":"Top shops (all apps)","tags":["Metrics"],"description":"Get most recently active shops, aggregating data from all applications. Shops appearing in multiple apps are merged.","parameters":[{"schema":{"type":"integer","default":10},"in":"query","name":"limit","required":false,"description":"Number of shops to return"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"aggregate":{"type":"array","description":"Aggregated top shops by recent activity","items":{"type":"object","properties":{"shop":{"type":"string","example":"my-store.myshopify.com"},"name":{"type":"string","example":"My Store"},"domain":{"type":"string","example":"mystore.com"},"isActive":{"type":"boolean","example":true},"lastLogin":{"type":"string","format":"date-time"},"apps":{"type":"array","description":"Apps this shop is using","items":{"type":"object","properties":{"appId":{"type":"string"},"appName":{"type":"string"},"plan":{"type":"string"},"isActive":{"type":"boolean"}}}}}}},"byApp":{"type":"array","description":"Top shops per app","items":{"type":"object"}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/metrics/aggregate/activity":{"get":{"summary":"Recent activity (all apps)","tags":["Metrics"],"description":"Get recent activity from all applications, combined and sorted by timestamp","parameters":[{"schema":{"type":"integer","default":20},"in":"query","name":"limit","required":false,"description":"Number of activities to return"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","description":"List of recent activities with app information","items":{"type":"object","properties":{"type":{"type":"string","enum":["new_shop","shop_login","shop_updated"],"example":"new_shop"},"appId":{"type":"string","example":"banners-all-over"},"appName":{"type":"string","example":"Banners All Over"},"shop":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"domain":{"type":"string"},"isActive":{"type":"boolean"}}},"timestamp":{"type":"string","format":"date-time"}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/metrics/aggregate/summary":{"get":{"summary":"Quick summary (all apps)","tags":["Metrics"],"description":"Get a concise summary of key metrics for all applications","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"totals":{"type":"object","description":"Aggregated totals","properties":{"totalShops":{"type":"integer","example":300},"activeShops":{"type":"integer","example":250},"inactiveShops":{"type":"integer","example":50},"newToday":{"type":"integer","example":5},"newThisWeek":{"type":"integer","example":42},"newThisMonth":{"type":"integer","example":180}}},"byApp":{"type":"array","description":"Summary per app","items":{"type":"object","properties":{"appId":{"type":"string"},"appName":{"type":"string"},"totalShops":{"type":"integer"},"activeShops":{"type":"integer"},"inactiveShops":{"type":"integer"},"newToday":{"type":"integer"},"newThisWeek":{"type":"integer"},"newThisMonth":{"type":"integer"}}}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/users/":{"get":{"summary":"List users","tags":["Users"],"description":"Get list of admin users","parameters":[{"schema":{"type":"string","enum":["admin","user","viewer"]},"in":"query","name":"role","required":false,"description":"Filter by role"},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"isActive","required":false,"description":"Filter by active status"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"role":{"type":"string"},"isActive":{"type":"boolean"},"profile":{"type":"object","properties":{"avatar":{"type":"string"},"bio":{"type":"string"},"phone":{"type":"string"},"timezone":{"type":"string"},"language":{"type":"string"}}},"settings":{"type":"object","properties":{"notifications":{"type":"object","properties":{"email":{"type":"boolean"},"push":{"type":"boolean"}}},"theme":{"type":"string"},"defaultApp":{"type":"string"}}},"lastLoginAt":{"type":"string","format":"date-time"},"loginCount":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Create user","tags":["Users"],"description":"Create new admin user","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","firstName","lastName"],"properties":{"email":{"type":"string","format":"email","description":"User email"},"password":{"type":"string","minLength":6,"description":"User password"},"firstName":{"type":"string","description":"First name"},"lastName":{"type":"string","description":"Last name"},"role":{"type":"string","enum":["admin","user","viewer"],"default":"user","description":"User role"},"profile":{"type":"object","properties":{"avatar":{"type":"string","description":"Avatar URL"},"bio":{"type":"string","description":"User bio","maxLength":500},"phone":{"type":"string","description":"Phone number"},"timezone":{"type":"string","description":"Timezone","default":"UTC"},"language":{"type":"string","enum":["en","es"],"default":"en","description":"Preferred language"}}},"settings":{"type":"object","properties":{"notifications":{"type":"object","properties":{"email":{"type":"boolean","default":true,"description":"Email notifications"},"push":{"type":"boolean","default":false,"description":"Push notifications"}}},"theme":{"type":"string","enum":["light","dark","auto"],"default":"auto","description":"UI theme"},"defaultApp":{"type":"string","description":"Default app ID"}}}}}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/users/{id}":{"get":{"summary":"Get user by ID","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update user","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","description":"First name"},"lastName":{"type":"string","description":"Last name"},"role":{"type":"string","enum":["admin","user","viewer"],"description":"User role"},"isActive":{"type":"boolean","description":"Active status"},"profile":{"type":"object","properties":{"avatar":{"type":"string","description":"Avatar URL"},"bio":{"type":"string","description":"User bio","maxLength":500},"phone":{"type":"string","description":"Phone number"},"timezone":{"type":"string","description":"Timezone"},"language":{"type":"string","enum":["en","es"],"description":"Preferred language"}}},"settings":{"type":"object","properties":{"notifications":{"type":"object","properties":{"email":{"type":"boolean","description":"Email notifications"},"push":{"type":"boolean","description":"Push notifications"}}},"theme":{"type":"string","enum":["light","dark","auto"],"description":"UI theme"},"defaultApp":{"type":"string","description":"Default app ID"}}}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete user","tags":["Users"],"description":"Soft delete user (sets isActive to false)","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/users/{id}/password":{"patch":{"summary":"Update user password","tags":["Users"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","minLength":6,"description":"New password"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/feedback/":{"get":{"summary":"List all feedback","tags":["Feedback"],"description":"Get paginated list of feedback from all apps (optionally filter by appId)","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Optional: Filter by app ID"},{"schema":{"type":"string","enum":["pending","in_progress","resolved","closed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["bug","feature","improvement","general","praise"]},"in":"query","name":"type","required":false,"description":"Filter by type"},{"schema":{"type":"string","enum":["low","normal","high","urgent"]},"in":"query","name":"priority","required":false,"description":"Filter by priority"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","enum":["excellent","good","average","poor","terrible"]},"in":"query","name":"rating","required":false,"description":"Filter by rating"},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in subject and message"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/feedback/{feedbackId}":{"get":{"summary":"Get feedback by ID","tags":["Feedback"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"feedbackId","required":true,"description":"Feedback ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update feedback","tags":["Feedback"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","in_progress","resolved","closed"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"feedbackId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete feedback","tags":["Feedback"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"feedbackId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/feedback/{feedbackId}/status":{"patch":{"summary":"Update feedback status","tags":["Feedback"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["pending","in_progress","resolved","closed"],"description":"Feedback status"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"feedbackId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/tickets/":{"get":{"summary":"List all tickets","tags":["Tickets"],"description":"Get paginated list of tickets from all apps (optionally filter by appId)","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Optional: Filter by app ID"},{"schema":{"type":"string","enum":["pending","in_progress","resolved","closed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["general","technical","billing","feature"]},"in":"query","name":"topic","required":false,"description":"Filter by topic"},{"schema":{"type":"string","enum":["low","normal","high","urgent"]},"in":"query","name":"priority","required":false,"description":"Filter by priority"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string"},"in":"query","name":"email","required":false,"description":"Filter by email"},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in subject, message, and email"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/tickets/{messageId}":{"get":{"summary":"Get ticket by ID","tags":["Tickets"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update ticket","tags":["Tickets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","in_progress","resolved","closed"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"messageId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete ticket","tags":["Tickets"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"messageId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/tickets/{messageId}/status":{"patch":{"summary":"Update ticket status","tags":["Tickets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["pending","in_progress","resolved","closed"],"description":"Ticket status"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"messageId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api-keys/stats":{"get":{"summary":"API key statistics","tags":["API Keys"],"description":"Get API key statistics (total, active, inactive, by app)","parameters":[{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Filter by app ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"},"inactive":{"type":"integer"},"expired":{"type":"integer"},"byApp":{"type":"object"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api-keys/":{"get":{"summary":"List API keys","tags":["API Keys"],"description":"Get list of API keys with pagination and filters","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Filter by app ID"},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"isActive","required":false,"description":"Filter by active status"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in name and description"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false,"description":"Sort by field"},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false,"description":"Sort order"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed origins for CORS (URLs, wildcard patterns, or *)"},"isActive":{"type":"boolean"},"lastUsed":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Create API key","tags":["API Keys"],"description":"Create new API key for an app. The full key is returned only once.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["appId","name"],"properties":{"appId":{"type":"string","description":"App ID for this key"},"name":{"type":"string","description":"Name/label for this key"},"description":{"type":"string","description":"Optional description"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed origins (e.g., [\"https://example.com\", \"*.mydomain.com\"] or [\"*\"])","example":["https://app.example.com","*.dev.example.com"]},"expiresAt":{"type":"string","format":"date-time","description":"Optional expiration date"}}}}}},"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"key":{"type":"string","description":"Full API key (shown only once!)"},"appId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed origins for CORS"},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api-keys/{keyId}":{"get":{"summary":"Get API key","tags":["API Keys"],"description":"Get API key details by ID (includes the full key value)","parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true,"description":"API key ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"key":{"type":"string","description":"Full API key value"},"appId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed origins for CORS"},"isActive":{"type":"boolean"},"lastUsed":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update API key","tags":["API Keys"],"description":"Update API key details (name, description, expiration)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name/label"},"description":{"type":"string","description":"Description"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed origins (e.g., [\"https://example.com\", \"*.mydomain.com\"] or [\"*\"])"},"isActive":{"type":"boolean","description":"Active status"},"expiresAt":{"type":"string","format":"date-time","description":"Expiration date"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true,"description":"API key ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete API key","tags":["API Keys"],"description":"Permanently delete an API key","parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true,"description":"API key ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api-keys/{keyId}/revoke":{"post":{"summary":"Revoke API key","tags":["API Keys"],"description":"Revoke (deactivate) an API key","parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true,"description":"API key ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/api-keys/{keyId}/regenerate":{"post":{"summary":"Regenerate API key","tags":["API Keys"],"description":"Generate a new key value for an existing API key. The new key is returned only once.","parameters":[{"schema":{"type":"string"},"in":"path","name":"keyId","required":true,"description":"API key ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"key":{"type":"string","description":"New API key (shown only once!)"},"appId":{"type":"string"},"name":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/contacts/":{"get":{"summary":"List contacts","tags":["Contacts"],"description":"Get paginated list of contacts with optional filters by email, consent category, or tag","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search by email, first name, or last name"},{"schema":{"type":"string","enum":["outreach","commercial","blog"]},"in":"query","name":"category","required":false,"description":"Filter by consent category"},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"categoryStatus","required":false,"description":"Filter by consent status (requires category)"},{"schema":{"type":"string"},"in":"query","name":"tag","required":false,"description":"Filter by tag"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/contacts/{id}":{"get":{"summary":"Get contact by ID","tags":["Contacts"],"description":"Get contact details including full consent change history","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"GDPR delete contact","tags":["Contacts"],"description":"Soft-delete and anonymize a contact (right-to-be-forgotten). PII is removed but consent audit log is retained anonymized.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/contacts/{id}/consent":{"patch":{"summary":"Update consent for a category","tags":["Contacts"],"description":"Update consent status for a specific category. Creates an immutable consent_event log entry.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["category","status"],"properties":{"category":{"type":"string","enum":["outreach","commercial","blog"],"description":"Consent category to update"},"status":{"type":"boolean","description":"New consent status"},"reason":{"type":"string","description":"Reason for the change"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/contacts/{id}/opt-out":{"post":{"summary":"Global opt-out","tags":["Contacts"],"description":"Opt out contact from all email categories. No emails will be sent to this contact.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Reason for opt-out"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/contacts/{id}/export":{"get":{"summary":"GDPR data export","tags":["Contacts"],"description":"Export all data for a contact (right-to-access). Returns contact details and full consent history.","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-events/":{"get":{"summary":"List email events","tags":["Email Events"],"description":"List email lifecycle events with filters and pagination.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"contactId","required":false,"description":"Filter by contact ID"},{"schema":{"type":"string"},"in":"query","name":"campaignId","required":false,"description":"Filter by campaign ID"},{"schema":{"type":"string"},"in":"query","name":"messageId","required":false,"description":"Filter by message ID"},{"schema":{"type":"string","enum":["queued","sent","delivered","opened","clicked","bounced","complained","unsubscribed","replied"]},"in":"query","name":"type","required":false,"description":"Filter by event type"},{"schema":{"type":"string","enum":["resend","custom"]},"in":"query","name":"provider","required":false,"description":"Filter by provider"},{"schema":{"type":"string"},"in":"query","name":"appId","required":false,"description":"Filter by app ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"contactId":{"type":"string"},"messageId":{"type":"string"},"campaignId":{"type":"string"},"provider":{"type":"string"},"type":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-events/message/{messageId}":{"get":{"summary":"Get events for a message","tags":["Email Events"],"description":"Get all email lifecycle events for a specific message ID.","parameters":[{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Resend message ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"type":{"type":"string"},"provider":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-events/campaign/{campaignId}/stats":{"get":{"summary":"Campaign event statistics","tags":["Email Events"],"description":"Get event counts by type for a specific campaign.","parameters":[{"schema":{"type":"string"},"in":"path","name":"campaignId","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","additionalProperties":{"type":"integer"}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email/analytics/campaigns/{campaignId}":{"get":{"summary":"Campaign analytics","tags":["Email Analytics"],"description":"Full campaign performance: sent, delivered, opened, clicked, bounced, unique counts, open rate (unique opens / delivered), CTR (unique clicks / unique opens), top clicked links, and event timeline.","parameters":[{"schema":{"type":"string"},"in":"path","name":"campaignId","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"campaignId":{"type":"string"},"sent":{"type":"integer"},"delivered":{"type":"integer"},"opened":{"type":"integer"},"uniqueOpens":{"type":"integer"},"clicked":{"type":"integer"},"uniqueClicks":{"type":"integer"},"bounced":{"type":"integer"},"complained":{"type":"integer"},"unsubscribed":{"type":"integer"},"openRate":{"type":"number","description":"Unique opens / delivered"},"clickThroughRate":{"type":"number","description":"Unique clicks / unique opens"},"topLinks":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"clicks":{"type":"integer"}}}},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"type":{"type":"string"},"count":{"type":"integer"}}}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email/analytics/campaigns/{campaignId}/recipients":{"get":{"summary":"Campaign recipients breakdown","tags":["Email Analytics"],"description":"Per-recipient status breakdown for a campaign. Shows each contact and which event types they triggered.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"path","name":"campaignId","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"contactId":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"Event types triggered by this contact"},"lastEvent":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email/analytics/contacts/{contactId}":{"get":{"summary":"Contact engagement history","tags":["Email Analytics"],"description":"Full engagement history for a contact across all campaigns. Includes summary counts and paginated event timeline.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"path","name":"contactId","required":true,"description":"Contact ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"contactId":{"type":"string"},"totalSent":{"type":"integer"},"totalOpened":{"type":"integer"},"totalClicked":{"type":"integer"},"totalBounced":{"type":"integer"},"totalComplained":{"type":"integer"},"events":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"campaignId":{"type":"string"},"messageId":{"type":"string"},"type":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email/analytics/overview":{"get":{"summary":"Global email analytics overview","tags":["Email Analytics"],"description":"Dashboard KPIs for a time range. Aggregate numbers across all campaigns: totals, rates, and daily timeline.","parameters":[{"schema":{"type":"string","format":"date-time","example":"2026-01-01T00:00:00Z"},"in":"query","name":"from","required":false,"description":"Start of time range (ISO 8601, UTC)"},{"schema":{"type":"string","format":"date-time","example":"2026-12-31T23:59:59Z"},"in":"query","name":"to","required":false,"description":"End of time range (ISO 8601, UTC)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"totalSent":{"type":"integer"},"totalDelivered":{"type":"integer"},"totalOpened":{"type":"integer"},"totalUniqueOpens":{"type":"integer"},"totalClicked":{"type":"integer"},"totalUniqueClicks":{"type":"integer"},"totalBounced":{"type":"integer"},"totalComplained":{"type":"integer"},"totalUnsubscribed":{"type":"integer"},"openRate":{"type":"number"},"clickThroughRate":{"type":"number"},"bounceRate":{"type":"number"},"complaintRate":{"type":"number"},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"sent":{"type":"integer"},"delivered":{"type":"integer"},"opened":{"type":"integer"},"clicked":{"type":"integer"}}}}}}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-jobs/":{"get":{"summary":"List email jobs","tags":["Email Jobs"],"description":"List email jobs with filtering and pagination","parameters":[{"schema":{"type":"string","enum":["pending","processing","completed","failed","dead"]},"in":"query","name":"status","required":false,"description":"Filter by job status"},{"schema":{"type":"string","enum":["email.send","email.batch.plan","sequence.tick"]},"in":"query","name":"type","required":false,"description":"Filter by job type"},{"schema":{"type":"string"},"in":"query","name":"campaignId","required":false,"description":"Filter by campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"type":{"type":"string","enum":["email.send","email.batch.plan","sequence.tick"]},"status":{"type":"string","enum":["pending","processing","completed","failed","dead"]},"priority":{"type":"integer"},"payload":{"type":"object"},"result":{"type":"object"},"attempts":{"type":"integer"},"maxAttempts":{"type":"integer"},"lastError":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-jobs/stats":{"get":{"summary":"Email job statistics","tags":["Email Jobs"],"description":"Get aggregate job queue statistics, optionally filtered by campaign","parameters":[{"schema":{"type":"string"},"in":"query","name":"campaignId","required":false,"description":"Filter stats by campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"pending":{"type":"integer"},"processing":{"type":"integer"},"completed":{"type":"integer"},"failed":{"type":"integer"},"dead":{"type":"integer"},"total":{"type":"integer"},"progress":{"type":"object","properties":{"total":{"type":"integer"},"completed":{"type":"integer"},"failed":{"type":"integer"},"pending":{"type":"integer"},"processing":{"type":"integer"},"dead":{"type":"integer"},"percentage":{"type":"integer"}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/email-jobs/{id}":{"get":{"summary":"Get email job details","tags":["Email Jobs"],"description":"Get a single email job by ID with full payload, result, and error details","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Job ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"type":{"type":"string","enum":["email.send","email.batch.plan","sequence.tick"]},"status":{"type":"string","enum":["pending","processing","completed","failed","dead"]},"priority":{"type":"integer"},"payload":{"type":"object"},"result":{"type":"object"},"attempts":{"type":"integer"},"maxAttempts":{"type":"integer"},"lastError":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/shops/stats":{"get":{"summary":"Shop statistics","tags":["Shops"],"description":"Get aggregated shop statistics for an app","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"},"inactive":{"type":"integer"},"byPlan":{"type":"object"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/shops/domains":{"get":{"summary":"List of shop domains","tags":["Shops"],"description":"Get all unique shop myshopify domains","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/shops/":{"get":{"summary":"List shops","tags":["Shops"],"description":"Get paginated list of shops with filters","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"boolean"},"in":"query","name":"isActive","required":false,"description":"Filter by active status"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search by email, name, or domain"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/shops/{shopId}":{"get":{"summary":"Get shop by ID","tags":["Shops"],"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"shopId","required":true,"description":"Shop ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update shop","tags":["Shops"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","description":"Shop email address"},"name":{"type":"string","description":"Shop display name"},"isActive":{"type":"boolean","description":"Shop active status"},"settings":{"type":"object","description":"Shop settings (notifications, styles, etc.)"},"plan":{"type":"object","description":"Subscription plan","properties":{"type":{"type":"string","enum":["basic","standard_monthly","standard_yearly","pro_monthly","pro_yearly","business_monthly","business_yearly","enterprise"]},"activatedAt":{"type":"string","format":"date-time"},"trialEndsAt":{"type":"string","format":"date-time"}}},"needsDataRefresh":{"type":"boolean","description":"Force data refresh on next login"},"needsAuthUpdate":{"type":"boolean","description":"Force auth update on next login"},"timezone":{"type":"string","description":"Shop timezone (e.g., America/New_York)"},"storeLocale":{"type":"string","description":"Shop locale/language (e.g., en, es)"},"auth":{"type":"object","description":"API access configuration","properties":{"corsEnabled":{"type":"boolean","description":"Enable CORS for API requests"},"isApiActive":{"type":"boolean","description":"Enable/disable API access"},"allowedOrigins":{"type":"array","items":{"type":"string"},"description":"Allowed CORS origins"}}}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"shopId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/shops/{shopId}/status":{"patch":{"summary":"Change shop status","tags":["Shops"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["isActive"],"properties":{"isActive":{"type":"boolean","description":"Shop active status"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"shopId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/templates/categories":{"get":{"summary":"Template languages","tags":["Templates"],"description":"Get all available template languages with counts","parameters":[{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/templates/":{"get":{"summary":"List templates","tags":["Templates"],"description":"Get paginated list of email templates","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","enum":["en","es","fr","de","it","pt"]},"in":"query","name":"language","required":false,"description":"Filter by language"},{"schema":{"type":"boolean"},"in":"query","name":"isActive","required":false,"description":"Filter by active status"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search by name or subject"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Create template","tags":["Templates"],"description":"Create a new email template","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","language","subject","htmlTemplate","textTemplate"],"properties":{"name":{"type":"string","description":"Template name"},"language":{"type":"string","enum":["en","es","fr","de","it","pt"],"default":"en"},"subject":{"type":"string","description":"Email subject"},"htmlTemplate":{"type":"string","description":"HTML template content"},"textTemplate":{"type":"string","description":"Plain text template content"},"variables":{"type":"array","items":{"type":"string"},"description":"Available variables"},"isActive":{"type":"boolean","default":true},"version":{"type":"number","default":1},"shopId":{"type":"string","description":"Shop ID (optional)"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/templates/{templateId}":{"get":{"summary":"Get template by ID","tags":["Templates"],"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"put":{"summary":"Update template (full)","tags":["Templates"],"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Update template (partial)","tags":["Templates"],"description":"Partial update - only updates provided fields","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Delete template","tags":["Templates"],"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/templates/{templateId}/toggle":{"patch":{"summary":"Toggle template active status","tags":["Templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["isActive"],"properties":{"isActive":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/templates/{templateId}/duplicate":{"post":{"summary":"Duplicate template","tags":["Templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name for the duplicated template"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"templateId","required":true}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/metrics/dashboard":{"get":{"summary":"General dashboard","tags":["Metrics"],"description":"Get aggregated metrics for main dashboard","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object"}}}}}}}}},"/{appId}/metrics/shops-over-time":{"get":{"summary":"Shops over time","tags":["Metrics"],"description":"Get statistics of registered shops per day","parameters":[{"schema":{"type":"integer","default":30},"in":"query","name":"days","required":false,"description":"Number of days to query"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/metrics/top-shops":{"get":{"summary":"Top shops","tags":["Metrics"],"description":"Get most recently active shops","parameters":[{"schema":{"type":"integer","default":10},"in":"query","name":"limit","required":false,"description":"Number of shops to return"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/metrics/activity":{"get":{"summary":"Recent activity","tags":["Metrics"],"description":"Get recent activity in the application","parameters":[{"schema":{"type":"integer","default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/metrics/custom":{"get":{"summary":"Custom metrics","tags":["Metrics"],"description":"Get stored custom metrics with filters","parameters":[{"schema":{"type":"string"},"in":"query","name":"type","required":false,"description":"Metric type"},{"schema":{"type":"string"},"in":"query","name":"shop","required":false},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false},{"schema":{"type":"integer","default":100},"in":"query","name":"limit","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response"}}}},"/{appId}/logs/stats":{"get":{"summary":"Log statistics","tags":["Logs"],"description":"Get aggregated log statistics for an app","parameters":[{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"shopDomain","required":false,"description":"Filter by shop domain"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"byLevel":{"type":"object","properties":{"debug":{"type":"integer"},"info":{"type":"integer"},"warn":{"type":"integer"},"error":{"type":"integer"}}},"topModules":{"type":"array","items":{"type":"object","properties":{"module":{"type":"string"},"count":{"type":"integer"}}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/logs/shop-domains":{"get":{"summary":"List of shop domains","tags":["Logs"],"description":"Get all unique shop domains from logs","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/logs/modules":{"get":{"summary":"List of modules","tags":["Logs"],"description":"Get all unique module names from logs","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/logs/over-time":{"get":{"summary":"Logs over time","tags":["Logs"],"description":"Get log statistics over time for charts","parameters":[{"schema":{"type":"integer","default":7},"in":"query","name":"days","required":false,"description":"Number of days to query"},{"schema":{"type":"string","enum":["debug","info","warn","error"]},"in":"query","name":"level","required":false,"description":"Filter by log level"},{"schema":{"type":"string"},"in":"query","name":"module","required":false,"description":"Filter by module"},{"schema":{"type":"string"},"in":"query","name":"shopDomain","required":false,"description":"Filter by shop domain"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","example":"2024-01-15"},"debug":{"type":"integer"},"info":{"type":"integer"},"warn":{"type":"integer"},"error":{"type":"integer"},"total":{"type":"integer"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/logs/":{"get":{"summary":"List logs","tags":["Logs"],"description":"Get paginated list of logs with filters","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["debug","info","warn","error"]},"in":"query","name":"level","required":false,"description":"Filter by log level"},{"schema":{"type":"string"},"in":"query","name":"module","required":false,"description":"Filter by module"},{"schema":{"type":"string"},"in":"query","name":"shopDomain","required":false,"description":"Filter by shop domain"},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in message"},{"schema":{"type":"string","default":"createdAtTimestamp"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"shopDomain":{"type":"string"},"module":{"type":"string"},"level":{"type":"string","enum":["debug","info","warn","error"]},"message":{"type":"string"},"data":{"type":"object"},"error":{"type":"object","properties":{"name":{"type":"string"},"message":{"type":"string"},"stack":{"type":"string"},"type":{"type":"string"},"isErrorInstance":{"type":"boolean"}}},"createdAtTimestamp":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete logs","tags":["Logs"],"description":"Delete logs based on filters (cleanup operation)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"olderThanDays":{"type":"integer","description":"Delete logs older than N days"},"level":{"type":"string","enum":["debug","info","warn","error"],"description":"Delete only logs of this level"},"module":{"type":"string","description":"Delete only logs from this module"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"deletedCount":{"type":"integer"}}},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/logs/{logId}":{"get":{"summary":"Get log by ID","tags":["Logs"],"description":"Get detailed information about a specific log entry","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"logId","required":true,"description":"Log ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete log by ID","tags":["Logs"],"description":"Delete a specific log entry by its ID","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"logId","required":true,"description":"Log ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/feedback/stats":{"get":{"summary":"Feedback statistics","tags":["Feedback"],"description":"Get aggregated feedback statistics for an app","parameters":[{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"byStatus":{"type":"object"},"byType":{"type":"object"},"byPriority":{"type":"object"},"byRating":{"type":"object"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/feedback/":{"post":{"summary":"Create feedback","tags":["Feedback"],"description":"Create new feedback entry","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["shopId","type","subject","message"],"properties":{"shopId":{"type":"string","description":"Shop ID"},"type":{"type":"string","enum":["bug","feature","improvement","general","praise"],"description":"Feedback type"},"subject":{"type":"string","description":"Feedback subject"},"message":{"type":"string","description":"Feedback message"},"rating":{"type":"string","enum":["excellent","good","average","poor","terrible"],"description":"Optional rating"},"ratingReason":{"type":"string","description":"Reason for rating"},"canContact":{"type":"boolean","description":"Can contact user about this feedback","default":false},"priority":{"type":"string","enum":["low","normal","high","urgent"],"default":"normal"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"get":{"summary":"List feedback","tags":["Feedback"],"description":"Get paginated list of feedback for an app","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["pending","in_progress","resolved","closed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["bug","feature","improvement","general","praise"]},"in":"query","name":"type","required":false,"description":"Filter by type"},{"schema":{"type":"string","enum":["low","normal","high","urgent"]},"in":"query","name":"priority","required":false,"description":"Filter by priority"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","enum":["excellent","good","average","poor","terrible"]},"in":"query","name":"rating","required":false,"description":"Filter by rating"},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in subject and message"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/tickets/stats":{"get":{"summary":"Ticket statistics","tags":["Tickets"],"description":"Get aggregated ticket statistics for an app","parameters":[{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of tickets"},"byStatus":{"type":"object","description":"Ticket count grouped by status","additionalProperties":{"type":"integer"}},"byTopic":{"type":"object","description":"Ticket count grouped by topic","additionalProperties":{"type":"integer"}},"byPriority":{"type":"object","description":"Ticket count grouped by priority","additionalProperties":{"type":"integer"}},"recentActivity":{"type":"array","description":"Last 10 tickets","items":{"type":"object","properties":{"_id":{"type":"string"},"subject":{"type":"string"},"email":{"type":"string"},"status":{"type":"string"},"priority":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"volumeOverTime":{"type":"array","description":"Ticket volume per day (last 30 days)","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"count":{"type":"integer"}}}},"averageResolutionTime":{"type":"number","nullable":true,"description":"Average time to resolve tickets (in hours)"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/tickets/":{"post":{"summary":"Create ticket with attachments","tags":["Tickets"],"description":"Create new support ticket with optional file attachments.\n\n**Content Types:**\n- `application/json`: For tickets without attachments\n- `multipart/form-data`: For tickets with file attachments\n\n**File Constraints:**\n- Max file size: 50MB per file\n- Max files: 5 per ticket\n- Allowed types: images (jpeg, png, gif, webp, svg), videos (mp4, webm, quicktime), PDF\n\n**Multipart Fields:**\n- `shopId`: string (required)\n- `topic`: enum (required)\n- `email`: string (required)\n- `subject`: string (required)\n- `message`: string (required)\n- `priority`: enum (optional, default: normal)\n- `attachments`: file(s) (optional, can send multiple)","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"shopId":{"type":"string"},"topic":{"type":"string"},"email":{"type":"string"},"subject":{"type":"string"},"message":{"type":"string"},"status":{"type":"string"},"priority":{"type":"string"},"attachments":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Public URL of the file"},"key":{"type":"string","description":"Storage key for deletion"},"filename":{"type":"string","description":"Original filename"},"mimetype":{"type":"string","description":"File MIME type"},"size":{"type":"number","description":"File size in bytes"},"uploadedAt":{"type":"string","format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"get":{"summary":"List tickets","tags":["Tickets"],"description":"Get paginated list of tickets for an app","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["open","pending","in_progress","resolved","closed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["general","technical","billing","feature"]},"in":"query","name":"topic","required":false,"description":"Filter by topic"},{"schema":{"type":"string","enum":["low","normal","high","urgent"]},"in":"query","name":"priority","required":false,"description":"Filter by priority"},{"schema":{"type":"string"},"in":"query","name":"shopId","required":false,"description":"Filter by shop ID"},{"schema":{"type":"string"},"in":"query","name":"email","required":false,"description":"Filter by email"},{"schema":{"type":"string","format":"date"},"in":"query","name":"startDate","required":false,"description":"Start date filter"},{"schema":{"type":"string","format":"date"},"in":"query","name":"endDate","required":false,"description":"End date filter"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search in subject, message, and email"},{"schema":{"type":"string","default":"createdAt"},"in":"query","name":"sortBy","required":false},{"schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"in":"query","name":"sortOrder","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Bulk delete tickets","tags":["Tickets"],"description":"Delete multiple tickets by IDs","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"string"},"description":"Array of ticket IDs to delete"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"},"deletedCount":{"type":"integer"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/tickets/{messageId}":{"get":{"summary":"Get ticket by ID","tags":["Tickets"],"description":"Get a single ticket by its ID","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update ticket","tags":["Tickets"],"description":"Update ticket fields (status, priority, etc.)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["open","pending","in_progress","resolved","closed"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]},"topic":{"type":"string","enum":["general","technical","billing","feature"]}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete ticket","tags":["Tickets"],"description":"Delete a ticket by ID","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/tickets/{messageId}/status":{"patch":{"summary":"Update ticket status","tags":["Tickets"],"description":"Update only the status of a ticket","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["open","pending","in_progress","resolved","closed"]}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/tickets/{messageId}/messages":{"post":{"summary":"Add message to ticket","tags":["Tickets"],"description":"Add a reply/message to an existing ticket","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"Message content"},"isCustomer":{"type":"boolean","default":false,"description":"True if message is from customer"},"authorEmail":{"type":"string","description":"Author email"},"authorName":{"type":"string","description":"Author name"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":true},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"get":{"summary":"Get ticket messages","tags":["Tickets"],"description":"Get all messages/replies for a ticket","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"messageId","required":true,"description":"Ticket ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"content":{"type":"string"},"isCustomer":{"type":"boolean"},"authorEmail":{"type":"string"},"authorName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/stats":{"get":{"summary":"Plan statistics","tags":["Plans"],"description":"Get aggregated plan statistics for an app","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"},"inactive":{"type":"integer"},"byInterval":{"type":"object"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/active":{"get":{"summary":"List active plans","tags":["Plans"],"description":"Get all active plans sorted by price (ascending)","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/features":{"get":{"summary":"List all features","tags":["Plans"],"description":"Get all unique features used across all plans","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/":{"get":{"summary":"List plans","tags":["Plans"],"description":"Get paginated list of plans with filters","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"boolean"},"in":"query","name":"isActive","required":false,"description":"Filter by active status"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search by id or name"},{"schema":{"type":"string","default":"price"},"in":"query","name":"sortBy","required":false,"description":"Field to sort by"},{"schema":{"type":"string","enum":["asc","desc"],"default":"asc"},"in":"query","name":"sortOrder","required":false},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Create plan","tags":["Plans"],"description":"Create a new subscription plan","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","name","price","interval"],"properties":{"id":{"type":"string","description":"Unique plan identifier (e.g., pro_monthly)"},"name":{"type":"string","description":"Display name"},"price":{"type":"number","minimum":0,"description":"Price in USD"},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"description":"Billing interval"},"trialDays":{"type":"integer","minimum":0,"default":0,"description":"Trial period in days"},"features":{"type":"array","items":{"type":"string"},"description":"List of feature identifiers"},"isActive":{"type":"boolean","default":true}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/{planId}":{"get":{"summary":"Get plan by ID","tags":["Plans"],"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"planId","required":true,"description":"Plan MongoDB _id"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update plan","tags":["Plans"],"description":"Update an existing plan (cannot change plan id)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Display name"},"price":{"type":"number","minimum":0,"description":"Price in USD"},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"description":"Billing interval"},"trialDays":{"type":"integer","minimum":0,"description":"Trial period in days"},"features":{"type":"array","items":{"type":"string"},"description":"List of feature identifiers"},"isActive":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"planId","required":true,"description":"Plan MongoDB _id"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete plan","tags":["Plans"],"description":"Permanently delete a plan","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"planId","required":true,"description":"Plan MongoDB _id"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/plans/{planId}/toggle":{"patch":{"summary":"Toggle plan status","tags":["Plans"],"description":"Toggle plan active/inactive status","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"planId","required":true,"description":"Plan MongoDB _id"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string","example":"6901449da196a70c326622f8"},"id":{"type":"string","example":"pro_monthly"},"name":{"type":"string","example":"Pro"},"price":{"type":"number","example":40},"interval":{"type":"string","enum":["EVERY_30_DAYS","ANNUAL"],"example":"EVERY_30_DAYS"},"trialDays":{"type":"integer","example":14},"features":{"type":"array","items":{"type":"string"},"example":["unlimited_banners","priority_support"]},"isActive":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"message":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/wants/stats":{"get":{"summary":"Feature request statistics","tags":["Wants"],"description":"Get aggregated want statistics for an app","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"byStatus":{"type":"object","additionalProperties":{"type":"integer"}},"byCategory":{"type":"object","additionalProperties":{"type":"integer"}},"byPriority":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/wants/":{"get":{"summary":"List wants (admin)","tags":["Wants"],"description":"Get paginated list of wants with full admin data","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","enum":["feature","improvement","integration"]},"in":"query","name":"category","required":false,"description":"Filter by category"},{"schema":{"type":"string","enum":["newest","oldest","most_voted"],"default":"newest"},"in":"query","name":"sort","required":false,"description":"Sort order"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"priority":{"type":"string","enum":["low","normal","high"]},"voteCount":{"type":"integer"},"authorEmail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/wants/{id}":{"get":{"summary":"Get want by ID (admin)","tags":["Wants"],"description":"Get a single want with full admin data","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"priority":{"type":"string","enum":["low","normal","high"]},"voteCount":{"type":"integer"},"authorEmail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update want","tags":["Wants"],"description":"Update want fields (title, description, category)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Feature request title"},"description":{"type":"string","description":"Detailed description"},"category":{"type":"string","enum":["feature","improvement","integration"],"description":"Category"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"priority":{"type":"string","enum":["low","normal","high"]},"voteCount":{"type":"integer"},"authorEmail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete want","tags":["Wants"],"description":"Permanently delete a want","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/wants/{id}/status":{"patch":{"summary":"Update want status","tags":["Wants"],"description":"Update only the status of a want","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"priority":{"type":"string","enum":["low","normal","high"]},"voteCount":{"type":"integer"},"authorEmail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/wants/{id}/priority":{"patch":{"summary":"Update want priority","tags":["Wants"],"description":"Update only the priority of a want","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["priority"],"properties":{"priority":{"type":"string","enum":["low","normal","high"]}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Feature request ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["feature","improvement","integration"]},"status":{"type":"string","enum":["under_review","planned","in_progress","completed"]},"priority":{"type":"string","enum":["low","normal","high"]},"voteCount":{"type":"integer"},"authorEmail":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/newsletter/subscribe":{"post":{"summary":"Subscribe to newsletter","tags":["Newsletter"],"description":"Subscribe an email to the newsletter for an app. Requires API Key. Rate limited to 10 per hour.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Subscriber email"},"name":{"type":"string","description":"Subscriber name (optional)"},"language":{"type":"string","description":"Browser language code (e.g. en, es, fr)","example":"en"},"referralUrl":{"type":"string","description":"URL where the user subscribed from","example":"https://bannersallover.com"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"apiKeyAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/{appId}/newsletter/unsubscribe/{token}":{"get":{"summary":"Unsubscribe from newsletter","tags":["Newsletter"],"description":"One-click unsubscribe via token. Requires API Key. Returns an HTML confirmation page.","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"token","required":true,"description":"Unsubscribe token"}],"security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}},"post":{"summary":"Unsubscribe from newsletter (POST)","tags":["Newsletter"],"description":"Unsubscribe via POST request for programmatic use. Requires API Key.","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"token","required":true,"description":"Unsubscribe token"}],"security":[{"apiKeyAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/admin/{appId}/newsletter/subscribers/stats":{"get":{"summary":"Subscriber statistics","tags":["Newsletter"],"description":"Get aggregated subscriber statistics for an app","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"total":{"type":"integer"},"active":{"type":"integer"},"unsubscribed":{"type":"integer"},"bounced":{"type":"integer"},"bySource":{"type":"object","additionalProperties":{"type":"integer"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/subscribers":{"get":{"summary":"List subscribers","tags":["Newsletter"],"description":"Get paginated list of newsletter subscribers","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["active","unsubscribed","bounced"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Search by email or name"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"language":{"type":"string","description":"Subscriber language code"},"referralUrl":{"type":"string","description":"URL where the user subscribed from"},"status":{"type":"string","enum":["active","unsubscribed","bounced"]},"source":{"type":"string","enum":["form","import","manual"]},"subscribedAt":{"type":"string","format":"date-time"},"unsubscribedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Add subscriber manually","tags":["Newsletter"],"description":"Manually add a subscriber to the newsletter","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"language":{"type":"string","description":"Subscriber language code"},"referralUrl":{"type":"string","description":"URL where the user subscribed from"},"status":{"type":"string","enum":["active","unsubscribed","bounced"]},"source":{"type":"string","enum":["form","import","manual"]},"subscribedAt":{"type":"string","format":"date-time"},"unsubscribedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/subscribers/import":{"post":{"summary":"Import subscribers","tags":["Newsletter"],"description":"Bulk import subscribers from a JSON array","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["subscribers"],"properties":{"subscribers":{"type":"array","items":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"}}}}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"imported":{"type":"integer"},"skipped":{"type":"integer"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/subscribers/{id}":{"delete":{"summary":"Delete subscriber","tags":["Newsletter"],"description":"Permanently remove a subscriber","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Subscriber ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/campaigns":{"get":{"summary":"List campaigns","tags":["Newsletter"],"description":"Get paginated list of newsletter campaigns","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false,"description":"Items per page"},{"schema":{"type":"string","enum":["draft","scheduled","sending","sent","failed","cancelled"]},"in":"query","name":"status","required":false,"description":"Filter by status"},{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","sending","sent","failed","cancelled"]},"stats":{"type":"object","properties":{"total":{"type":"integer"},"sent":{"type":"integer"},"failed":{"type":"integer"}}},"sentAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Create campaign","tags":["Newsletter"],"description":"Create a new newsletter campaign (draft)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","subject","htmlContent"],"properties":{"name":{"type":"string","description":"Campaign name"},"subject":{"type":"string","description":"Email subject line"},"htmlContent":{"type":"string","description":"HTML email content. Use {{unsubscribeUrl}} for unsubscribe link"},"textContent":{"type":"string","description":"Plain text fallback"},"templateId":{"type":"string","description":"Optional template ID to base on"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"}],"security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","sending","sent","failed","cancelled"]},"stats":{"type":"object","properties":{"total":{"type":"integer"},"sent":{"type":"integer"},"failed":{"type":"integer"}}},"sentAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/campaigns/{id}":{"get":{"summary":"Get campaign","tags":["Newsletter"],"description":"Get campaign details including content and stats","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","sending","sent","failed","cancelled"]},"stats":{"type":"object","properties":{"total":{"type":"integer"},"sent":{"type":"integer"},"failed":{"type":"integer"}}},"sentAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"patch":{"summary":"Update campaign","tags":["Newsletter"],"description":"Update campaign fields (only draft campaigns can be updated)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"subject":{"type":"string"},"htmlContent":{"type":"string"},"textContent":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"appId":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","sending","sent","failed","cancelled"]},"stats":{"type":"object","properties":{"total":{"type":"integer"},"sent":{"type":"integer"},"failed":{"type":"integer"}}},"sentAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete campaign","tags":["Newsletter"],"description":"Delete a campaign (only draft campaigns can be deleted)","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/campaigns/{id}/send":{"post":{"summary":"Send campaign","tags":["Newsletter"],"description":"Send the campaign to all active subscribers. Uses batch sending via Resend.","parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"status":{"type":"string","example":"queued"},"jobId":{"type":"string","description":"Batch plan job ID"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/campaigns/{id}/test":{"post":{"summary":"Send test email","tags":["Newsletter"],"description":"Send a test email to a single address to preview the campaign","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Test recipient email"}}}}}},"parameters":[{"schema":{"type":"string","example":"banners-all-over"},"in":"path","name":"appId","required":true,"description":"Application ID (e.g.: banners-all-over)"},{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Campaign ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/templates":{"get":{"summary":"List newsletter templates","tags":["Newsletter"],"description":"Get all newsletter templates","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"in":"path","name":"appId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"htmlContent":{"type":"string"},"textContent":{"type":"string"},"isActive":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"post":{"summary":"Create newsletter template","tags":["Newsletter"],"description":"Create a reusable newsletter template","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","subject","htmlContent"],"properties":{"name":{"type":"string","description":"Template name (unique)"},"subject":{"type":"string","description":"Default subject line"},"htmlContent":{"type":"string","description":"HTML content with {{variable}} placeholders"},"textContent":{"type":"string","description":"Plain text fallback"}}}}}},"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"in":"path","name":"appId","required":true}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"htmlContent":{"type":"string"},"textContent":{"type":"string"},"isActive":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}},"/admin/{appId}/newsletter/templates/{id}":{"patch":{"summary":"Update newsletter template","tags":["Newsletter"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"subject":{"type":"string"},"htmlContent":{"type":"string"},"textContent":{"type":"string"},"isActive":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Template ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"htmlContent":{"type":"string"},"textContent":{"type":"string"},"isActive":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}},"delete":{"summary":"Delete newsletter template","tags":["Newsletter"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"Template ID"}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}}}}},"servers":[{"url":"https://api.alloverapps.com","description":"Production server"}],"tags":[{"name":"Auth","description":"Back Office authentication"},{"name":"Users","description":"Admin user management"},{"name":"Apps","description":"Application management"},{"name":"API Keys","description":"API key management for backend-to-backend authentication"},{"name":"Shops","description":"Shopify shop management per app"},{"name":"Templates","description":"Email template management"},{"name":"Metrics","description":"Metrics and analytics"},{"name":"Logs","description":"Application logs and debugging"},{"name":"Feedback","description":"User feedback management"},{"name":"Tickets","description":"Support tickets management"},{"name":"Magic Link","description":"Passwordless authentication for end users"},{"name":"Wants","description":"Feature requests with voting system"},{"name":"Newsletter","description":"Newsletter subscribers, campaigns, and templates"},{"name":"Contacts","description":"Shared contact model with per-category consent and GDPR compliance"},{"name":"Webhooks","description":"Email provider webhook receivers (Resend, cold-email)"},{"name":"Email Tracking","description":"Own tracking pixel and click redirect endpoints"},{"name":"Email Events","description":"Email lifecycle event log and analytics"},{"name":"Email Analytics","description":"Per-campaign, per-contact, and global email engagement analytics"},{"name":"Email Jobs","description":"Job queue monitoring and management"},{"name":"Health","description":"Health checks"}]}