Commit 8bc9c30b authored by ThinhNC's avatar ThinhNC

docs(swagger): add complete openapi 3.0 path specs and component schemas for...

docs(swagger): add complete openapi 3.0 path specs and component schemas for all remaining endpoints
parent f89bdfdb
...@@ -26,7 +26,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -26,7 +26,7 @@ All findings across authentication security, dynamic permission-based access con
## Findings Backlog & Resolution Summary ## Findings Backlog & Resolution Summary
| ID | Severity | Module | Summary of Issue | Verification | Resolution Status | | ID | Severity | Module | Summary of Issue | Verification | Resolution Status |
| :--- | :--- | :--- | :--- | :--- | :--- | | :----------- | :------- | :------------------- | :-------------------------------------------------------------------------------------------- | :----------- | :-------------------------------- |
| **BUG-01** | 🔴 P0 | App / Security | CORS origin reflection allowed wildcard with credentials | CONFIRMED | **FIXED & TESTED** | | **BUG-01** | 🔴 P0 | App / Security | CORS origin reflection allowed wildcard with credentials | CONFIRMED | **FIXED & TESTED** |
| **BUG-02** | 🟠 P1 | Webhooks / Templates | Missing authorization guards on webhook and extraction template mutations | CONFIRMED | **FIXED & RBAC-PROTECTED** | | **BUG-02** | 🟠 P1 | Webhooks / Templates | Missing authorization guards on webhook and extraction template mutations | CONFIRMED | **FIXED & RBAC-PROTECTED** |
| **BUG-03** | 🟠 P1 | Auth / DB | Non-atomic default role assignment during user registration | CONFIRMED | **FIXED (Atomic Transaction)** | | **BUG-03** | 🟠 P1 | Auth / DB | Non-atomic default role assignment during user registration | CONFIRMED | **FIXED (Atomic Transaction)** |
...@@ -52,6 +52,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -52,6 +52,7 @@ All findings across authentication security, dynamic permission-based access con
## Fixed Issues Detail ## Fixed Issues Detail
### [BUG-01] CORS Origin Reflection With Credentials ### [BUG-01] CORS Origin Reflection With Credentials
- **Severity**: 🔴 P0 - **Severity**: 🔴 P0
- **Module**: `app` - **Module**: `app`
- **Root Cause**: Wildcard origins combined with `credentials: true` caused the server to reflect the incoming `Origin` header dynamically, permitting malicious third-party origins to perform authenticated cross-origin reads. - **Root Cause**: Wildcard origins combined with `credentials: true` caused the server to reflect the incoming `Origin` header dynamically, permitting malicious third-party origins to perform authenticated cross-origin reads.
...@@ -63,6 +64,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -63,6 +64,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-02] Missing RBAC / Permissions on Webhooks and Extraction Templates ### [BUG-02] Missing RBAC / Permissions on Webhooks and Extraction Templates
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `webhooks`, `extraction-templates` - **Module**: `webhooks`, `extraction-templates`
- **Root Cause**: Router definitions applied `authMiddleware` but lacked permission checks, allowing unprivileged accounts (`VIEWER`) to create webhooks (SSRF / Data exfiltration risk) or alter extraction templates. - **Root Cause**: Router definitions applied `authMiddleware` but lacked permission checks, allowing unprivileged accounts (`VIEWER`) to create webhooks (SSRF / Data exfiltration risk) or alter extraction templates.
...@@ -75,6 +77,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -75,6 +77,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-03] Atomic Default Role Assignment During Registration ### [BUG-03] Atomic Default Role Assignment During Registration
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `auth` - **Module**: `auth`
- **Root Cause**: User creation and initial role assignment to `user_roles` were executed across separate, non-atomic steps, creating dangling unassigned users if interrupted. - **Root Cause**: User creation and initial role assignment to `user_roles` were executed across separate, non-atomic steps, creating dangling unassigned users if interrupted.
...@@ -86,6 +89,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -86,6 +89,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-04] Prisma Known Request Error Normalization ### [BUG-04] Prisma Known Request Error Normalization
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `error-middleware` - **Module**: `error-middleware`
- **Root Cause**: Uncaught Prisma errors (`P2002`, `P2023`, `P2025`, `P2003`) fell into the generic 500 handler, leaking database table names and column identifiers to client logs. - **Root Cause**: Uncaught Prisma errors (`P2002`, `P2023`, `P2025`, `P2003`) fell into the generic 500 handler, leaking database table names and column identifiers to client logs.
...@@ -97,6 +101,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -97,6 +101,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-05] Cascading Resource Deactivation on User Soft-Delete & Self-Deactivation ### [BUG-05] Cascading Resource Deactivation on User Soft-Delete & Self-Deactivation
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `users`, `auth` - **Module**: `users`, `auth`
- **Root Cause**: Deleting a user or confirming account deactivation left `crawl_schedules`, `api_keys`, and `webhook_configs` active, causing background BullMQ workers to continue crawling and dispatching webhooks. - **Root Cause**: Deleting a user or confirming account deactivation left `crawl_schedules`, `api_keys`, and `webhook_configs` active, causing background BullMQ workers to continue crawling and dispatching webhooks.
...@@ -109,6 +114,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -109,6 +114,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-10] Global Content Security Policy (CSP) Scoping ### [BUG-10] Global Content Security Policy (CSP) Scoping
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `app` - **Module**: `app`
- **Root Cause**: Global Helmet CSP was previously turned off to allow Swagger UI inline assets, removing client-side injection protection for all API endpoints. - **Root Cause**: Global Helmet CSP was previously turned off to allow Swagger UI inline assets, removing client-side injection protection for all API endpoints.
...@@ -120,6 +126,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -120,6 +126,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-06] N+1 Query in User Role Assignment ### [BUG-06] N+1 Query in User Role Assignment
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `roles`, `users` - **Module**: `roles`, `users`
- **Root Cause**: `assignUserRoles` iterated sequentially over `roleIds` with individual `findById` queries. - **Root Cause**: `assignUserRoles` iterated sequentially over `roleIds` with individual `findById` queries.
...@@ -132,6 +139,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -132,6 +139,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-07] Strict Layer Architecture Isolation in Health Check ### [BUG-07] Strict Layer Architecture Isolation in Health Check
- **Severity**: 🟡 P2 - **Severity**: 🟡 P2
- **Module**: `health` - **Module**: `health`
- **Root Cause**: `HealthService` directly imported and called `prisma.$queryRaw`, violating the exclusive Prisma access rule in `AGENTS.md`. - **Root Cause**: `HealthService` directly imported and called `prisma.$queryRaw`, violating the exclusive Prisma access rule in `AGENTS.md`.
...@@ -144,6 +152,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -144,6 +152,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-08] Dashboard Query Aggregation Optimization ### [BUG-08] Dashboard Query Aggregation Optimization
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `dashboard` - **Module**: `dashboard`
- **Root Cause**: 11 sequential `count()` queries executed per dashboard stats request, overloading PostgreSQL. - **Root Cause**: 11 sequential `count()` queries executed per dashboard stats request, overloading PostgreSQL.
...@@ -155,6 +164,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -155,6 +164,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [BUG-09] & [BUG-15] Schema Cascade & Composite Index Optimization ### [BUG-09] & [BUG-15] Schema Cascade & Composite Index Optimization
- **Severity**: 🟡 P2 - **Severity**: 🟡 P2
- **Module**: `database` - **Module**: `database`
- **Root Cause**: `CrawlAsset.crawlJob` lacked `onDelete: Cascade` (causing P2003 errors on job deletion), and `CrawlJob` lacked composite indexing for user timeline queries. - **Root Cause**: `CrawlAsset.crawlJob` lacked `onDelete: Cascade` (causing P2003 errors on job deletion), and `CrawlJob` lacked composite indexing for user timeline queries.
...@@ -166,6 +176,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -166,6 +176,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [AUDIT-01] CrawlScheduleController Envelope Standardization ### [AUDIT-01] CrawlScheduleController Envelope Standardization
- **Severity**: 🟠 P1 - **Severity**: 🟠 P1
- **Module**: `crawl-schedules` - **Module**: `crawl-schedules`
- **Root Cause**: Endpoints in `CrawlScheduleController` returned raw data or `{ message, data }` without `{ success: true, data }`, breaking frontend API consumer expectations. - **Root Cause**: Endpoints in `CrawlScheduleController` returned raw data or `{ message, data }` without `{ success: true, data }`, breaking frontend API consumer expectations.
...@@ -177,6 +188,7 @@ All findings across authentication security, dynamic permission-based access con ...@@ -177,6 +188,7 @@ All findings across authentication security, dynamic permission-based access con
--- ---
### [AUDIT-02] Edge Route Parameter Validation Across All Routers ### [AUDIT-02] Edge Route Parameter Validation Across All Routers
- **Severity**: 🟡 P2 - **Severity**: 🟡 P2
- **Module**: `cross-cutting / routing` - **Module**: `cross-cutting / routing`
- **Root Cause**: Route identifiers (`:id`, `:roleId`, `:permissionId`) were passed directly to services without edge validation, risking malformed identifiers reaching Prisma. - **Root Cause**: Route identifiers (`:id`, `:roleId`, `:permissionId`) were passed directly to services without edge validation, risking malformed identifiers reaching Prisma.
......
This diff is collapsed.
This diff is collapsed.
...@@ -695,6 +695,122 @@ const rawSchemas = { ...@@ -695,6 +695,122 @@ const rawSchemas = {
}, },
}, },
}, },
UpdateWebhookConfigRequest: {
type: "object",
properties: {
url: {
type: "string",
format: "uri",
example: "https://example.com/webhook",
},
secret: {
type: "string",
minLength: 16,
maxLength: 128,
example: "new_webhook_secret_key_123456",
},
events: {
type: "array",
items: { type: "string", enum: ["job.completed", "job.failed"] },
example: ["job.completed"],
},
isActive: { type: "boolean", example: true },
},
},
ExtractionTemplateField: {
type: "object",
required: ["name", "selector", "attr", "required"],
properties: {
name: { type: "string", example: "title" },
selector: { type: "string", example: "h1.product-title" },
attr: { type: "string", example: "innerText" },
required: { type: "boolean", example: true },
},
},
ExtractionTemplate: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
userId: { type: "string", format: "uuid" },
name: { type: "string", example: "E-Commerce Product Extractor" },
domain: { type: "string", example: "example.com" },
fields: {
type: "array",
items: { $ref: "#/components/schemas/ExtractionTemplateField" },
},
createdAt: { type: "string", format: "date-time" },
updatedAt: { type: "string", format: "date-time" },
},
},
CreateExtractionTemplateRequest: {
type: "object",
required: ["name", "domain", "fields"],
properties: {
name: { type: "string", example: "E-Commerce Product Extractor" },
domain: { type: "string", example: "example.com" },
fields: {
type: "array",
items: { $ref: "#/components/schemas/ExtractionTemplateField" },
},
},
},
UpdateExtractionTemplateRequest: {
type: "object",
properties: {
name: { type: "string", example: "Updated Template Name" },
fields: {
type: "array",
items: { $ref: "#/components/schemas/ExtractionTemplateField" },
},
},
},
CrawlJobLog: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
jobId: { type: "string", format: "uuid" },
level: { type: "string", enum: ["INFO", "WARN", "ERROR"] },
step: { type: "string", example: "FETCH_PAGE" },
message: { type: "string", example: "Successfully fetched page 1" },
createdAt: { type: "string", format: "date-time" },
},
},
DashboardStats: {
type: "object",
properties: {
jobs: {
type: "object",
properties: {
total: { type: "integer", example: 42 },
completed: { type: "integer", example: 35 },
failed: { type: "integer", example: 3 },
running: { type: "integer", example: 2 },
pending: { type: "integer", example: 2 },
},
},
pages: {
type: "object",
properties: {
total: { type: "integer", example: 1250 },
successful: { type: "integer", example: 1200 },
failed: { type: "integer", example: 50 },
},
},
schedules: {
type: "object",
properties: {
total: { type: "integer", example: 5 },
active: { type: "integer", example: 4 },
},
},
exports: {
type: "object",
properties: {
total: { type: "integer", example: 18 },
},
},
},
},
}; };
const outputFile = "./src/docs/swagger.json"; const outputFile = "./src/docs/swagger.json";
......
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