Commit f8b76737 authored by ThinhNC's avatar ThinhNC

fix(api,validation): standardize CrawlScheduleController envelope and enforce...

fix(api,validation): standardize CrawlScheduleController envelope and enforce validateParams on all route identifiers
parent 2a7f8a5f
......@@ -83,9 +83,7 @@
"description": "Email hoặc mật khẩu không chính xác"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Đăng nhập người dùng",
"requestBody": {
"required": true,
......@@ -141,9 +139,7 @@
}
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Làm mới Access Token"
}
},
......@@ -182,9 +178,7 @@
}
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Đăng xuất"
}
},
......@@ -215,9 +209,7 @@
"description": "Chưa xác thực hoặc token không hợp lệ"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Lấy thông tin người dùng hiện tại"
},
"put": {
......@@ -249,9 +241,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Cập nhật thông tin cá nhân",
"requestBody": {
"required": true,
......@@ -348,9 +338,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Xem hạn mức và mức độ sử dụng Quota hiện tại"
}
},
......@@ -415,9 +403,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Đổi mật khẩu tài khoản",
"requestBody": {
"required": true,
......@@ -458,9 +444,7 @@
"description": "Email đã được sử dụng hoặc dữ liệu không hợp lệ"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Đăng ký tài khoản mới",
"requestBody": {
"required": true,
......@@ -502,9 +486,7 @@
"description": "Email không hợp lệ"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Yêu cầu đặt lại mật khẩu",
"requestBody": {
"required": true,
......@@ -512,9 +494,7 @@
"application/json": {
"schema": {
"type": "object",
"required": [
"email"
],
"required": ["email"],
"properties": {
"email": {
"type": "string",
......@@ -556,9 +536,7 @@
"description": "Token không hợp lệ, đã hết hạn hoặc mật khẩu không đúng định dạng"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Đặt lại mật khẩu mới",
"requestBody": {
"required": true,
......@@ -566,10 +544,7 @@
"application/json": {
"schema": {
"type": "object",
"required": [
"token",
"password"
],
"required": ["token", "password"],
"properties": {
"token": {
"type": "string",
......@@ -614,9 +589,7 @@
"description": "Địa chỉ email không hợp lệ"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Gửi lại email xác thực",
"requestBody": {
"required": true,
......@@ -658,9 +631,7 @@
"description": "Token không hợp lệ hoặc đã hết hạn"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Xác thực địa chỉ email",
"requestBody": {
"required": true,
......@@ -668,9 +639,7 @@
"application/json": {
"schema": {
"type": "object",
"required": [
"token"
],
"required": ["token"],
"properties": {
"token": {
"type": "string",
......@@ -714,9 +683,7 @@
"description": "Chưa xác thực hoặc mật khẩu không chính xác"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Yêu cầu vô hiệu hóa tài khoản",
"requestBody": {
"required": true,
......@@ -758,9 +725,7 @@
"description": "Mã xác nhận không hợp lệ, đã hết hạn hoặc tài khoản đã bị vô hiệu hóa"
}
},
"tags": [
"Auth"
],
"tags": ["Auth"],
"summary": "Xác nhận vô hiệu hóa tài khoản",
"requestBody": {
"required": true,
......@@ -857,9 +822,7 @@
"description": "Không có quyền truy cập"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Lấy danh sách người dùng"
},
"post": {
......@@ -904,9 +867,7 @@
}
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Tạo người dùng mới"
}
},
......@@ -954,9 +915,7 @@
"description": "Không tìm thấy người dùng"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Lấy thông tin người dùng theo ID"
},
"put": {
......@@ -1009,9 +968,7 @@
}
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Cập nhật thông tin người dùng"
},
"delete": {
......@@ -1052,9 +1009,7 @@
"description": "Không tìm thấy người dùng"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Xóa người dùng"
}
},
......@@ -1083,9 +1038,7 @@
"description": "Không có quyền users.roles.read"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Xem Roles của User"
},
"put": {
......@@ -1118,9 +1071,7 @@
"description": "Không tìm thấy User hoặc Role"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Cập nhật toàn bộ Roles của User",
"requestBody": {
"required": true,
......@@ -1171,9 +1122,7 @@
"description": "Không tìm thấy User hoặc Role"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Gán thêm một Role cho User"
},
"delete": {
......@@ -1215,9 +1164,7 @@
"description": "Không tìm thấy User hoặc Role"
}
},
"tags": [
"Users"
],
"tags": ["Users"],
"summary": "Gỡ một Role khỏi User"
}
},
......@@ -1274,9 +1221,7 @@
"description": "Không có quyền roles.read"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Danh sách Roles"
},
"post": {
......@@ -1298,9 +1243,7 @@
"description": "Role slug đã tồn tại"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Tạo Role tùy chỉnh",
"requestBody": {
"required": true,
......@@ -1342,9 +1285,7 @@
"description": "Không tìm thấy Role"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Chi tiết Role"
},
"patch": {
......@@ -1377,9 +1318,7 @@
"description": "Không tìm thấy Role"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Cập nhật Role",
"requestBody": {
"required": true,
......@@ -1422,9 +1361,7 @@
"description": "Không tìm thấy Role"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Xóa Role"
}
},
......@@ -1456,9 +1393,7 @@
"description": "Không tìm thấy Role"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Xem danh sách Permissions của Role"
},
"put": {
......@@ -1488,9 +1423,7 @@
"description": "Không tìm thấy Role"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Gán danh sách Permissions cho Role",
"requestBody": {
"required": true,
......@@ -1529,9 +1462,7 @@
"description": "Không có quyền roles.read"
}
},
"tags": [
"Roles"
],
"tags": ["Roles"],
"summary": "Danh sách Users thuộc Role"
}
},
......@@ -1565,9 +1496,7 @@
"description": "Không có quyền permissions.read"
}
},
"tags": [
"Permissions"
],
"tags": ["Permissions"],
"summary": "Danh mục Permissions hệ thống"
}
},
......@@ -1599,9 +1528,7 @@
"description": "Không tìm thấy Permission"
}
},
"tags": [
"Permissions"
],
"tags": ["Permissions"],
"summary": "Chi tiết Permission"
}
},
......@@ -1654,9 +1581,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Tạo crawl job mới",
"requestBody": {
"required": true,
......@@ -1745,9 +1670,7 @@
}
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Lấy danh sách các crawl jobs"
}
},
......@@ -1789,9 +1712,7 @@
"description": "Không tìm thấy crawl job hoặc không có quyền truy cập"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Lấy thông tin chi tiết một crawl job"
},
"delete": {
......@@ -1942,9 +1863,7 @@
"description": "Không tìm thấy crawl job"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Hủy một crawl job đang chạy"
}
},
......@@ -2148,10 +2067,7 @@
"in": "query",
"schema": {
"type": "string",
"enum": [
"asc",
"desc"
],
"enum": ["asc", "desc"],
"default": "asc"
},
"description": "Thứ tự sắp xếp"
......@@ -2212,9 +2128,7 @@
}
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Lấy danh sách các trang đã crawl của job"
}
},
......@@ -2418,10 +2332,7 @@
"in": "query",
"schema": {
"type": "string",
"enum": [
"asc",
"desc"
],
"enum": ["asc", "desc"],
"default": "asc"
},
"description": "Thứ tự sắp xếp"
......@@ -2556,9 +2467,7 @@
"description": "Không tìm thấy crawl job hoặc không có quyền truy cập"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Xem preview dữ liệu clean/raw của các trang đã crawl"
}
},
......@@ -2600,9 +2509,7 @@
}
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Lấy danh sách các bản export của job"
},
"post": {
......@@ -2639,9 +2546,7 @@
}
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Yêu cầu xuất dữ liệu cho job",
"requestBody": {
"required": true,
......@@ -2680,9 +2585,7 @@
}
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Tải xuống file export mới nhất"
}
},
......@@ -2723,14 +2626,7 @@
"required": false,
"schema": {
"type": "string",
"enum": [
"IMAGE",
"LINK",
"PDF",
"FILE",
"VIDEO",
"OTHER"
]
"enum": ["IMAGE", "LINK", "PDF", "FILE", "VIDEO", "OTHER"]
},
"description": "Lọc theo loại asset"
}
......@@ -2822,9 +2718,7 @@
"description": "Không tìm thấy crawl job hoặc không có quyền truy cập"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Lấy danh sách assets của job (có phân trang)"
}
},
......@@ -2877,9 +2771,7 @@
"description": "Không tìm thấy crawl job"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Xem báo cáo thay đổi (Diff Report)"
}
},
......@@ -2924,9 +2816,7 @@
"description": "Không tìm thấy crawl job hoặc diff report"
}
},
"tags": [
"Crawl Jobs"
],
"tags": ["Crawl Jobs"],
"summary": "Tải file diff_report.json"
}
},
......@@ -2968,9 +2858,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Tạo lịch crawl định kỳ mới",
"requestBody": {
"required": true,
......@@ -2999,12 +2887,7 @@
"in": "query",
"schema": {
"type": "string",
"enum": [
"DAILY",
"WEEKLY",
"MONTHLY",
"CUSTOM"
]
"enum": ["DAILY", "WEEKLY", "MONTHLY", "CUSTOM"]
},
"description": "Lọc theo tần suất"
},
......@@ -3073,9 +2956,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Lấy danh sách lịch crawl định kỳ"
}
},
......@@ -3111,9 +2992,7 @@
"description": "Không tìm thấy lịch crawl"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Xem chi tiết lịch crawl"
},
"patch": {
......@@ -3158,9 +3037,7 @@
"description": "Không tìm thấy lịch crawl"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Cập nhật lịch crawl",
"requestBody": {
"required": true,
......@@ -3210,9 +3087,7 @@
"description": "Không tìm thấy lịch crawl"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Xóa lịch crawl"
}
},
......@@ -3257,9 +3132,7 @@
"description": "Không tìm thấy lịch crawl"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Kích hoạt chạy ngay lịch crawl"
}
},
......@@ -3336,9 +3209,7 @@
"description": "Không tìm thấy lịch crawl"
}
},
"tags": [
"Crawl Schedules"
],
"tags": ["Crawl Schedules"],
"summary": "Xem lịch sử các lần chạy của lịch crawl"
}
},
......@@ -3380,9 +3251,7 @@
"description": "Không tìm thấy file export"
}
},
"tags": [
"Crawl Exports"
],
"tags": ["Crawl Exports"],
"summary": "Tải xuống tệp export theo ID"
}
},
......@@ -3520,9 +3389,7 @@
"description": "Không có quyền truy cập (không phải ADMIN)"
}
},
"tags": [
"Audit Logs"
],
"tags": ["Audit Logs"],
"summary": "Lấy danh sách nhật ký hệ thống"
}
},
......@@ -3556,9 +3423,7 @@
"description": "Dữ liệu không hợp lệ hoặc thời điểm hết hạn không ở trong tương lai"
}
},
"tags": [
"API Keys"
],
"tags": ["API Keys"],
"security": [
{
"BearerAuth": []
......@@ -3605,9 +3470,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"API Keys"
],
"tags": ["API Keys"],
"security": [
{
"BearerAuth": []
......@@ -3661,9 +3524,7 @@
"description": "Trạng thái không hợp lệ"
}
},
"tags": [
"API Keys"
],
"tags": ["API Keys"],
"security": [
{
"BearerAuth": []
......@@ -3722,9 +3583,7 @@
"description": "Không tìm thấy API Key"
}
},
"tags": [
"API Keys"
],
"tags": ["API Keys"],
"security": [
{
"BearerAuth": []
......@@ -3763,9 +3622,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Webhooks"
],
"tags": ["Webhooks"],
"summary": "Tạo cấu hình Webhook",
"requestBody": {
"required": true,
......@@ -3807,9 +3664,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Webhooks"
],
"tags": ["Webhooks"],
"summary": "Xem danh sách Webhook configs"
}
},
......@@ -3872,9 +3727,7 @@
"description": "Không tìm thấy cấu hình Webhook"
}
},
"tags": [
"Webhooks"
],
"tags": ["Webhooks"],
"summary": "Xóa cấu hình Webhook"
}
},
......@@ -3946,9 +3799,7 @@
"description": "Chưa xác thực"
}
},
"tags": [
"Webhooks"
],
"tags": ["Webhooks"],
"summary": "Xem lịch sử gửi Webhook"
}
},
......@@ -4079,11 +3930,7 @@
},
"role": {
"type": "string",
"enum": [
"ADMIN",
"CRAWLER_USER",
"VIEWER"
]
"enum": ["ADMIN", "CRAWLER_USER", "VIEWER"]
},
"isActive": {
"type": "boolean"
......@@ -4112,12 +3959,7 @@
},
"mode": {
"type": "string",
"enum": [
"SCRAPE",
"CRAWL",
"SITEMAP",
"URL_LIST"
]
"enum": ["SCRAPE", "CRAWL", "SITEMAP", "URL_LIST"]
},
"status": {
"type": "string",
......@@ -4328,10 +4170,7 @@
},
"type": {
"type": "string",
"enum": [
"internal",
"external"
]
"enum": ["internal", "external"]
}
}
}
......@@ -4417,21 +4256,11 @@
},
"exportType": {
"type": "string",
"enum": [
"JSON",
"CSV",
"XLSX",
"MARKDOWN",
"ZIP"
]
"enum": ["JSON", "CSV", "XLSX", "MARKDOWN", "ZIP"]
},
"status": {
"type": "string",
"enum": [
"PENDING",
"COMPLETED",
"FAILED"
]
"enum": ["PENDING", "COMPLETED", "FAILED"]
},
"fileName": {
"type": "string"
......@@ -4454,10 +4283,7 @@
},
"LoginRequest": {
"type": "object",
"required": [
"email",
"password"
],
"required": ["email", "password"],
"properties": {
"email": {
"type": "string",
......@@ -4472,10 +4298,7 @@
},
"RegisterRequest": {
"type": "object",
"required": [
"email",
"password"
],
"required": ["email", "password"],
"properties": {
"email": {
"type": "string",
......@@ -4494,9 +4317,7 @@
},
"ResendVerificationRequest": {
"type": "object",
"required": [
"email"
],
"required": ["email"],
"properties": {
"email": {
"type": "string",
......@@ -4507,9 +4328,7 @@
},
"RequestDeactivationRequest": {
"type": "object",
"required": [
"password"
],
"required": ["password"],
"properties": {
"password": {
"type": "string",
......@@ -4520,9 +4339,7 @@
},
"ConfirmDeactivationRequest": {
"type": "object",
"required": [
"token"
],
"required": ["token"],
"properties": {
"token": {
"type": "string",
......@@ -4533,9 +4350,7 @@
},
"RefreshRequest": {
"type": "object",
"required": [
"refreshToken"
],
"required": ["refreshToken"],
"properties": {
"refreshToken": {
"type": "string",
......@@ -4545,9 +4360,7 @@
},
"LogoutRequest": {
"type": "object",
"required": [
"refreshToken"
],
"required": ["refreshToken"],
"properties": {
"refreshToken": {
"type": "string",
......@@ -4566,11 +4379,7 @@
},
"ChangePasswordRequest": {
"type": "object",
"required": [
"currentPassword",
"newPassword",
"confirmPassword"
],
"required": ["currentPassword", "newPassword", "confirmPassword"],
"properties": {
"currentPassword": {
"type": "string",
......@@ -4588,10 +4397,7 @@
},
"CreateUserRequest": {
"type": "object",
"required": [
"email",
"password"
],
"required": ["email", "password"],
"properties": {
"email": {
"type": "string",
......@@ -4608,11 +4414,7 @@
},
"role": {
"type": "string",
"enum": [
"ADMIN",
"CRAWLER_USER",
"VIEWER"
],
"enum": ["ADMIN", "CRAWLER_USER", "VIEWER"],
"example": "CRAWLER_USER"
},
"maxPagesLimit": {
......@@ -4638,11 +4440,7 @@
},
"role": {
"type": "string",
"enum": [
"ADMIN",
"CRAWLER_USER",
"VIEWER"
],
"enum": ["ADMIN", "CRAWLER_USER", "VIEWER"],
"example": "VIEWER"
},
"isActive": {
......@@ -4673,12 +4471,7 @@
},
"mode": {
"type": "string",
"enum": [
"SCRAPE",
"CRAWL",
"SITEMAP",
"URL_LIST"
],
"enum": ["SCRAPE", "CRAWL", "SITEMAP", "URL_LIST"],
"example": "CRAWL"
},
"maxPages": {
......@@ -4699,38 +4492,25 @@
"type": "string",
"format": "uri"
},
"example": [
"https://example.com/1",
"https://example.com/2"
],
"example": ["https://example.com/1", "https://example.com/2"],
"description": "Bắt buộc khi mode là URL_LIST"
}
}
},
"CreateExportRequest": {
"type": "object",
"required": [
"exportType"
],
"required": ["exportType"],
"properties": {
"exportType": {
"type": "string",
"enum": [
"JSON",
"CSV",
"XLSX",
"MARKDOWN",
"ZIP"
],
"enum": ["JSON", "CSV", "XLSX", "MARKDOWN", "ZIP"],
"example": "JSON"
}
}
},
"CreateApiKeyRequest": {
"type": "object",
"required": [
"name"
],
"required": ["name"],
"properties": {
"name": {
"type": "string",
......@@ -4749,9 +4529,7 @@
},
"UpdateApiKeyStatusRequest": {
"type": "object",
"required": [
"isActive"
],
"required": ["isActive"],
"additionalProperties": false,
"properties": {
"isActive": {
......@@ -4848,11 +4626,7 @@
},
"CreateWebhookConfigRequest": {
"type": "object",
"required": [
"url",
"secret",
"events"
],
"required": ["url", "secret", "events"],
"properties": {
"url": {
"type": "string",
......@@ -4867,15 +4641,9 @@
"type": "array",
"items": {
"type": "string",
"enum": [
"job.completed",
"job.failed"
]
"enum": ["job.completed", "job.failed"]
},
"example": [
"job.completed",
"job.failed"
]
"example": ["job.completed", "job.failed"]
}
}
},
......@@ -4936,11 +4704,7 @@
},
"status": {
"type": "string",
"enum": [
"PENDING",
"SUCCESS",
"FAILED"
]
"enum": ["PENDING", "SUCCESS", "FAILED"]
},
"statusCode": {
"type": "integer",
......@@ -5004,21 +4768,11 @@
},
"mode": {
"type": "string",
"enum": [
"SCRAPE",
"CRAWL",
"SITEMAP",
"URL_LIST"
]
"enum": ["SCRAPE", "CRAWL", "SITEMAP", "URL_LIST"]
},
"frequency": {
"type": "string",
"enum": [
"DAILY",
"WEEKLY",
"MONTHLY",
"CUSTOM"
]
"enum": ["DAILY", "WEEKLY", "MONTHLY", "CUSTOM"]
},
"cronExpression": {
"type": "string",
......@@ -5081,10 +4835,7 @@
},
"CreateCrawlScheduleRequest": {
"type": "object",
"required": [
"name",
"startUrl"
],
"required": ["name", "startUrl"],
"properties": {
"name": {
"type": "string",
......@@ -5097,22 +4848,12 @@
},
"mode": {
"type": "string",
"enum": [
"SCRAPE",
"CRAWL",
"SITEMAP",
"URL_LIST"
],
"enum": ["SCRAPE", "CRAWL", "SITEMAP", "URL_LIST"],
"example": "CRAWL"
},
"frequency": {
"type": "string",
"enum": [
"DAILY",
"WEEKLY",
"MONTHLY",
"CUSTOM"
],
"enum": ["DAILY", "WEEKLY", "MONTHLY", "CUSTOM"],
"example": "DAILY"
},
"cronExpression": {
......@@ -5175,21 +4916,11 @@
},
"mode": {
"type": "string",
"enum": [
"SCRAPE",
"CRAWL",
"SITEMAP",
"URL_LIST"
]
"enum": ["SCRAPE", "CRAWL", "SITEMAP", "URL_LIST"]
},
"frequency": {
"type": "string",
"enum": [
"DAILY",
"WEEKLY",
"MONTHLY",
"CUSTOM"
]
"enum": ["DAILY", "WEEKLY", "MONTHLY", "CUSTOM"]
},
"cronExpression": {
"type": "string"
......@@ -5389,10 +5120,7 @@
},
"CreateRoleRequest": {
"type": "object",
"required": [
"name",
"slug"
],
"required": ["name", "slug"],
"properties": {
"name": {
"type": "string",
......@@ -5431,9 +5159,7 @@
},
"AssignRolePermissionsRequest": {
"type": "object",
"required": [
"permissionIds"
],
"required": ["permissionIds"],
"properties": {
"permissionIds": {
"type": "array",
......@@ -5446,9 +5172,7 @@
},
"AssignUserRolesRequest": {
"type": "object",
"required": [
"roleIds"
],
"required": ["roleIds"],
"properties": {
"roleIds": {
"type": "array",
......
......@@ -3,10 +3,14 @@ import { ApiKeyController } from "./api-key.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate } from "../../middlewares/validate.middleware";
import {
validate,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createApiKeySchema,
updateApiKeyStatusSchema,
apiKeyParamsSchema,
} from "./api-key.validation";
const router = Router();
......@@ -29,6 +33,7 @@ router.patch(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.API_KEYS_UPDATE),
validateParams(apiKeyParamsSchema),
validate(updateApiKeyStatusSchema),
controller.setActive,
);
......@@ -36,6 +41,7 @@ router.delete(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.API_KEYS_DELETE),
validateParams(apiKeyParamsSchema),
controller.revoke,
);
......
......@@ -24,3 +24,7 @@ export const updateApiKeyStatusSchema = z.object({
invalid_type_error: "API Key status must be a boolean",
}),
});
export const apiKeyParamsSchema = z.object({
id: z.string().uuid("Invalid API key ID format"),
});
import { Router } from "express";
import { CrawlJobController } from "./crawl-job.controller";
import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware";
import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createCrawlJobSchema,
createExportSchema,
......@@ -9,6 +13,7 @@ import {
getAssetsQuerySchema,
jobLogsQuerySchema,
diffQuerySchema,
crawlJobParamsSchema,
} from "./crawl-job.validation";
import { crawlPageQuerySchema } from "../crawl-pages/crawl-page.validation";
import { requirePermission } from "../../middlewares/permission.middleware";
......@@ -37,24 +42,28 @@ router.get(
"/:id",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
controller.findById,
);
router.delete(
"/:id",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_DELETE),
validateParams(crawlJobParamsSchema),
controller.delete,
);
router.post(
"/:id/rerun",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_RETRY),
validateParams(crawlJobParamsSchema),
controller.rerun,
);
router.get(
"/:id/logs",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(jobLogsQuerySchema),
controller.getLogs,
);
......@@ -62,18 +71,21 @@ router.get(
"/:id/events",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
controller.streamEvents,
);
router.post(
"/:id/cancel",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_CANCEL),
validateParams(crawlJobParamsSchema),
controller.cancel,
);
router.get(
"/:id/pages",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(crawlPageQuerySchema),
controller.getPages,
);
......@@ -81,6 +93,7 @@ router.get(
"/:id/pages/preview",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(crawlPageQuerySchema),
controller.getPagesPreview,
);
......@@ -88,12 +101,14 @@ router.get(
"/:id/exports",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_READ),
validateParams(crawlJobParamsSchema),
controller.getExports,
);
router.post(
"/:id/exports",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_CREATE),
validateParams(crawlJobParamsSchema),
validate(createExportSchema),
(req, res, next) => {
controller.createExport(req, res, next);
......@@ -103,12 +118,14 @@ router.get(
"/:id/download",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_DOWNLOAD),
validateParams(crawlJobParamsSchema),
controller.download,
);
router.get(
"/:id/assets",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(getAssetsQuerySchema),
controller.getAssets,
);
......@@ -116,6 +133,7 @@ router.get(
"/:id/diff",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(diffQuerySchema),
controller.getDiff,
);
......@@ -123,6 +141,7 @@ router.get(
"/:id/diff/download",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(diffQuerySchema),
controller.downloadDiff,
);
......
......@@ -86,3 +86,7 @@ export const diffQuerySchema = z.object({
.uuid("Invalid compareWithJobId format")
.optional(),
});
export const crawlJobParamsSchema = z.object({
id: z.string().uuid("Invalid job ID format"),
});
......@@ -13,6 +13,7 @@ export class CrawlScheduleController {
req.body,
);
res.status(201).json({
success: true,
message: "Crawl schedule created successfully",
data: schedule,
});
......@@ -28,7 +29,10 @@ export class CrawlScheduleController {
req.user!.role,
req.query as unknown as CrawlScheduleQueryDto,
);
res.json(result);
res.json({
success: true,
data: result,
});
} catch (error) {
next(error);
}
......@@ -41,7 +45,10 @@ export class CrawlScheduleController {
req.user!.role,
req.params.id,
);
res.json(schedule);
res.json({
success: true,
data: schedule,
});
} catch (error) {
next(error);
}
......@@ -56,6 +63,7 @@ export class CrawlScheduleController {
req.body,
);
res.json({
success: true,
message: "Crawl schedule updated successfully",
data: updated,
});
......@@ -68,6 +76,7 @@ export class CrawlScheduleController {
try {
await this.service.delete(req.user!.id, req.user!.role, req.params.id);
res.json({
success: true,
message: "Crawl schedule deleted successfully",
});
} catch (error) {
......@@ -83,6 +92,7 @@ export class CrawlScheduleController {
req.params.id,
);
res.status(201).json({
success: true,
message: "Scheduled crawl triggered successfully",
data: job,
});
......@@ -104,7 +114,10 @@ export class CrawlScheduleController {
page,
limit,
);
res.json(history);
res.json({
success: true,
data: history,
});
} catch (error) {
next(error);
}
......
import { Router } from "express";
import { CrawlScheduleController } from "./crawl-schedule.controller";
import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware";
import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createCrawlScheduleSchema,
updateCrawlScheduleSchema,
crawlScheduleQuerySchema,
crawlScheduleHistoryQuerySchema,
crawlScheduleParamsSchema,
} from "./crawl-schedule.validation";
import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant";
......@@ -34,6 +39,7 @@ router.get(
"/:id",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ),
validateParams(crawlScheduleParamsSchema),
controller.findById,
);
......@@ -41,6 +47,7 @@ router.patch(
"/:id",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_UPDATE),
validateParams(crawlScheduleParamsSchema),
validate(updateCrawlScheduleSchema),
controller.update,
);
......@@ -49,6 +56,7 @@ router.delete(
"/:id",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_DELETE),
validateParams(crawlScheduleParamsSchema),
controller.delete,
);
......@@ -56,6 +64,7 @@ router.post(
"/:id/run",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_RUN),
validateParams(crawlScheduleParamsSchema),
controller.triggerRun,
);
......@@ -63,6 +72,7 @@ router.get(
"/:id/history",
apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ),
validateParams(crawlScheduleParamsSchema),
validateQuery(crawlScheduleHistoryQuerySchema),
controller.getHistory,
);
......
......@@ -111,3 +111,7 @@ export const crawlScheduleHistoryQuerySchema = z.object({
page: z.coerce.number().int().min(1).default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
});
export const crawlScheduleParamsSchema = z.object({
id: z.string().uuid("Invalid schedule ID format"),
});
......@@ -3,10 +3,14 @@ import { ExtractionTemplateController } from "./extraction-template.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate } from "../../middlewares/validate.middleware";
import {
validate,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createExtractionTemplateSchema,
updateExtractionTemplateSchema,
extractionTemplateParamsSchema,
} from "./extraction-template.validation";
const router = Router();
......@@ -28,17 +32,20 @@ router.get(
router.get(
"/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_READ),
validateParams(extractionTemplateParamsSchema),
controller.findById,
);
router.patch(
"/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_UPDATE),
validateParams(extractionTemplateParamsSchema),
validate(updateExtractionTemplateSchema),
controller.update,
);
router.delete(
"/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_DELETE),
validateParams(extractionTemplateParamsSchema),
controller.delete,
);
......
......@@ -27,3 +27,7 @@ export const updateExtractionTemplateSchema = z.object({
name: z.string().min(1).optional(),
fields: z.array(extractionFieldSchema).min(1).optional(),
});
export const extractionTemplateParamsSchema = z.object({
id: z.string().uuid("Invalid template ID format"),
});
......@@ -3,6 +3,8 @@ import { PermissionController } from "./permission.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validateParams } from "../../middlewares/validate.middleware";
import { permissionParamsSchema } from "./permission.validation";
const router = Router();
const controller = new PermissionController();
......@@ -18,6 +20,7 @@ router.get(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.PERMISSIONS_READ),
validateParams(permissionParamsSchema),
controller.findById,
);
......
import { z } from "zod";
export const permissionParamsSchema = z.object({
id: z.string().uuid("Invalid permission ID format"),
});
......@@ -2,12 +2,17 @@ import { Router } from "express";
import { RoleController } from "./role.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware";
import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createRoleSchema,
updateRoleSchema,
assignRolePermissionsSchema,
listRolesQuerySchema,
roleParamsSchema,
} from "./role.validation";
import { PERMISSIONS } from "../../common/constants/permission.constant";
......@@ -26,6 +31,7 @@ router.get(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_READ),
validateParams(roleParamsSchema),
controller.findById,
);
......@@ -41,6 +47,7 @@ router.patch(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_UPDATE),
validateParams(roleParamsSchema),
validate(updateRoleSchema),
controller.update,
);
......@@ -49,6 +56,7 @@ router.delete(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_DELETE),
validateParams(roleParamsSchema),
controller.delete,
);
......@@ -56,6 +64,7 @@ router.get(
"/:id/permissions",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_PERMISSIONS_READ),
validateParams(roleParamsSchema),
controller.getRolePermissions,
);
......@@ -63,6 +72,7 @@ router.put(
"/:id/permissions",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_PERMISSIONS_ASSIGN),
validateParams(roleParamsSchema),
validate(assignRolePermissionsSchema),
controller.setRolePermissions,
);
......@@ -71,6 +81,7 @@ router.get(
"/:id/users",
authMiddleware,
requirePermission(PERMISSIONS.ROLES_READ),
validateParams(roleParamsSchema),
controller.getRoleUsers,
);
......
......@@ -67,3 +67,12 @@ export const listRolesQuerySchema = z.object({
)
.optional(),
});
export const roleParamsSchema = z.object({
id: z.string().uuid("Invalid role ID format"),
});
export const rolePermissionParamsSchema = z.object({
id: z.string().uuid("Invalid role ID format"),
permissionId: z.string().uuid("Invalid permission ID format"),
});
......@@ -2,12 +2,18 @@ import { Router } from "express";
import { UserController } from "./user.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware";
import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createUserSchema,
updateUserSchema,
listUsersQuerySchema,
assignUserRolesSchema,
userParamsSchema,
userRoleAssignmentParamsSchema,
} from "./user.validation";
import { PERMISSIONS } from "../../common/constants/permission.constant";
......@@ -26,6 +32,7 @@ router.get(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.USERS_READ),
validateParams(userParamsSchema),
controller.findById,
);
......@@ -44,6 +51,7 @@ router.put(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.USERS_UPDATE),
validateParams(userParamsSchema),
validate(updateUserSchema),
(req, res, next) => {
// #swagger.requestBody = { schema: { $ref: '#/components/schemas/UpdateUserRequest' } }
......@@ -55,6 +63,7 @@ router.delete(
"/:id",
authMiddleware,
requirePermission(PERMISSIONS.USERS_DELETE),
validateParams(userParamsSchema),
controller.delete,
);
......@@ -63,6 +72,7 @@ router.get(
"/:id/roles",
authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_READ),
validateParams(userParamsSchema),
controller.getUserRoles,
);
......@@ -70,6 +80,7 @@ router.put(
"/:id/roles",
authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userParamsSchema),
validate(assignUserRolesSchema),
controller.assignRoles,
);
......@@ -78,6 +89,7 @@ router.post(
"/:id/roles/:roleId",
authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userRoleAssignmentParamsSchema),
controller.assignRole,
);
......@@ -85,6 +97,7 @@ router.delete(
"/:id/roles/:roleId",
authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userRoleAssignmentParamsSchema),
controller.revokeRole,
);
......
......@@ -47,3 +47,12 @@ export const assignUserRolesSchema = z.object({
required_error: "roleIds array is required",
}),
});
export const userParamsSchema = z.object({
id: z.string().uuid("Invalid user ID format"),
});
export const userRoleAssignmentParamsSchema = z.object({
id: z.string().uuid("Invalid user ID format"),
roleId: z.string().uuid("Invalid role ID format"),
});
......@@ -3,11 +3,16 @@ import { WebhookController } from "./webhook.controller";
import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate, validateQuery } from "../../middlewares/validate.middleware";
import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import {
createWebhookConfigSchema,
updateWebhookConfigSchema,
listWebhookDeliveriesQuerySchema,
webhookParamsSchema,
} from "./webhook.validation";
const router = Router();
......@@ -30,6 +35,7 @@ router.patch(
"/configs/:id",
authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_UPDATE),
validateParams(webhookParamsSchema),
validate(updateWebhookConfigSchema),
controller.updateConfig,
);
......@@ -37,12 +43,14 @@ router.delete(
"/configs/:id",
authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_DELETE),
validateParams(webhookParamsSchema),
controller.deleteConfig,
);
router.post(
"/configs/:id/test",
authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_TEST),
validateParams(webhookParamsSchema),
controller.testConfig,
);
router.get(
......@@ -56,6 +64,7 @@ router.post(
"/deliveries/:id/redeliver",
authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_UPDATE),
validateParams(webhookParamsSchema),
controller.redeliver,
);
......
......@@ -41,3 +41,7 @@ export const listWebhookDeliveriesQuerySchema = z.object({
page: z.coerce.number().int().min(1).default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
});
export const webhookParamsSchema = z.object({
id: z.string().uuid("Invalid webhook ID format"),
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment