diff --git a/app/(tabs)/profile.tsx b/app/(tabs)/profile.tsx
index fabdb87..c37852f 100644
--- a/app/(tabs)/profile.tsx
+++ b/app/(tabs)/profile.tsx
@@ -1,4 +1,5 @@
-import { View, ScrollView } from 'react-native';
+import { View, ScrollView, Pressable } from 'react-native';
+import { router } from 'expo-router';
import { Text } from '@/components/ui/text';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
@@ -28,10 +29,10 @@ export default function ProfileScreen() {
Language
English
-
+ router.push('/notifications')} className="flex-row justify-between py-2">
Notifications
- On
-
+ Manage
+
@@ -46,6 +47,9 @@ export default function ProfileScreen() {
+
diff --git a/app/_layout.tsx b/app/_layout.tsx
index 90d11a5..4761d3b 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -12,7 +12,20 @@ export default function RootLayout() {
-
+
+
+
+
+
+
+
+
diff --git a/app/login.tsx b/app/login.tsx
new file mode 100644
index 0000000..1669f8e
--- /dev/null
+++ b/app/login.tsx
@@ -0,0 +1,30 @@
+import { View, ScrollView } from 'react-native';
+import { router } from 'expo-router';
+import { Text } from '@/components/ui/text';
+import { Button } from '@/components/ui/button';
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
+
+export default function LoginScreen() {
+ return (
+
+ Yaltopia Tickets
+
+
+ Sign in
+ Use the same account as the web app.
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/notifications/index.tsx b/app/notifications/index.tsx
new file mode 100644
index 0000000..1290072
--- /dev/null
+++ b/app/notifications/index.tsx
@@ -0,0 +1,33 @@
+import { View, ScrollView, Pressable } from 'react-native';
+import { router } from 'expo-router';
+import { Text } from '@/components/ui/text';
+import { Card, CardContent } from '@/components/ui/card';
+
+const MOCK_NOTIFICATIONS = [
+ { id: '1', title: 'Invoice reminder', body: 'Invoice #2 to Robin Murray is due in 2 days.', time: '2h ago', read: false },
+ { id: '2', title: 'Payment received', body: 'Payment of $500 received for Invoice #4.', time: '1d ago', read: true },
+ { id: '3', title: 'Proforma submission', body: 'Vendor A submitted a quote for Marketing Landing Page.', time: '2d ago', read: true },
+];
+
+export default function NotificationsScreen() {
+ return (
+
+
+ Notifications
+ router.push('/notifications/settings')}>
+ Settings
+
+
+
+ {MOCK_NOTIFICATIONS.map((n) => (
+
+
+ {n.title}
+ {n.body}
+ {n.time}
+
+
+ ))}
+
+ );
+}
diff --git a/app/notifications/settings.tsx b/app/notifications/settings.tsx
new file mode 100644
index 0000000..e570b8e
--- /dev/null
+++ b/app/notifications/settings.tsx
@@ -0,0 +1,41 @@
+import { View, ScrollView, Switch } from 'react-native';
+import { router } from 'expo-router';
+import { useState } from 'react';
+import { Text } from '@/components/ui/text';
+import { Button } from '@/components/ui/button';
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+
+export default function NotificationSettingsScreen() {
+ const [invoiceReminders, setInvoiceReminders] = useState(true);
+ const [daysBeforeDue, setDaysBeforeDue] = useState(2);
+ const [newsAlerts, setNewsAlerts] = useState(true);
+ const [reportReady, setReportReady] = useState(true);
+
+ return (
+
+
+
+ Notification settings
+
+
+
+ Invoice reminders
+
+
+
+ News & announcements
+
+
+
+ Report ready
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/payments/[id].tsx b/app/payments/[id].tsx
new file mode 100644
index 0000000..1070da0
--- /dev/null
+++ b/app/payments/[id].tsx
@@ -0,0 +1,44 @@
+import { View, ScrollView } from 'react-native';
+import { useLocalSearchParams, router } from 'expo-router';
+import { Text } from '@/components/ui/text';
+import { Button } from '@/components/ui/button';
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+
+export default function PaymentDetailScreen() {
+ const { id } = useLocalSearchParams<{ id: string }>();
+
+ return (
+
+
+
+ Payment #{id ?? '—'}
+
+
+
+ Amount
+ $2,000.00
+
+
+ Source
+ Telebirr
+
+
+ Date
+ Sep 11, 2022
+
+
+ Associated invoice
+ Not linked
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/proforma/[id].tsx b/app/proforma/[id].tsx
new file mode 100644
index 0000000..d3b1014
--- /dev/null
+++ b/app/proforma/[id].tsx
@@ -0,0 +1,66 @@
+import { View, ScrollView } from 'react-native';
+import { useLocalSearchParams, router } from 'expo-router';
+import { Text } from '@/components/ui/text';
+import { Button } from '@/components/ui/button';
+import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
+
+const MOCK_ITEMS = [
+ { description: 'Marketing Landing Page Package', qty: 1, unitPrice: 1000, total: 1000 },
+ { description: 'Instagram Post Initial Design', qty: 4, unitPrice: 100, total: 400 },
+];
+const MOCK_SUBTOTAL = 1400;
+const MOCK_TAX = 140;
+const MOCK_TOTAL = 1540;
+
+export default function ProformaDetailScreen() {
+ const { id } = useLocalSearchParams<{ id: string }>();
+
+ return (
+
+
+
+ Proforma Request #{id ?? '—'}
+ Marketing Landing Page Package
+ Deadline: Sep 20, 2022 · OPEN
+
+
+ {MOCK_ITEMS.map((item, i) => (
+
+ {item.description} × {item.qty}
+ ${item.total.toLocaleString()}
+
+ ))}
+
+
+ Subtotal
+ ${MOCK_SUBTOTAL.toLocaleString()}
+
+
+ Tax (10%)
+ ${MOCK_TAX.toLocaleString()}
+
+
+ Total
+ ${MOCK_TOTAL.toLocaleString()}
+
+
+
+
+
+
+
+
+ Submissions (mock)
+
+
+ Vendor A — $1,450
+ Submitted Sep 15, 2022
+
+
+
+ );
+}
diff --git a/swagger.json b/swagger.json
new file mode 100644
index 0000000..aeb1488
--- /dev/null
+++ b/swagger.json
@@ -0,0 +1,11540 @@
+{
+ "openapi": "3.0.0",
+ "paths": {
+ "/api/v1/rbac/roles": {
+ "get": {
+ "operationId": "RbacController_getRoles",
+ "summary": "Get all available roles with descriptions",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RoleInfoDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/permissions": {
+ "get": {
+ "operationId": "RbacController_getPermissions",
+ "summary": "Get all available permissions",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/my-permissions": {
+ "get": {
+ "operationId": "RbacController_getMyPermissions",
+ "summary": "Get current user permissions",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/creatable-roles": {
+ "get": {
+ "operationId": "RbacController_getCreatableRoles",
+ "summary": "Get roles that current user can create",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/manageable-roles": {
+ "get": {
+ "operationId": "RbacController_getManageableRoles",
+ "summary": "Get roles that current user can manage",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/role/{role}/permissions": {
+ "get": {
+ "operationId": "RbacController_getRolePermissions",
+ "summary": "Get permissions for a specific role",
+ "parameters": [
+ {
+ "name": "role",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/user/{userId}/change-role": {
+ "post": {
+ "operationId": "RbacController_changeUserRole",
+ "summary": "Change user role",
+ "parameters": [
+ {
+ "name": "userId",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ChangeUserRoleDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/check-permission/{permission}": {
+ "get": {
+ "operationId": "RbacController_checkPermission",
+ "summary": "Check if current user has a specific permission",
+ "parameters": [
+ {
+ "name": "permission",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/can-create-role/{role}": {
+ "get": {
+ "operationId": "RbacController_canCreateRole",
+ "summary": "Check if current user can create a user with specific role",
+ "parameters": [
+ {
+ "name": "role",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/rbac/can-manage-role/{role}": {
+ "get": {
+ "operationId": "RbacController_canManageRole",
+ "summary": "Check if current user can manage users with specific role",
+ "parameters": [
+ {
+ "name": "role",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "RBAC"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/me": {
+ "get": {
+ "operationId": "UserController_getProfile",
+ "summary": "Get current user profile",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "UserController_updateProfile",
+ "summary": "Update current user profile",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateUserDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users": {
+ "get": {
+ "operationId": "UserController_findAll",
+ "summary": "Get users that current user can manage",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/created-by-me": {
+ "get": {
+ "operationId": "UserController_getMyCreatedUsers",
+ "summary": "Get users created by current user",
+ "description": "Returns all users that were created by the currently authenticated user. Business Owners can see employees, accountants, and customer service users they created.",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "List of users created by current user",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/{id}": {
+ "get": {
+ "operationId": "UserController_findOne",
+ "summary": "Get user by ID (if user can manage them)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Cannot manage this user"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/{id}/deactivate": {
+ "patch": {
+ "operationId": "UserController_deactivate",
+ "summary": "Deactivate user (if user can manage them)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Cannot manage this user"
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/{id}/activate": {
+ "patch": {
+ "operationId": "UserController_activate",
+ "summary": "Activate user (if user can manage them)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Cannot manage this user"
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/users/{id}/change-role": {
+ "patch": {
+ "operationId": "UserController_changeRole",
+ "summary": "Change user role (if user can manage them)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ChangeUserRoleDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Cannot manage this user or assign this role"
+ }
+ },
+ "tags": [
+ "Users"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/auth/register": {
+ "post": {
+ "operationId": "AuthController_register",
+ "summary": "Register a new user with role-based authorization",
+ "description": "Register a new user with conditional access control.\n\n**IMPORTANT: Role field is REQUIRED in request body**\n\n**Authorization Requirements:**\n- VIEWER: No token required (can be created by anyone)\n- EMPLOYEE, ACCOUNTANT, CUSTOMER_SERVICE: Business Owner or Admin token required\n- BUSINESS_OWNER: Admin token only\n- ADMIN, AUDITOR: Admin token only\n\n**Example Request Bodies:**\n\nFor VIEWER (no token needed):\n```json\n{\n \"email\": \"viewer@example.com\",\n \"phone\": \"+1234567890\",\n \"password\": \"Password@123\",\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"role\": \"VIEWER\"\n}\n```\n\nFor EMPLOYEE (Business Owner token required):\n```json\n{\n \"email\": \"employee@example.com\",\n \"phone\": \"+1234567891\",\n \"password\": \"Password@123\",\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\",\n \"role\": \"EMPLOYEE\"\n}\n```\n\n**Note: Both email and phone number are required for all registrations. For public registration, simply use role \"VIEWER\" without any authorization token.**",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RegisterDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "User successfully registered",
+ "example": {
+ "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "user": {
+ "id": "uuid-string",
+ "email": "employee@example.com",
+ "firstName": "Jane",
+ "lastName": "Smith",
+ "role": "EMPLOYEE"
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuthResponseDto"
+ },
+ "example": {
+ "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "user": {
+ "id": "uuid-string",
+ "email": "employee@example.com",
+ "firstName": "Jane",
+ "lastName": "Smith",
+ "role": "EMPLOYEE"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid role specified",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 400,
+ "message": [
+ "Role must be a valid UserRole"
+ ],
+ "error": "Bad Request"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication required for this role",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 401,
+ "message": "Authentication required to create user with role: EMPLOYEE.",
+ "error": "Unauthorized"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Insufficient permissions to create user with this role",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 403,
+ "message": "Insufficient permissions. EMPLOYEE cannot create users with role: BUSINESS_OWNER",
+ "error": "Forbidden"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "User already exists",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 409,
+ "message": "User with this email already exists",
+ "error": "Conflict"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Authentication"
+ ]
+ }
+ },
+ "/api/v1/auth/login": {
+ "post": {
+ "operationId": "AuthController_login",
+ "summary": "Login user with email or phone number",
+ "description": "Login using either email address or phone number along with password.\n\n**Login Options:**\n- Email + Password\n- Phone Number + Password\n\n**Example Request Bodies:**\n\nLogin with email:\n```json\n{\n \"email\": \"user@example.com\",\n \"password\": \"Password@123\"\n}\n```\n\nLogin with phone:\n```json\n{\n \"phone\": \"+1234567890\",\n \"password\": \"Password@123\"\n}\n```\n\n**Note: Provide either email OR phone number, not both.**",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LoginDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "User successfully logged in",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuthResponseDto"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Invalid credentials"
+ }
+ },
+ "tags": [
+ "Authentication"
+ ]
+ }
+ },
+ "/api/v1/auth/refresh": {
+ "post": {
+ "operationId": "AuthController_refresh",
+ "summary": "Refresh access token",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RefreshTokenDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Token successfully refreshed"
+ },
+ "401": {
+ "description": "Invalid refresh token"
+ }
+ },
+ "tags": [
+ "Authentication"
+ ]
+ }
+ },
+ "/api/v1/auth/profile": {
+ "get": {
+ "operationId": "AuthController_getProfile",
+ "summary": "Get current user profile with permissions",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "User profile with permissions retrieved successfully"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ },
+ "tags": [
+ "Authentication"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/auth/logout": {
+ "post": {
+ "operationId": "AuthController_logout",
+ "summary": "Logout user",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "User successfully logged out"
+ }
+ },
+ "tags": [
+ "Authentication"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/auth/google": {
+ "get": {
+ "operationId": "AuthController_googleAuth",
+ "summary": "Initiate Google OAuth login",
+ "description": "Redirects to Google OAuth consent screen",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "302": {
+ "description": "Redirects to Google OAuth"
+ }
+ },
+ "tags": [
+ "Authentication"
+ ]
+ }
+ },
+ "/api/v1/auth/google/callback": {
+ "get": {
+ "operationId": "AuthController_googleAuthRedirect",
+ "summary": "Google OAuth callback",
+ "description": "Handles Google OAuth callback and returns JWT tokens",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "User successfully authenticated with Google",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AuthResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Authentication"
+ ]
+ }
+ },
+ "/api/v1/invoices": {
+ "post": {
+ "operationId": "InvoiceController_create",
+ "summary": "Create a new invoice",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateInvoiceDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Invoice successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvoiceResponseDto"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Invoice number already exists"
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "InvoiceController_findAll",
+ "summary": "Get all invoices with filtering and pagination",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "status",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DRAFT",
+ "PENDING",
+ "PAID",
+ "OVERDUE",
+ "CANCELLED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-01-01",
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-12-31",
+ "type": "string"
+ }
+ },
+ {
+ "name": "customerName",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "Acme",
+ "type": "string"
+ }
+ },
+ {
+ "name": "invoiceNumber",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "INV-2024",
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "search term",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InvoiceResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/stats": {
+ "get": {
+ "operationId": "InvoiceController_getStats",
+ "summary": "Get invoice statistics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Invoice statistics retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "number"
+ },
+ "paid": {
+ "type": "number"
+ },
+ "pending": {
+ "type": "number"
+ },
+ "overdue": {
+ "type": "number"
+ },
+ "totalRevenue": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/share/email": {
+ "post": {
+ "operationId": "InvoiceController_shareViaEmail",
+ "summary": "Share invoice via email",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SendShareEmailDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Invoice shared via email successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/share/link": {
+ "post": {
+ "operationId": "InvoiceController_shareViaLink",
+ "summary": "Generate shareable link for invoice",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateShareLinkDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Share link created successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/{id}": {
+ "get": {
+ "operationId": "InvoiceController_findOne",
+ "summary": "Get invoice by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvoiceResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Invoice not found"
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "InvoiceController_update",
+ "summary": "Update invoice",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateInvoiceDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvoiceResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Invoice not found"
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "InvoiceController_delete",
+ "summary": "Delete invoice",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Invoice successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Invoice not found"
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/{id}/pdf": {
+ "get": {
+ "operationId": "InvoiceController_downloadPDF",
+ "summary": "Download invoice as PDF",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "PDF file"
+ },
+ "404": {
+ "description": "Invoice not found"
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/invoices/{id}/status": {
+ "patch": {
+ "operationId": "InvoiceController_updateStatus",
+ "summary": "Update invoice status",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InvoiceResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Invoices"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/share": {
+ "post": {
+ "operationId": "ShareController_create",
+ "summary": "Create a shareable link for an invoice",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateShareLinkDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Share link successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Invoice not found"
+ }
+ },
+ "tags": [
+ "Share"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "ShareController_findAll",
+ "summary": "Get all share links",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Share"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/share/email": {
+ "post": {
+ "operationId": "ShareController_sendEmail",
+ "summary": "Create share link and send via email",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SendShareEmailDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Share link created and email sent",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Share"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/share/view/{token}": {
+ "get": {
+ "operationId": "ShareController_viewShared",
+ "summary": "View shared invoice by token (public)",
+ "parameters": [
+ {
+ "name": "token",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Invoice data"
+ },
+ "403": {
+ "description": "Share link expired or inactive"
+ },
+ "404": {
+ "description": "Share link not found"
+ }
+ },
+ "tags": [
+ "Share"
+ ]
+ }
+ },
+ "/api/v1/share/{id}/deactivate": {
+ "patch": {
+ "operationId": "ShareController_deactivate",
+ "summary": "Deactivate a share link",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ShareLinkResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Share"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/share/{id}": {
+ "delete": {
+ "operationId": "ShareController_delete",
+ "summary": "Delete a share link",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Share link successfully deleted"
+ }
+ },
+ "tags": [
+ "Share"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/reports/generate": {
+ "post": {
+ "operationId": "ReportController_generate",
+ "summary": "Generate report (monthly/quarterly/annual)",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GenerateReportDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Report successfully generated",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ReportResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/reports/latest": {
+ "get": {
+ "operationId": "ReportController_getLatest",
+ "summary": "Get latest generated report",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ReportResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "No reports found"
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/reports": {
+ "get": {
+ "operationId": "ReportController_findAll",
+ "summary": "Get all reports (with optional pagination)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ReportResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/reports/{id}": {
+ "get": {
+ "operationId": "ReportController_findOne",
+ "summary": "Get report by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ReportResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Report not found"
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "ReportController_delete",
+ "summary": "Delete report",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Report successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Report not found"
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/reports/{id}/download": {
+ "get": {
+ "operationId": "ReportController_downloadPDF",
+ "summary": "Download report PDF",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "PDF file"
+ },
+ "404": {
+ "description": "Report or PDF not found"
+ }
+ },
+ "tags": [
+ "Reports"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications/subscribe": {
+ "post": {
+ "operationId": "NotificationController_subscribe",
+ "summary": "Subscribe to push notifications",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SubscribeDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully subscribed"
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications/unsubscribe/{endpoint}": {
+ "delete": {
+ "operationId": "NotificationController_unsubscribe",
+ "summary": "Unsubscribe from push notifications",
+ "parameters": [
+ {
+ "name": "endpoint",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully unsubscribed"
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications/send": {
+ "post": {
+ "operationId": "NotificationController_send",
+ "summary": "Send push notification (Admin only)",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SendNotificationDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Notification sent successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NotificationResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications": {
+ "get": {
+ "operationId": "NotificationController_findAll",
+ "summary": "Get all notifications for current user",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/NotificationResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications/settings": {
+ "get": {
+ "operationId": "NotificationController_getSettings",
+ "summary": "Get user notification settings",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Notification settings retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "invoiceReminders": {
+ "type": "boolean"
+ },
+ "daysBeforeDueDate": {
+ "type": "number"
+ },
+ "newsAlerts": {
+ "type": "boolean"
+ },
+ "reportReady": {
+ "type": "boolean"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "NotificationController_updateSettings",
+ "summary": "Update user notification settings",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateNotificationSettingsDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Notification settings updated successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "invoiceReminders": {
+ "type": "boolean"
+ },
+ "daysBeforeDueDate": {
+ "type": "number"
+ },
+ "newsAlerts": {
+ "type": "boolean"
+ },
+ "reportReady": {
+ "type": "boolean"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updatedAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/notifications/invoice/{id}/reminder": {
+ "post": {
+ "operationId": "NotificationController_sendInvoiceReminder",
+ "summary": "Send invoice due reminder",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Reminder sent successfully"
+ },
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Notifications"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/news": {
+ "get": {
+ "operationId": "NewsController_findAll",
+ "summary": "Get all news/announcements (public)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "isPublished",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "default": true,
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "category",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "ANNOUNCEMENT",
+ "UPDATE",
+ "MAINTENANCE",
+ "NEWS"
+ ],
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "News"
+ ]
+ },
+ "post": {
+ "operationId": "NewsController_create",
+ "summary": "Create news article (Admin only)",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateNewsDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "News"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/news/latest": {
+ "get": {
+ "operationId": "NewsController_getLatest",
+ "summary": "Get latest news items (public)",
+ "parameters": [
+ {
+ "name": "limit",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "News"
+ ]
+ }
+ },
+ "/api/v1/news/{id}": {
+ "get": {
+ "operationId": "NewsController_findOne",
+ "summary": "Get news by ID (public)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "News not found"
+ }
+ },
+ "tags": [
+ "News"
+ ]
+ },
+ "put": {
+ "operationId": "NewsController_update",
+ "summary": "Update news article (Admin only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateNewsDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "News"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "NewsController_delete",
+ "summary": "Delete news (Admin only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "News successfully deleted"
+ }
+ },
+ "tags": [
+ "News"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/news/{id}/read": {
+ "post": {
+ "operationId": "NewsController_markAsRead",
+ "summary": "Mark news item as read",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "News marked as read"
+ }
+ },
+ "tags": [
+ "News"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/news/{id}/toggle-publish": {
+ "patch": {
+ "operationId": "NewsController_togglePublish",
+ "summary": "Toggle news publish status (Admin only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NewsResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "News"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/upload": {
+ "post": {
+ "operationId": "DocumentController_upload",
+ "summary": "Upload a document",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "binary"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "PDF",
+ "EXCEL",
+ "IMAGE",
+ "OTHER"
+ ]
+ },
+ "invoiceId": {
+ "type": "string"
+ },
+ "isPublic": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "file",
+ "type"
+ ]
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Document successfully uploaded",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DocumentResponseDto"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid file or request"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents": {
+ "get": {
+ "operationId": "DocumentController_findAll",
+ "summary": "Get all documents (filterable by category)",
+ "parameters": [
+ {
+ "name": "category",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DocumentResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/storage-usage": {
+ "get": {
+ "operationId": "DocumentController_getStorageUsage",
+ "summary": "Get user storage usage statistics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Storage usage statistics"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/{id}/preview": {
+ "get": {
+ "operationId": "DocumentController_getPreview",
+ "summary": "Get document preview URL",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Document preview URL",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "previewUrl": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/{id}": {
+ "get": {
+ "operationId": "DocumentController_findOne",
+ "summary": "Get document metadata by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DocumentResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Document not found"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "DocumentController_delete",
+ "summary": "Delete document",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Document successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Document not found"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/{id}/download": {
+ "get": {
+ "operationId": "DocumentController_download",
+ "summary": "Download document file",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "File stream"
+ },
+ "404": {
+ "description": "Document not found"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/documents/public/{id}/download": {
+ "get": {
+ "operationId": "DocumentController_downloadPublic",
+ "summary": "Download public document file (no auth required)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "File stream"
+ },
+ "404": {
+ "description": "Document not found"
+ }
+ },
+ "tags": [
+ "Documents"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma": {
+ "post": {
+ "operationId": "ProformaController_create",
+ "summary": "Create a new proforma invoice",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProformaDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Proforma successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaResponseDto"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Proforma number already exists"
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "ProformaController_findAll",
+ "summary": "Get all proforma invoices with filtering and pagination",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-01-01",
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-12-31",
+ "type": "string"
+ }
+ },
+ {
+ "name": "customerName",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "Acme",
+ "type": "string"
+ }
+ },
+ {
+ "name": "proformaNumber",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "PROF-2024",
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "search term",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma/{id}": {
+ "get": {
+ "operationId": "ProformaController_findOne",
+ "summary": "Get proforma invoice by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Proforma not found"
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "ProformaController_update",
+ "summary": "Update proforma invoice",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateProformaDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Proforma not found"
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "ProformaController_delete",
+ "summary": "Delete proforma invoice",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Proforma successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Proforma not found"
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma/{id}/pdf": {
+ "get": {
+ "operationId": "ProformaController_downloadPDF",
+ "summary": "Download proforma invoice as PDF",
+ "description": "Generate and download proforma invoice as PDF. \n \n**Company Information Priority:**\n1. **Override**: Use companyName query parameter if provided\n2. **Database**: Fetch from your company profile if exists\n3. **Fallback**: Use default company name from configuration\n\n**Company Profile Data Included (if available):**\n- Company name, address, city, state, zip code, country\n- Phone, email, website, TIN (Tax Identification Number)\n- Company logo (if uploaded)\n\n**Usage Examples:**\n- Default: `GET /proforma/123/pdf`\n- With override: `GET /proforma/123/pdf?companyName=Custom Company Ltd.`",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "companyName",
+ "required": false,
+ "in": "query",
+ "description": "Override company name for this PDF (max 100 characters)",
+ "schema": {
+ "example": "Custom Company Name Ltd.",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "PDF file generated successfully",
+ "headers": {
+ "Content-Type": {
+ "description": "application/pdf"
+ },
+ "Content-Disposition": {
+ "description": "attachment; filename=\"proforma_[number]_[id].pdf\""
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Proforma not found"
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma/company/info": {
+ "get": {
+ "operationId": "ProformaController_getCompanyInfo",
+ "summary": "Get company information for proforma generation",
+ "description": "Get current company information that will be used in proforma PDFs",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Company information retrieved successfully",
+ "content": {
+ "application/json": {
+ "example": {
+ "hasCompanyInfo": true,
+ "companyName": "My Company Ltd.",
+ "address": "123 Business St, City, State 12345",
+ "contact": "Phone: +1234567890 | Email: info@company.com",
+ "tin": "TIN123456789"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/payments": {
+ "post": {
+ "operationId": "PaymentController_create",
+ "summary": "Create a new payment record",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreatePaymentDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Payment successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Transaction ID already exists"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "PaymentController_findAll",
+ "summary": "Get all payments (filterable by invoiceId)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "invoiceId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "invoice-123-id",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/payments/{id}": {
+ "get": {
+ "operationId": "PaymentController_findOne",
+ "summary": "Get payment details by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Payment not found"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "PaymentController_update",
+ "summary": "Update payment record",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdatePaymentDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Payment not found"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "PaymentController_delete",
+ "summary": "Delete payment record",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Payment successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Payment not found"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/payments/{id}/flag": {
+ "post": {
+ "operationId": "PaymentController_flag",
+ "summary": "Flag payment as fake/scam/other",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FlagPaymentDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Payment not found"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/payments/{paymentId}/associate": {
+ "post": {
+ "operationId": "PaymentController_associate",
+ "summary": "Associate payment with invoice",
+ "parameters": [
+ {
+ "name": "paymentId",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AssociatePaymentDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PaymentResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Payment or invoice not found"
+ }
+ },
+ "tags": [
+ "Payments"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/metrics": {
+ "get": {
+ "operationId": "DashboardController_getMetrics",
+ "summary": "Get dashboard metrics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Dashboard metrics retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DashboardMetricsDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/invoice-trends": {
+ "get": {
+ "operationId": "DashboardController_getInvoiceTrends",
+ "summary": "Get invoice trends",
+ "parameters": [
+ {
+ "name": "period",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Invoice trends retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "date": {
+ "type": "string"
+ },
+ "count": {
+ "type": "number"
+ },
+ "revenue": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/revenue-trends": {
+ "get": {
+ "operationId": "DashboardController_getRevenueTrends",
+ "summary": "Get revenue trends",
+ "parameters": [
+ {
+ "name": "period",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Revenue trends retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "date": {
+ "type": "string"
+ },
+ "revenue": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/invoice-status": {
+ "get": {
+ "operationId": "DashboardController_getInvoiceStatus",
+ "summary": "Get invoice status breakdown",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Invoice status breakdown retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "count": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/sales-purchase": {
+ "get": {
+ "operationId": "DashboardController_getSalesPurchaseComparison",
+ "summary": "Get sales vs purchase comparison",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Sales vs purchase comparison retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "sales": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "count": {
+ "type": "number"
+ },
+ "total": {
+ "type": "number"
+ }
+ }
+ }
+ },
+ "purchases": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "count": {
+ "type": "number"
+ },
+ "total": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/dashboard/scanned-invoices": {
+ "get": {
+ "operationId": "DashboardController_getScannedInvoices",
+ "summary": "Get scanned invoices pending verification",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Scanned invoices retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "invoiceNumber": {
+ "type": "string"
+ },
+ "customerName": {
+ "type": "string"
+ },
+ "amount": {
+ "type": "number"
+ },
+ "issueDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "scannedData": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Dashboard"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/company": {
+ "get": {
+ "operationId": "CompanyController_getCompany",
+ "summary": "Get company information",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Company information retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CompanyResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Company not found"
+ }
+ },
+ "tags": [
+ "Company"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "CompanyController_updateCompany",
+ "summary": "Update company information",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateCompanyDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Company information updated successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CompanyResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Company"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/company/logo": {
+ "post": {
+ "operationId": "CompanyController_uploadLogo",
+ "summary": "Upload company logo",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "binary"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Logo uploaded successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CompanyResponseDto"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CompanyResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Company"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/team": {
+ "get": {
+ "operationId": "TeamController_findAll",
+ "summary": "List team members (paginated)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/TeamMemberResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Team"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "post": {
+ "operationId": "TeamController_create",
+ "summary": "Add team member",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateTeamMemberDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Team member successfully added",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TeamMemberResponseDto"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Team member already exists"
+ }
+ },
+ "tags": [
+ "Team"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/team/{id}": {
+ "put": {
+ "operationId": "TeamController_update",
+ "summary": "Update team member",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateTeamMemberDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Team member successfully updated",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TeamMemberResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Team member not found"
+ }
+ },
+ "tags": [
+ "Team"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "TeamController_delete",
+ "summary": "Delete team member",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Team member successfully deleted"
+ },
+ "404": {
+ "description": "Team member not found"
+ }
+ },
+ "tags": [
+ "Team"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/team/invite": {
+ "post": {
+ "operationId": "TeamController_invite",
+ "summary": "Invite team member via email",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InviteTeamMemberDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Team member invitation sent",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TeamMemberResponseDto"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Team member already exists"
+ }
+ },
+ "tags": [
+ "Team"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/integration/endpoints": {
+ "get": {
+ "operationId": "IntegrationController_getEndpoints",
+ "summary": "Get available API endpoints documentation",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "API endpoints documentation"
+ }
+ },
+ "tags": [
+ "Integration"
+ ]
+ }
+ },
+ "/api/v1/integration/keys": {
+ "get": {
+ "operationId": "IntegrationController_findAll",
+ "summary": "List API keys",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "API keys retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ApiKeyResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Integration"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "post": {
+ "operationId": "IntegrationController_create",
+ "summary": "Create new API key",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateApiKeyDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "API key successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ApiKeyResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Integration"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/integration/keys/{id}": {
+ "delete": {
+ "operationId": "IntegrationController_delete",
+ "summary": "Delete API key",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "API key successfully deleted"
+ },
+ "404": {
+ "description": "API key not found"
+ }
+ },
+ "tags": [
+ "Integration"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/scan/invoice": {
+ "post": {
+ "operationId": "ScanController_scanInvoice",
+ "summary": "Scan invoice image and extract data",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "binary"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Invoice scanned successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ScanInvoiceResponseDto"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ScanInvoiceResponseDto"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid file"
+ }
+ },
+ "tags": [
+ "Scan"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/scan/payment-receipt": {
+ "post": {
+ "operationId": "ScanController_scanPaymentReceipt",
+ "summary": "Scan payment receipt image and extract data",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "binary"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Payment receipt scanned successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ScanPaymentResponseDto"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ScanPaymentResponseDto"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid file"
+ }
+ },
+ "tags": [
+ "Scan"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/scan/images/invoice/{invoiceId}": {
+ "get": {
+ "operationId": "ScanImageController_getInvoiceImage",
+ "summary": "Get scanned invoice image",
+ "parameters": [
+ {
+ "name": "invoiceId",
+ "required": true,
+ "in": "path",
+ "description": "Invoice ID",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Image file returned"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Invoice or image not found"
+ }
+ },
+ "tags": [
+ "Scan Images"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/scan/images/payment/{paymentId}": {
+ "get": {
+ "operationId": "ScanImageController_getPaymentImage",
+ "summary": "Get scanned payment receipt image",
+ "parameters": [
+ {
+ "name": "paymentId",
+ "required": true,
+ "in": "path",
+ "description": "Payment ID",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Image file returned"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Payment or image not found"
+ }
+ },
+ "tags": [
+ "Scan Images"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs": {
+ "get": {
+ "operationId": "AdminController_getLogs",
+ "summary": "Get application logs",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "level",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ "FATAL"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "APPLICATION",
+ "ACCESS",
+ "ERROR",
+ "DATABASE",
+ "EMAIL",
+ "NOTIFICATION",
+ "AUDIT"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "userId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "minDuration",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 0,
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/errors": {
+ "get": {
+ "operationId": "AdminController_getErrorLogs",
+ "summary": "Get error logs only",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "level",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ "FATAL"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "APPLICATION",
+ "ACCESS",
+ "ERROR",
+ "DATABASE",
+ "EMAIL",
+ "NOTIFICATION",
+ "AUDIT"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "userId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "minDuration",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 0,
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/access": {
+ "get": {
+ "operationId": "AdminController_getAccessLogs",
+ "summary": "Get access logs",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "level",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ "FATAL"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "APPLICATION",
+ "ACCESS",
+ "ERROR",
+ "DATABASE",
+ "EMAIL",
+ "NOTIFICATION",
+ "AUDIT"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "userId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "minDuration",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 0,
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/{id}": {
+ "get": {
+ "operationId": "AdminController_getLogById",
+ "summary": "Get log by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/stats/summary": {
+ "get": {
+ "operationId": "AdminController_getLogStats",
+ "summary": "Get log statistics",
+ "parameters": [
+ {
+ "name": "startDate",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/export": {
+ "post": {
+ "operationId": "AdminController_exportLogs",
+ "summary": "Export logs",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "level",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ "FATAL"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "APPLICATION",
+ "ACCESS",
+ "ERROR",
+ "DATABASE",
+ "EMAIL",
+ "NOTIFICATION",
+ "AUDIT"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "userId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "startDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "minDuration",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 0,
+ "type": "number"
+ }
+ },
+ {
+ "name": "format",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/logs/cleanup": {
+ "post": {
+ "operationId": "AdminController_cleanupLogs",
+ "summary": "Cleanup old logs",
+ "parameters": [
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/system/health": {
+ "get": {
+ "operationId": "AdminController_getSystemHealth",
+ "summary": "Get system health status",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/system/info": {
+ "get": {
+ "operationId": "AdminController_getSystemInfo",
+ "summary": "Get system information",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/system/settings": {
+ "get": {
+ "operationId": "AdminController_getSettings",
+ "summary": "Get system settings",
+ "parameters": [
+ {
+ "name": "category",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "post": {
+ "operationId": "AdminController_createSetting",
+ "summary": "Create system setting",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateSystemSettingDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/system/settings/{key}": {
+ "get": {
+ "operationId": "AdminController_getSetting",
+ "summary": "Get specific setting",
+ "parameters": [
+ {
+ "name": "key",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "AdminController_updateSetting",
+ "summary": "Update system setting",
+ "parameters": [
+ {
+ "name": "key",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateSystemSettingDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "AdminController_deleteSetting",
+ "summary": "Delete system setting",
+ "parameters": [
+ {
+ "name": "key",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/maintenance": {
+ "get": {
+ "operationId": "AdminController_getMaintenanceStatus",
+ "summary": "Get maintenance mode status",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/maintenance/enable": {
+ "post": {
+ "operationId": "AdminController_enableMaintenance",
+ "summary": "Enable maintenance mode",
+ "parameters": [],
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/maintenance/disable": {
+ "post": {
+ "operationId": "AdminController_disableMaintenance",
+ "summary": "Disable maintenance mode",
+ "parameters": [],
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/announcements": {
+ "get": {
+ "operationId": "AdminController_getAnnouncements",
+ "summary": "Get all announcements",
+ "parameters": [
+ {
+ "name": "activeOnly",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "post": {
+ "operationId": "AdminController_createAnnouncement",
+ "summary": "Create announcement",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateAnnouncementDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/announcements/{id}": {
+ "put": {
+ "operationId": "AdminController_updateAnnouncement",
+ "summary": "Update announcement",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "AdminController_deleteAnnouncement",
+ "summary": "Delete announcement",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/announcements/{id}/toggle": {
+ "patch": {
+ "operationId": "AdminController_toggleAnnouncement",
+ "summary": "Toggle announcement active status",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users": {
+ "get": {
+ "operationId": "AdminController_getAllUsers",
+ "summary": "Get all users with filters",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users/{id}": {
+ "get": {
+ "operationId": "AdminController_getUserDetails",
+ "summary": "Get user details",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "AdminController_updateUser",
+ "summary": "Update user",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "AdminController_deleteUser",
+ "summary": "Delete user",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "hard",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users/{id}/activity": {
+ "get": {
+ "operationId": "AdminController_getUserActivity",
+ "summary": "Get user activity",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users/export": {
+ "post": {
+ "operationId": "AdminController_exportUsers",
+ "summary": "Export users",
+ "parameters": [
+ {
+ "name": "format",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users/import": {
+ "post": {
+ "operationId": "AdminController_importUsers",
+ "summary": "Bulk import users from CSV",
+ "parameters": [],
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/users/{id}/reset-password": {
+ "post": {
+ "operationId": "AdminController_resetUserPassword",
+ "summary": "Reset user password",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/audit/logs": {
+ "get": {
+ "operationId": "AdminController_getAuditLogs",
+ "summary": "Get audit logs",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/audit/users/{userId}": {
+ "get": {
+ "operationId": "AdminController_getUserAudit",
+ "summary": "Get user activity audit log",
+ "parameters": [
+ {
+ "name": "userId",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/audit/resource/{type}/{id}": {
+ "get": {
+ "operationId": "AdminController_getResourceHistory",
+ "summary": "Get resource change history",
+ "parameters": [
+ {
+ "name": "type",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/audit/stats": {
+ "get": {
+ "operationId": "AdminController_getAuditStats",
+ "summary": "Get audit statistics",
+ "parameters": [
+ {
+ "name": "startDate",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "endDate",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/overview": {
+ "get": {
+ "operationId": "AdminController_getPlatformOverview",
+ "summary": "Get platform overview",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/users/growth": {
+ "get": {
+ "operationId": "AdminController_getUserGrowth",
+ "summary": "Get user growth analytics",
+ "parameters": [
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/revenue": {
+ "get": {
+ "operationId": "AdminController_getRevenueAnalytics",
+ "summary": "Get revenue analytics",
+ "parameters": [
+ {
+ "name": "period",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/storage": {
+ "get": {
+ "operationId": "AdminController_getStorageAnalytics",
+ "summary": "Get storage analytics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/api-usage": {
+ "get": {
+ "operationId": "AdminController_getApiUsage",
+ "summary": "Get API usage statistics",
+ "parameters": [
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/analytics/error-rate": {
+ "get": {
+ "operationId": "AdminController_getErrorRate",
+ "summary": "Get error rate",
+ "parameters": [
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/failed-logins": {
+ "get": {
+ "operationId": "AdminController_getFailedLogins",
+ "summary": "Get failed login attempts",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/suspicious-activity": {
+ "get": {
+ "operationId": "AdminController_getSuspiciousActivity",
+ "summary": "Get suspicious activity",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/api-keys": {
+ "get": {
+ "operationId": "AdminController_getAllApiKeys",
+ "summary": "Get all API keys",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/api-keys/{id}/revoke": {
+ "patch": {
+ "operationId": "AdminController_revokeApiKey",
+ "summary": "Revoke API key",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/rate-limits": {
+ "get": {
+ "operationId": "AdminController_getRateLimitViolations",
+ "summary": "Get rate limit violations",
+ "parameters": [
+ {
+ "name": "days",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/security/sessions": {
+ "get": {
+ "operationId": "AdminController_getActiveSessions",
+ "summary": "Get active sessions",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-requests": {
+ "get": {
+ "operationId": "AdminController_getAllProformaRequests",
+ "summary": "Get all proforma requests (admin view)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "status",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DRAFT",
+ "OPEN",
+ "UNDER_REVIEW",
+ "REVISION_REQUESTED",
+ "CLOSED",
+ "CANCELLED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "category",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "EQUIPMENT",
+ "SERVICE",
+ "MIXED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "equipment",
+ "type": "string"
+ }
+ },
+ {
+ "name": "deadlineFrom",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-01-01T00:00:00Z",
+ "type": "string"
+ }
+ },
+ {
+ "name": "deadlineTo",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-12-31T23:59:59Z",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Object"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-requests/{id}": {
+ "get": {
+ "operationId": "AdminController_getProformaRequest",
+ "summary": "Get proforma request details (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-requests/{id}/submissions": {
+ "get": {
+ "operationId": "AdminController_getProformaRequestSubmissions",
+ "summary": "Get all submissions for a proforma request (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-submissions/{id}": {
+ "get": {
+ "operationId": "AdminController_getProformaSubmission",
+ "summary": "Get submission details (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-submissions/{id}/accept": {
+ "post": {
+ "operationId": "AdminController_acceptProformaSubmission",
+ "summary": "Accept a submission (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-submissions/{id}/reject": {
+ "post": {
+ "operationId": "AdminController_rejectProformaSubmission",
+ "summary": "Reject a submission (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/proforma-requests/{id}/comparison-data": {
+ "get": {
+ "operationId": "AdminController_getProformaComparisonData",
+ "summary": "Get comparison data for proforma request (admin)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ComparisonDataDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/bootstrap-admin": {
+ "post": {
+ "operationId": "AdminController_bootstrapAdmin",
+ "summary": "Bootstrap admin creation (No authentication required)",
+ "description": "Create initial admin users to bootstrap the system. This endpoint is only available when there are fewer than 2 admins in the system.\n \n**Bootstrap Rules:**\n- Maximum of 2 admins can be created through this endpoint\n- No authentication required for system initialization\n- Once 2 admins exist, this endpoint becomes unavailable\n- Email and phone number must be unique\n- Strong password requirements enforced\n\n**Password Requirements:**\n- Minimum 8 characters\n- Must contain uppercase letter\n- Must contain lowercase letter \n- Must contain number\n- Must contain special character (@$!%*?&)\n\n**Use Case:**\nThis endpoint is designed for initial system setup when no admins exist yet. After creating the first 2 admins, use the regular authenticated admin creation endpoint.",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateAdminDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Bootstrap admin successfully created",
+ "content": {
+ "application/json": {
+ "example": {
+ "admin": {
+ "id": "uuid-string",
+ "email": "admin@example.com",
+ "phone": "+1234567890",
+ "firstName": "John",
+ "lastName": "Doe",
+ "role": "ADMIN",
+ "isActive": true,
+ "createdAt": "2024-01-01T00:00:00.000Z"
+ },
+ "stats": {
+ "totalAdmins": 1,
+ "activeAdmins": 1,
+ "maxBootstrapAdmins": 2,
+ "remainingBootstrapSlots": 1,
+ "canCreateMore": true
+ },
+ "message": "Bootstrap admin successfully created"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Bootstrap limit reached or not available",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 403,
+ "message": "Bootstrap admin creation is no longer available. Maximum of 2 bootstrap admins already exist.",
+ "error": "Forbidden"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "User already exists",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 409,
+ "message": "User with this email already exists",
+ "error": "Conflict"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/create-admin": {
+ "post": {
+ "operationId": "AdminController_createAdmin",
+ "summary": "Create a new admin user",
+ "description": "Create a new admin user with limited slots available.\n \n**Admin Creation Rules:**\n- Maximum number of admins is configurable (default: 5)\n- Only existing admins can create new admin accounts\n- Email and phone number must be unique\n- Strong password requirements enforced\n- All admin creations are logged for audit purposes\n\n**Password Requirements:**\n- Minimum 8 characters\n- Must contain uppercase letter\n- Must contain lowercase letter \n- Must contain number\n- Must contain special character (@$!%*?&)\n\n**Response includes:**\n- Created admin details\n- Current admin statistics\n- Remaining admin slots available",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateAdminDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Admin successfully created",
+ "content": {
+ "application/json": {
+ "example": {
+ "admin": {
+ "id": "uuid-string",
+ "email": "admin@example.com",
+ "phone": "+1234567890",
+ "firstName": "John",
+ "lastName": "Doe",
+ "role": "ADMIN",
+ "isActive": true,
+ "createdAt": "2024-01-01T00:00:00.000Z"
+ },
+ "stats": {
+ "totalAdmins": 2,
+ "activeAdmins": 2,
+ "maxAdmins": 5,
+ "remainingSlots": 3,
+ "canCreateMore": true
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid input data",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 400,
+ "message": [
+ "Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character"
+ ],
+ "error": "Bad Request"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Maximum admin limit reached",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 403,
+ "message": "Maximum number of admins (5) has been reached. Cannot create more admin accounts.",
+ "error": "Forbidden"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "User already exists",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 409,
+ "message": "User with this email already exists",
+ "error": "Conflict"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/bootstrap-stats": {
+ "get": {
+ "operationId": "AdminController_getBootstrapStats",
+ "summary": "Get bootstrap admin statistics",
+ "description": "Get current bootstrap admin availability and limits (no authentication required)",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Bootstrap statistics retrieved successfully",
+ "content": {
+ "application/json": {
+ "example": {
+ "totalAdmins": 1,
+ "activeAdmins": 1,
+ "maxBootstrapAdmins": 2,
+ "remainingBootstrapSlots": 1,
+ "canCreateMore": true,
+ "bootstrapAvailable": true
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/admin-stats": {
+ "get": {
+ "operationId": "AdminController_getAdminStats",
+ "summary": "Get admin statistics",
+ "description": "Get current admin count, limits, and availability information",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Admin statistics retrieved successfully",
+ "content": {
+ "application/json": {
+ "example": {
+ "totalAdmins": 3,
+ "activeAdmins": 2,
+ "maxAdmins": 5,
+ "remainingSlots": 2,
+ "canCreateMore": true
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/admins": {
+ "get": {
+ "operationId": "AdminController_getAllAdmins",
+ "summary": "Get all admin users",
+ "description": "Get list of all admin users with their details and statistics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Admin list retrieved successfully",
+ "content": {
+ "application/json": {
+ "example": {
+ "admins": [
+ {
+ "id": "uuid-string",
+ "email": "admin1@example.com",
+ "phone": "+1234567890",
+ "firstName": "John",
+ "lastName": "Doe",
+ "role": "ADMIN",
+ "isActive": true,
+ "createdAt": "2024-01-01T00:00:00.000Z",
+ "updatedAt": "2024-01-01T00:00:00.000Z"
+ }
+ ],
+ "stats": {
+ "totalAdmins": 1,
+ "activeAdmins": 1,
+ "maxAdmins": 5,
+ "remainingSlots": 4,
+ "canCreateMore": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/admins/{id}/deactivate": {
+ "patch": {
+ "operationId": "AdminController_deactivateAdmin",
+ "summary": "Deactivate an admin user",
+ "description": "Deactivate an admin user account.\n \n**Deactivation Rules:**\n- Cannot deactivate the last active admin\n- Cannot deactivate your own admin account\n- Deactivation is logged for audit purposes",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Admin successfully deactivated",
+ "content": {
+ "application/json": {
+ "example": {
+ "id": "uuid-string",
+ "email": "admin@example.com",
+ "firstName": "John",
+ "lastName": "Doe",
+ "isActive": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Cannot deactivate admin",
+ "content": {
+ "application/json": {
+ "example": {
+ "statusCode": 400,
+ "message": "Cannot deactivate the last active admin",
+ "error": "Bad Request"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/admin/admins/{id}/reactivate": {
+ "patch": {
+ "operationId": "AdminController_reactivateAdmin",
+ "summary": "Reactivate an admin user",
+ "description": "Reactivate a previously deactivated admin user account",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Admin successfully reactivated",
+ "content": {
+ "application/json": {
+ "example": {
+ "id": "uuid-string",
+ "email": "admin@example.com",
+ "firstName": "John",
+ "lastName": "Doe",
+ "isActive": true
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Admin"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests": {
+ "post": {
+ "operationId": "ProformaCollectorController_createRequest",
+ "summary": "Create a new proforma request",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProformaRequestDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Proforma request created successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "ProformaCollectorController_listRequests",
+ "summary": "List all proforma requests (filtered)",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "default": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "maximum": 100,
+ "default": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "status",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "DRAFT",
+ "OPEN",
+ "UNDER_REVIEW",
+ "REVISION_REQUESTED",
+ "CLOSED",
+ "CANCELLED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "category",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "enum": [
+ "EQUIPMENT",
+ "SERVICE",
+ "MIXED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "equipment",
+ "type": "string"
+ }
+ },
+ {
+ "name": "deadlineFrom",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-01-01T00:00:00Z",
+ "type": "string"
+ }
+ },
+ {
+ "name": "deadlineTo",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "example": "2024-12-31T23:59:59Z",
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}": {
+ "get": {
+ "operationId": "ProformaCollectorController_getRequest",
+ "summary": "Get proforma request by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Request not found"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "ProformaCollectorController_updateRequest",
+ "summary": "Update proforma request",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateProformaRequestDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Request not found"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}/items": {
+ "post": {
+ "operationId": "ProformaCollectorController_addItem",
+ "summary": "Add item to proforma request",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "Item added successfully"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/items/{itemId}": {
+ "put": {
+ "operationId": "ProformaCollectorController_updateItem",
+ "summary": "Update proforma request item",
+ "parameters": [
+ {
+ "name": "itemId",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Item updated successfully"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}/submissions": {
+ "post": {
+ "operationId": "ProformaCollectorController_createSubmission",
+ "summary": "Submit pricing proposal for proforma request",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProformaSubmissionDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Submission created successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "ProformaCollectorController_listSubmissions",
+ "summary": "Get all submissions for a proforma request (requester only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/submissions/{id}": {
+ "get": {
+ "operationId": "ProformaCollectorController_getSubmission",
+ "summary": "Get submission by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Submission not found"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/submissions/{id}/revision-request": {
+ "post": {
+ "operationId": "ProformaCollectorController_requestRevision",
+ "summary": "Request revision for a submission (requester only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRevisionRequestDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Revision request created successfully"
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/submissions/{id}/revise": {
+ "post": {
+ "operationId": "ProformaCollectorController_reviseSubmission",
+ "summary": "Submit revised pricing (respondent only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProformaSubmissionDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Revised submission created successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaSubmissionResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}/comparison-data": {
+ "get": {
+ "operationId": "ProformaCollectorController_getComparisonData",
+ "summary": "Get comparison data for all submissions (requester only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Comparison data retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ComparisonDataDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}/close": {
+ "put": {
+ "operationId": "ProformaCollectorController_closeRequest",
+ "summary": "Close proforma request (requester or admin only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/proforma-requests/{id}/cancel": {
+ "put": {
+ "operationId": "ProformaCollectorController_cancelRequest",
+ "summary": "Cancel proforma request (requester or admin only)",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProformaRequestResponseDto"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Proforma Collector"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/declarations": {
+ "post": {
+ "operationId": "DeclarationController_create",
+ "summary": "Create a new declaration",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateDeclarationDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Declaration successfully created",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeclarationResponseDto"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Declaration number already exists"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "DeclarationController_findAll",
+ "summary": "Get all declarations with filtering and pagination",
+ "parameters": [
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "description": "Page number for pagination",
+ "schema": {
+ "default": 1,
+ "example": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "limit",
+ "required": false,
+ "in": "query",
+ "description": "Number of items per page",
+ "schema": {
+ "default": 10,
+ "example": 10,
+ "type": "number"
+ }
+ },
+ {
+ "name": "type",
+ "required": false,
+ "in": "query",
+ "description": "Filter by declaration type",
+ "schema": {
+ "example": "VAT",
+ "enum": [
+ "CUSTOMS",
+ "TAX",
+ "IMPORT",
+ "EXPORT",
+ "VAT",
+ "EXCISE",
+ "INCOME_TAX",
+ "BUSINESS_LICENSE",
+ "OTHER"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "status",
+ "required": false,
+ "in": "query",
+ "description": "Filter by declaration status",
+ "schema": {
+ "example": "PENDING_UPLOAD",
+ "enum": [
+ "PENDING_UPLOAD",
+ "UPLOADED",
+ "PROCESSING",
+ "PROCESSED",
+ "OVERDUE",
+ "REJECTED",
+ "ARCHIVED"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "period",
+ "required": false,
+ "in": "query",
+ "description": "Filter by declaration period",
+ "schema": {
+ "example": "MONTHLY",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "SEMI_ANNUAL",
+ "ANNUAL",
+ "ONE_TIME"
+ ],
+ "type": "string"
+ }
+ },
+ {
+ "name": "dueDateFrom",
+ "required": false,
+ "in": "query",
+ "description": "Filter by due date from",
+ "schema": {
+ "example": "2024-01-01T00:00:00.000Z",
+ "type": "string"
+ }
+ },
+ {
+ "name": "dueDateTo",
+ "required": false,
+ "in": "query",
+ "description": "Filter by due date to",
+ "schema": {
+ "example": "2024-12-31T23:59:59.999Z",
+ "type": "string"
+ }
+ },
+ {
+ "name": "isRecurring",
+ "required": false,
+ "in": "query",
+ "description": "Filter by recurring declarations",
+ "schema": {
+ "example": true,
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "isActive",
+ "required": false,
+ "in": "query",
+ "description": "Filter by active status",
+ "schema": {
+ "example": true,
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "overdue",
+ "required": false,
+ "in": "query",
+ "description": "Filter overdue declarations",
+ "schema": {
+ "example": true,
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "search",
+ "required": false,
+ "in": "query",
+ "description": "Search by declaration number or title",
+ "schema": {
+ "example": "VAT-2024",
+ "type": "string"
+ }
+ },
+ {
+ "name": "sortBy",
+ "required": false,
+ "in": "query",
+ "description": "Sort field",
+ "schema": {
+ "default": "createdAt",
+ "example": "dueDate",
+ "type": "string"
+ }
+ },
+ {
+ "name": "sortOrder",
+ "required": false,
+ "in": "query",
+ "description": "Sort order",
+ "schema": {
+ "default": "desc",
+ "example": "desc",
+ "enum": [
+ "asc",
+ "desc"
+ ],
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully received paginated list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/PaginatedDto"
+ },
+ {
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DeclarationResponseDto"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/declarations/stats": {
+ "get": {
+ "operationId": "DeclarationController_getStats",
+ "summary": "Get declaration statistics",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Declaration statistics retrieved successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "number"
+ },
+ "pending": {
+ "type": "number"
+ },
+ "uploaded": {
+ "type": "number"
+ },
+ "processed": {
+ "type": "number"
+ },
+ "overdue": {
+ "type": "number"
+ },
+ "upcomingDue": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/declarations/{id}": {
+ "get": {
+ "operationId": "DeclarationController_findOne",
+ "summary": "Get declaration by ID",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeclarationResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Declaration not found"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "put": {
+ "operationId": "DeclarationController_update",
+ "summary": "Update declaration",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateDeclarationDto"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeclarationResponseDto"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Declaration not found"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "delete": {
+ "operationId": "DeclarationController_delete",
+ "summary": "Delete declaration",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Declaration successfully deleted"
+ },
+ "403": {
+ "description": "Access denied"
+ },
+ "404": {
+ "description": "Declaration not found"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/declarations/{id}/upload": {
+ "post": {
+ "operationId": "DeclarationController_uploadFile",
+ "summary": "Upload declaration PDF file",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "description": "File uploaded successfully",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DeclarationUploadResponseDto"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid file or declaration not found"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/declarations/{id}/download": {
+ "get": {
+ "operationId": "DeclarationController_downloadFile",
+ "summary": "Download declaration PDF file",
+ "parameters": [
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "File downloaded successfully"
+ },
+ "404": {
+ "description": "Declaration or file not found"
+ }
+ },
+ "tags": [
+ "Declarations"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/api/v1/health": {
+ "get": {
+ "operationId": "HealthController_health",
+ "summary": "Health check endpoint (public)",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "Service is healthy"
+ }
+ },
+ "tags": [
+ "Health"
+ ]
+ }
+ }
+ },
+ "info": {
+ "title": "Yaltopia Invoice System API",
+ "description": "\n ## Enterprise-grade Invoice Management System API\n \n This API provides comprehensive invoice management capabilities including:\n \n ### Core Features\n - 🔐 **Authentication**: JWT-based authentication with refresh tokens\n - 📄 **Invoice Management**: Full CRUD operations with filtering and pagination\n - 📊 **Report Generation**: Monthly reports with PDF export\n - 🔗 **Secure Sharing**: Time-limited shareable links with email dispatch\n - 🔔 **PWA Notifications**: Push notifications for calendar reminders\n - 📰 **News Feed**: Integrated news and announcements system\n - 📁 **Document Storage**: Secure file upload/download with validation\n \n ### Quick Start\n 1. Register a new user account via `POST /auth/register`\n 2. Login to get access token via `POST /auth/login`\n 3. Use the access token in the Authorization header: `Bearer `\n 4. Explore the API endpoints below\n \n ### Authentication\n Most endpoints require authentication. Use the **Authorize** button below to set your bearer token.\n \n ### Rate Limiting\n API requests are rate-limited to 100 requests per minute per IP address.\n \n ### Error Handling\n All errors follow a consistent format with appropriate HTTP status codes.\n ",
+ "version": "1.0",
+ "contact": {}
+ },
+ "tags": [
+ {
+ "name": "Authentication",
+ "description": "User registration, login, and token management"
+ },
+ {
+ "name": "Users",
+ "description": "User profile and management"
+ },
+ {
+ "name": "Invoices",
+ "description": "Invoice CRUD operations with filtering"
+ },
+ {
+ "name": "Reports",
+ "description": "Monthly report generation and PDF export"
+ },
+ {
+ "name": "Share",
+ "description": "Secure invoice sharing with links and email"
+ },
+ {
+ "name": "Notifications",
+ "description": "PWA push notifications for reminders"
+ },
+ {
+ "name": "News",
+ "description": "News and announcements management"
+ },
+ {
+ "name": "Documents",
+ "description": "Secure document storage and management"
+ },
+ {
+ "name": "Proforma Collector",
+ "description": "Proforma request and submission management"
+ },
+ {
+ "name": "Admin",
+ "description": "Admin panel endpoints for system management"
+ }
+ ],
+ "servers": [
+ {
+ "url": "http://localhost:3001/api/v1",
+ "description": "Local Development"
+ },
+ {
+ "url": "https://api.yaltopia.com/api/v1",
+ "description": "Production"
+ }
+ ],
+ "components": {
+ "securitySchemes": {
+ "access-token": {
+ "scheme": "bearer",
+ "bearerFormat": "JWT",
+ "type": "http",
+ "name": "Authorization",
+ "description": "Enter your JWT token",
+ "in": "header"
+ }
+ },
+ "schemas": {
+ "RoleInfoDto": {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "BUSINESS_OWNER",
+ "EMPLOYEE",
+ "ACCOUNTANT",
+ "CUSTOMER_SERVICE",
+ "AUDITOR",
+ "VIEWER"
+ ],
+ "description": "Role identifier",
+ "example": "EMPLOYEE"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Human-readable role name",
+ "example": "Employee"
+ },
+ "description": {
+ "type": "string",
+ "description": "Role description",
+ "example": "Standard employee access for daily operations"
+ },
+ "permissions": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "user:create",
+ "user:read",
+ "user:update",
+ "user:delete",
+ "user:activate",
+ "user:deactivate",
+ "invoice:create",
+ "invoice:read",
+ "invoice:update",
+ "invoice:delete",
+ "invoice:approve",
+ "invoice:share",
+ "invoice:export",
+ "payment:create",
+ "payment:read",
+ "payment:update",
+ "payment:delete",
+ "payment:verify",
+ "payment:flag",
+ "company:read",
+ "company:update",
+ "company:settings",
+ "team:create",
+ "team:read",
+ "team:update",
+ "team:delete",
+ "team:invite",
+ "document:create",
+ "document:read",
+ "document:update",
+ "document:delete",
+ "document:share",
+ "report:create",
+ "report:read",
+ "report:delete",
+ "report:export",
+ "proforma:create",
+ "proforma:read",
+ "proforma:update",
+ "proforma:delete",
+ "proforma:approve",
+ "proforma_request:create",
+ "proforma_request:read",
+ "proforma_request:update",
+ "proforma_request:delete",
+ "proforma_request:approve",
+ "proforma_request:submit",
+ "dashboard:read",
+ "analytics:read",
+ "metrics:read",
+ "admin:logs",
+ "admin:system",
+ "admin:settings",
+ "admin:maintenance",
+ "admin:audit",
+ "admin:security",
+ "admin:users",
+ "admin:analytics",
+ "integration:read",
+ "integration:manage",
+ "api_key:create",
+ "api_key:delete",
+ "notification:send",
+ "notification:manage",
+ "news:create",
+ "news:read",
+ "news:update",
+ "news:delete",
+ "news:publish",
+ "scan:invoice",
+ "scan:payment",
+ "ocr:process",
+ "audit:read",
+ "audit:export",
+ "compliance:read"
+ ]
+ },
+ "description": "List of permissions granted to this role"
+ }
+ },
+ "required": [
+ "role",
+ "displayName",
+ "description",
+ "permissions"
+ ]
+ },
+ "ChangeUserRoleDto": {
+ "type": "object",
+ "properties": {
+ "newRole": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "BUSINESS_OWNER",
+ "EMPLOYEE",
+ "ACCOUNTANT",
+ "CUSTOMER_SERVICE",
+ "AUDITOR",
+ "VIEWER"
+ ],
+ "description": "New role to assign to the user",
+ "example": "EMPLOYEE"
+ },
+ "reason": {
+ "type": "string",
+ "description": "Reason for role change",
+ "example": "Promoted to team lead"
+ }
+ },
+ "required": [
+ "newRole"
+ ]
+ },
+ "UserResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "BUSINESS_OWNER",
+ "EMPLOYEE",
+ "ACCOUNTANT",
+ "CUSTOMER_SERVICE",
+ "AUDITOR",
+ "VIEWER"
+ ]
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "createdById": {
+ "type": "string",
+ "nullable": true
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "refreshToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "email",
+ "firstName",
+ "lastName",
+ "role",
+ "isActive",
+ "createdAt",
+ "updatedAt",
+ "password",
+ "refreshToken"
+ ]
+ },
+ "UpdateUserDto": {
+ "type": "object",
+ "properties": {
+ "firstName": {
+ "type": "string",
+ "minLength": 2,
+ "maxLength": 50
+ },
+ "lastName": {
+ "type": "string",
+ "minLength": 2,
+ "maxLength": 50
+ }
+ }
+ },
+ "RegisterDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "example": "john.doe@example.com",
+ "description": "User email address"
+ },
+ "phone": {
+ "type": "string",
+ "pattern": "/^\\+[1-9]\\d{1,14}$/",
+ "example": "+1234567890",
+ "description": "User phone number"
+ },
+ "password": {
+ "type": "string",
+ "minLength": 8,
+ "maxLength": 50,
+ "pattern": "/((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$/",
+ "example": "Password@123",
+ "description": "Password must contain uppercase, lowercase, and number/special character"
+ },
+ "firstName": {
+ "type": "string",
+ "minLength": 2,
+ "maxLength": 50,
+ "example": "John",
+ "description": "User first name"
+ },
+ "lastName": {
+ "type": "string",
+ "minLength": 2,
+ "maxLength": 50,
+ "example": "Doe",
+ "description": "User last name"
+ },
+ "role": {
+ "type": "string",
+ "example": "EMPLOYEE",
+ "enum": [
+ "ADMIN",
+ "BUSINESS_OWNER",
+ "EMPLOYEE",
+ "ACCOUNTANT",
+ "CUSTOMER_SERVICE",
+ "AUDITOR",
+ "VIEWER"
+ ],
+ "description": "User role (optional). Available roles:\n - VIEWER: Basic read-only access (no token required)\n - EMPLOYEE: Daily operations (Business Owner/Admin token required)\n - ACCOUNTANT: Financial management (Business Owner/Admin token required)\n - CUSTOMER_SERVICE: Customer support (Business Owner/Admin token required)\n - BUSINESS_OWNER: Business management (Admin token required)\n - ADMIN: Full system access (Admin token required)\n - AUDITOR: Compliance access (Admin token required)\n \n Defaults to VIEWER if not specified."
+ }
+ },
+ "required": [
+ "email",
+ "phone",
+ "password",
+ "firstName",
+ "lastName"
+ ]
+ },
+ "AuthResponseDto": {
+ "type": "object",
+ "properties": {
+ "accessToken": {
+ "type": "string"
+ },
+ "refreshToken": {
+ "type": "string"
+ },
+ "user": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "required": true,
+ "type": "string"
+ },
+ "email": {
+ "required": true,
+ "type": "string"
+ },
+ "firstName": {
+ "required": true,
+ "type": "string"
+ },
+ "lastName": {
+ "required": true,
+ "type": "string"
+ },
+ "role": {
+ "required": true,
+ "type": "object"
+ },
+ "avatar": {
+ "required": false,
+ "type": "string"
+ },
+ "provider": {
+ "required": false,
+ "type": "string"
+ }
+ }
+ }
+ },
+ "required": [
+ "accessToken",
+ "refreshToken",
+ "user"
+ ]
+ },
+ "LoginDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "example": "john.doe@example.com",
+ "description": "User email address (required if phone is not provided)"
+ },
+ "phone": {
+ "type": "string",
+ "pattern": "/^\\+[1-9]\\d{1,14}$/",
+ "example": "+1234567890",
+ "description": "User phone number (required if email is not provided)"
+ },
+ "password": {
+ "type": "string",
+ "example": "Password@123"
+ }
+ },
+ "required": [
+ "password"
+ ]
+ },
+ "RefreshTokenDto": {
+ "type": "object",
+ "properties": {
+ "refreshToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "refreshToken"
+ ]
+ },
+ "InvoiceItemDto": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string",
+ "example": "Web Development Service"
+ },
+ "quantity": {
+ "type": "number",
+ "minimum": 0,
+ "example": 10
+ },
+ "unitPrice": {
+ "type": "number",
+ "minimum": 0,
+ "example": 50
+ },
+ "total": {
+ "type": "number",
+ "minimum": 0,
+ "example": 500
+ }
+ },
+ "required": [
+ "description",
+ "quantity",
+ "unitPrice",
+ "total"
+ ]
+ },
+ "CreateInvoiceDto": {
+ "type": "object",
+ "properties": {
+ "invoiceNumber": {
+ "type": "string",
+ "example": "INV-2024-001"
+ },
+ "customerName": {
+ "type": "string",
+ "example": "Acme Corporation"
+ },
+ "customerEmail": {
+ "type": "string",
+ "example": "billing@acme.com"
+ },
+ "customerPhone": {
+ "type": "string",
+ "example": "+1234567890"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ],
+ "default": "SALES"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "DRAFT",
+ "PENDING",
+ "PAID",
+ "OVERDUE",
+ "CANCELLED"
+ ],
+ "default": "DRAFT"
+ },
+ "issueDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "dueDate": {
+ "type": "string",
+ "example": "2024-02-15T00:00:00Z"
+ },
+ "description": {
+ "type": "string",
+ "example": "Web development services for January 2024"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Payment terms: Net 30"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 150,
+ "default": 0
+ },
+ "discountAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 0,
+ "default": 0
+ },
+ "isScanned": {
+ "type": "boolean",
+ "example": false,
+ "default": false
+ },
+ "scannedData": {
+ "type": "object",
+ "example": {
+ "sellerTIN": "123456",
+ "items": []
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InvoiceItemDto"
+ }
+ }
+ },
+ "required": [
+ "invoiceNumber",
+ "customerName",
+ "amount",
+ "dueDate",
+ "items"
+ ]
+ },
+ "InvoiceItemResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "unitPrice": {
+ "type": "number"
+ },
+ "total": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "id",
+ "description",
+ "quantity",
+ "unitPrice",
+ "total"
+ ]
+ },
+ "InvoiceResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "invoiceNumber": {
+ "type": "string"
+ },
+ "customerName": {
+ "type": "string"
+ },
+ "customerEmail": {
+ "type": "string"
+ },
+ "customerPhone": {
+ "type": "string"
+ },
+ "amount": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "DRAFT",
+ "PENDING",
+ "PAID",
+ "OVERDUE",
+ "CANCELLED"
+ ]
+ },
+ "issueDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "dueDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "paidDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "notes": {
+ "type": "string"
+ },
+ "taxAmount": {
+ "type": "number"
+ },
+ "discountAmount": {
+ "type": "number"
+ },
+ "isScanned": {
+ "type": "boolean"
+ },
+ "scannedData": {
+ "type": "object"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InvoiceItemResponseDto"
+ }
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "invoiceNumber",
+ "customerName",
+ "amount",
+ "currency",
+ "type",
+ "status",
+ "issueDate",
+ "dueDate",
+ "taxAmount",
+ "discountAmount",
+ "userId",
+ "items",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "PaginationMetaDto": {
+ "type": "object",
+ "properties": {
+ "total": {
+ "type": "number"
+ },
+ "page": {
+ "type": "number"
+ },
+ "limit": {
+ "type": "number"
+ },
+ "totalPages": {
+ "type": "number"
+ },
+ "hasNextPage": {
+ "type": "boolean"
+ },
+ "hasPreviousPage": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "total",
+ "page",
+ "limit",
+ "totalPages",
+ "hasNextPage",
+ "hasPreviousPage"
+ ]
+ },
+ "PaginatedDto": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "type": "array"
+ }
+ },
+ "meta": {
+ "$ref": "#/components/schemas/PaginationMetaDto"
+ }
+ },
+ "required": [
+ "data",
+ "meta"
+ ]
+ },
+ "SendShareEmailDto": {
+ "type": "object",
+ "properties": {
+ "invoiceId": {
+ "type": "string",
+ "example": "123e4567-e89b-12d3-a456-426614174000"
+ },
+ "expiresAt": {
+ "type": "string",
+ "example": "2024-12-31T23:59:59Z"
+ },
+ "maxAccess": {
+ "type": "number",
+ "minimum": 1,
+ "example": 10
+ },
+ "recipientEmail": {
+ "type": "string",
+ "example": "client@example.com"
+ },
+ "message": {
+ "type": "string",
+ "example": "Please review this invoice"
+ }
+ },
+ "required": [
+ "invoiceId",
+ "expiresAt",
+ "recipientEmail"
+ ]
+ },
+ "ShareLinkResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "token": {
+ "type": "string"
+ },
+ "shareUrl": {
+ "type": "string"
+ },
+ "expiresAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "accessCount": {
+ "type": "number"
+ },
+ "maxAccess": {
+ "type": "number"
+ },
+ "invoiceId": {
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "token",
+ "shareUrl",
+ "expiresAt",
+ "isActive",
+ "accessCount",
+ "invoiceId",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "CreateShareLinkDto": {
+ "type": "object",
+ "properties": {
+ "invoiceId": {
+ "type": "string",
+ "example": "123e4567-e89b-12d3-a456-426614174000"
+ },
+ "expiresAt": {
+ "type": "string",
+ "example": "2024-12-31T23:59:59Z"
+ },
+ "maxAccess": {
+ "type": "number",
+ "minimum": 1,
+ "example": 10
+ }
+ },
+ "required": [
+ "invoiceId",
+ "expiresAt"
+ ]
+ },
+ "UpdateInvoiceDto": {
+ "type": "object",
+ "properties": {
+ "invoiceNumber": {
+ "type": "string",
+ "example": "INV-2024-001"
+ },
+ "customerName": {
+ "type": "string",
+ "example": "Acme Corporation"
+ },
+ "customerEmail": {
+ "type": "string",
+ "example": "billing@acme.com"
+ },
+ "customerPhone": {
+ "type": "string",
+ "example": "+1234567890"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ],
+ "default": "SALES"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "DRAFT",
+ "PENDING",
+ "PAID",
+ "OVERDUE",
+ "CANCELLED"
+ ],
+ "default": "DRAFT"
+ },
+ "issueDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "dueDate": {
+ "type": "string",
+ "example": "2024-02-15T00:00:00Z"
+ },
+ "description": {
+ "type": "string",
+ "example": "Web development services for January 2024"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Payment terms: Net 30"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 150,
+ "default": 0
+ },
+ "discountAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 0,
+ "default": 0
+ },
+ "isScanned": {
+ "type": "boolean",
+ "example": false,
+ "default": false
+ },
+ "scannedData": {
+ "type": "object",
+ "example": {
+ "sellerTIN": "123456",
+ "items": []
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InvoiceItemDto"
+ }
+ }
+ }
+ },
+ "GenerateReportDto": {
+ "type": "object",
+ "properties": {
+ "year": {
+ "type": "number",
+ "minimum": 2000,
+ "maximum": 2100,
+ "example": 2024
+ },
+ "month": {
+ "type": "number",
+ "minimum": 1,
+ "maximum": 12,
+ "example": 1
+ },
+ "quarter": {
+ "type": "number",
+ "minimum": 1,
+ "maximum": 4,
+ "example": 1
+ },
+ "periodType": {
+ "type": "string",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "ANNUAL"
+ ],
+ "default": "MONTHLY"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ],
+ "default": "SALES"
+ }
+ },
+ "required": [
+ "year"
+ ]
+ },
+ "ReportResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "month": {
+ "type": "number"
+ },
+ "quarter": {
+ "type": "number"
+ },
+ "year": {
+ "type": "number"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "SALES",
+ "PURCHASE"
+ ]
+ },
+ "periodType": {
+ "type": "string",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "ANNUAL"
+ ]
+ },
+ "totalInvoices": {
+ "type": "number"
+ },
+ "totalAmount": {
+ "type": "number"
+ },
+ "paidAmount": {
+ "type": "number"
+ },
+ "pendingAmount": {
+ "type": "number"
+ },
+ "overdueAmount": {
+ "type": "number"
+ },
+ "pdfPath": {
+ "type": "string"
+ },
+ "generatedAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "year",
+ "type",
+ "periodType",
+ "totalInvoices",
+ "totalAmount",
+ "paidAmount",
+ "pendingAmount",
+ "overdueAmount",
+ "generatedAt",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "SubscribeDto": {
+ "type": "object",
+ "properties": {
+ "endpoint": {
+ "type": "string",
+ "example": "https://fcm.googleapis.com/fcm/send/..."
+ },
+ "keys": {
+ "type": "object",
+ "properties": {
+ "p256dh": {
+ "required": true,
+ "type": "string"
+ },
+ "auth": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "deviceInfo": {
+ "type": "string",
+ "example": "Chrome on Windows"
+ }
+ },
+ "required": [
+ "endpoint",
+ "keys"
+ ]
+ },
+ "SendNotificationDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "example": "Invoice Due Reminder"
+ },
+ "body": {
+ "type": "string",
+ "example": "Your invoice #INV-001 is due tomorrow"
+ },
+ "icon": {
+ "type": "string",
+ "example": "/assets/icon.png"
+ },
+ "url": {
+ "type": "string",
+ "example": "/invoices/123"
+ },
+ "recipientId": {
+ "type": "string",
+ "example": "user-id-here"
+ },
+ "scheduledFor": {
+ "type": "string",
+ "example": "2024-12-31T10:00:00Z"
+ },
+ "data": {
+ "type": "object",
+ "example": {
+ "invoiceId": "123"
+ }
+ }
+ },
+ "required": [
+ "title",
+ "body",
+ "recipientId"
+ ]
+ },
+ "NotificationResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "body": {
+ "type": "string"
+ },
+ "icon": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "sentAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "scheduledFor": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "isSent": {
+ "type": "boolean"
+ },
+ "recipientId": {
+ "type": "string"
+ },
+ "data": {
+ "type": "object"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "body",
+ "isSent",
+ "recipientId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "UpdateNotificationSettingsDto": {
+ "type": "object",
+ "properties": {
+ "invoiceReminders": {
+ "type": "boolean",
+ "default": true
+ },
+ "daysBeforeDueDate": {
+ "type": "number",
+ "minimum": 1,
+ "maximum": 30,
+ "example": 7
+ },
+ "newsAlerts": {
+ "type": "boolean",
+ "default": true
+ },
+ "reportReady": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "NewsResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "content": {
+ "type": "string"
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "ANNOUNCEMENT",
+ "UPDATE",
+ "MAINTENANCE",
+ "NEWS"
+ ]
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "LOW",
+ "MEDIUM",
+ "HIGH"
+ ]
+ },
+ "publishedAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "isPublished": {
+ "type": "boolean"
+ },
+ "viewCount": {
+ "type": "number"
+ },
+ "isRead": {
+ "type": "boolean"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "content",
+ "category",
+ "priority",
+ "publishedAt",
+ "isPublished",
+ "viewCount",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "CreateNewsDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "News title"
+ },
+ "content": {
+ "type": "string",
+ "description": "News content"
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "ANNOUNCEMENT",
+ "UPDATE",
+ "MAINTENANCE",
+ "NEWS"
+ ],
+ "description": "News category"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "LOW",
+ "MEDIUM",
+ "HIGH"
+ ],
+ "description": "News priority"
+ },
+ "publishedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Publication date"
+ },
+ "isPublished": {
+ "type": "boolean",
+ "description": "Whether the news is published"
+ }
+ },
+ "required": [
+ "title",
+ "content"
+ ]
+ },
+ "UpdateNewsDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "News title"
+ },
+ "content": {
+ "type": "string",
+ "description": "News content"
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "ANNOUNCEMENT",
+ "UPDATE",
+ "MAINTENANCE",
+ "NEWS"
+ ],
+ "description": "News category"
+ },
+ "priority": {
+ "type": "string",
+ "enum": [
+ "LOW",
+ "MEDIUM",
+ "HIGH"
+ ],
+ "description": "News priority"
+ },
+ "publishedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Publication date"
+ },
+ "isPublished": {
+ "type": "boolean",
+ "description": "Whether the news is published"
+ }
+ }
+ },
+ "DocumentResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "filename": {
+ "type": "string"
+ },
+ "originalName": {
+ "type": "string"
+ },
+ "mimeType": {
+ "type": "string"
+ },
+ "size": {
+ "type": "number"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "PDF",
+ "EXCEL",
+ "IMAGE",
+ "OTHER"
+ ]
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "INVOICE",
+ "REPORT",
+ "CONTRACT",
+ "OTHER"
+ ]
+ },
+ "path": {
+ "type": "string"
+ },
+ "previewUrl": {
+ "type": "string"
+ },
+ "isPublic": {
+ "type": "boolean"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "invoiceId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "filename",
+ "originalName",
+ "mimeType",
+ "size",
+ "type",
+ "category",
+ "path",
+ "isPublic",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "ProformaItemDto": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string",
+ "example": "Web Development Service"
+ },
+ "quantity": {
+ "type": "number",
+ "minimum": 0,
+ "example": 10
+ },
+ "unitPrice": {
+ "type": "number",
+ "minimum": 0,
+ "example": 50
+ },
+ "total": {
+ "type": "number",
+ "minimum": 0,
+ "example": 500
+ }
+ },
+ "required": [
+ "description",
+ "quantity",
+ "unitPrice",
+ "total"
+ ]
+ },
+ "CreateProformaDto": {
+ "type": "object",
+ "properties": {
+ "proformaNumber": {
+ "type": "string",
+ "example": "PROF-2024-001"
+ },
+ "customerName": {
+ "type": "string",
+ "example": "Acme Corporation"
+ },
+ "customerEmail": {
+ "type": "string",
+ "example": "billing@acme.com"
+ },
+ "customerPhone": {
+ "type": "string",
+ "example": "+1234567890"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "issueDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "dueDate": {
+ "type": "string",
+ "example": "2024-02-15T00:00:00Z"
+ },
+ "description": {
+ "type": "string",
+ "example": "Web development services for January 2024"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Payment terms: Net 30"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 150,
+ "default": 0
+ },
+ "discountAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 0,
+ "default": 0
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaItemDto"
+ }
+ }
+ },
+ "required": [
+ "proformaNumber",
+ "customerName",
+ "amount",
+ "dueDate",
+ "items"
+ ]
+ },
+ "ProformaItemResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "unitPrice": {
+ "type": "number"
+ },
+ "total": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "id",
+ "description",
+ "quantity",
+ "unitPrice",
+ "total"
+ ]
+ },
+ "ProformaResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "proformaNumber": {
+ "type": "string"
+ },
+ "customerName": {
+ "type": "string"
+ },
+ "customerEmail": {
+ "type": "string"
+ },
+ "customerPhone": {
+ "type": "string"
+ },
+ "amount": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "issueDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "dueDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "notes": {
+ "type": "string"
+ },
+ "taxAmount": {
+ "type": "number"
+ },
+ "discountAmount": {
+ "type": "number"
+ },
+ "pdfPath": {
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaItemResponseDto"
+ }
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "proformaNumber",
+ "customerName",
+ "amount",
+ "currency",
+ "issueDate",
+ "dueDate",
+ "taxAmount",
+ "discountAmount",
+ "userId",
+ "items",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "UpdateProformaDto": {
+ "type": "object",
+ "properties": {
+ "proformaNumber": {
+ "type": "string",
+ "example": "PROF-2024-001"
+ },
+ "customerName": {
+ "type": "string",
+ "example": "Acme Corporation"
+ },
+ "customerEmail": {
+ "type": "string",
+ "example": "billing@acme.com"
+ },
+ "customerPhone": {
+ "type": "string",
+ "example": "+1234567890"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "issueDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "dueDate": {
+ "type": "string",
+ "example": "2024-02-15T00:00:00Z"
+ },
+ "description": {
+ "type": "string",
+ "example": "Web development services for January 2024"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Payment terms: Net 30"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 150,
+ "default": 0
+ },
+ "discountAmount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 0,
+ "default": 0
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaItemDto"
+ }
+ }
+ }
+ },
+ "CreatePaymentDto": {
+ "type": "object",
+ "properties": {
+ "transactionId": {
+ "type": "string",
+ "example": "TXN-2024-001"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "paymentDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "paymentMethod": {
+ "type": "string",
+ "example": "Credit Card"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Invoice payment"
+ },
+ "invoiceId": {
+ "type": "string",
+ "example": "invoice-123-id"
+ }
+ },
+ "required": [
+ "transactionId",
+ "amount"
+ ]
+ },
+ "PaymentResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "transactionId": {
+ "type": "string"
+ },
+ "amount": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "paymentDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "paymentMethod": {
+ "type": "string"
+ },
+ "notes": {
+ "type": "string"
+ },
+ "isFlagged": {
+ "type": "boolean"
+ },
+ "flagReason": {
+ "type": "string",
+ "enum": [
+ "FAKE",
+ "SCAM",
+ "OTHER"
+ ]
+ },
+ "flagNotes": {
+ "type": "string"
+ },
+ "receiptPath": {
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "invoiceId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "transactionId",
+ "amount",
+ "currency",
+ "paymentDate",
+ "isFlagged",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "UpdatePaymentDto": {
+ "type": "object",
+ "properties": {
+ "transactionId": {
+ "type": "string",
+ "example": "TXN-2024-001"
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0,
+ "example": 1500
+ },
+ "currency": {
+ "type": "string",
+ "example": "USD",
+ "default": "USD"
+ },
+ "paymentDate": {
+ "type": "string",
+ "example": "2024-01-15T00:00:00Z"
+ },
+ "paymentMethod": {
+ "type": "string",
+ "example": "Credit Card"
+ },
+ "notes": {
+ "type": "string",
+ "example": "Invoice payment"
+ },
+ "invoiceId": {
+ "type": "string",
+ "example": "invoice-123-id"
+ }
+ }
+ },
+ "FlagPaymentDto": {
+ "type": "object",
+ "properties": {
+ "flagReason": {
+ "type": "string",
+ "enum": [
+ "FAKE",
+ "SCAM",
+ "OTHER"
+ ]
+ },
+ "flagNotes": {
+ "type": "string",
+ "example": "Additional notes about the flag"
+ }
+ },
+ "required": [
+ "flagReason"
+ ]
+ },
+ "AssociatePaymentDto": {
+ "type": "object",
+ "properties": {
+ "invoiceId": {
+ "type": "string",
+ "example": "invoice-123-id"
+ }
+ },
+ "required": [
+ "invoiceId"
+ ]
+ },
+ "DashboardMetricsDto": {
+ "type": "object",
+ "properties": {
+ "totalInvoices": {
+ "type": "number"
+ },
+ "totalRevenue": {
+ "type": "number"
+ },
+ "totalPayments": {
+ "type": "number"
+ },
+ "pendingInvoices": {
+ "type": "number"
+ },
+ "overdueInvoices": {
+ "type": "number"
+ },
+ "paidInvoices": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "totalInvoices",
+ "totalRevenue",
+ "totalPayments",
+ "pendingInvoices",
+ "overdueInvoices",
+ "paidInvoices"
+ ]
+ },
+ "CompanyResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "tin": {
+ "type": "string"
+ },
+ "address": {
+ "type": "string"
+ },
+ "city": {
+ "type": "string"
+ },
+ "state": {
+ "type": "string"
+ },
+ "zipCode": {
+ "type": "string"
+ },
+ "country": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "website": {
+ "type": "string"
+ },
+ "logoPath": {
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "UpdateCompanyDto": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "example": "Yaltopia Inc."
+ },
+ "tin": {
+ "type": "string",
+ "example": "123456789"
+ },
+ "address": {
+ "type": "string",
+ "example": "123 Main Street"
+ },
+ "city": {
+ "type": "string",
+ "example": "New York"
+ },
+ "state": {
+ "type": "string",
+ "example": "NY"
+ },
+ "zipCode": {
+ "type": "string",
+ "example": "10001"
+ },
+ "country": {
+ "type": "string",
+ "example": "USA"
+ },
+ "phone": {
+ "type": "string",
+ "example": "+1234567890"
+ },
+ "email": {
+ "type": "string",
+ "example": "contact@yaltopia.com"
+ },
+ "website": {
+ "type": "string",
+ "example": "https://yaltopia.com"
+ }
+ }
+ },
+ "TeamMemberResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "MEMBER",
+ "VIEWER"
+ ]
+ },
+ "avatar": {
+ "type": "string"
+ },
+ "isInvited": {
+ "type": "boolean"
+ },
+ "invitedAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "joinedAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "email",
+ "firstName",
+ "lastName",
+ "role",
+ "isInvited",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "CreateTeamMemberDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "example": "john.doe@example.com"
+ },
+ "firstName": {
+ "type": "string",
+ "example": "John"
+ },
+ "lastName": {
+ "type": "string",
+ "example": "Doe"
+ },
+ "role": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "MEMBER",
+ "VIEWER"
+ ],
+ "default": "MEMBER"
+ }
+ },
+ "required": [
+ "email",
+ "firstName",
+ "lastName"
+ ]
+ },
+ "UpdateTeamMemberDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "example": "john.doe@example.com"
+ },
+ "firstName": {
+ "type": "string",
+ "example": "John"
+ },
+ "lastName": {
+ "type": "string",
+ "example": "Doe"
+ },
+ "role": {
+ "type": "string",
+ "enum": [
+ "ADMIN",
+ "MEMBER",
+ "VIEWER"
+ ],
+ "default": "MEMBER"
+ }
+ }
+ },
+ "InviteTeamMemberDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "example": "john.doe@example.com"
+ },
+ "firstName": {
+ "type": "string",
+ "example": "John"
+ },
+ "lastName": {
+ "type": "string",
+ "example": "Doe"
+ }
+ },
+ "required": [
+ "email",
+ "firstName",
+ "lastName"
+ ]
+ },
+ "ApiKeyResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "key": {
+ "type": "string"
+ },
+ "lastUsed": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "isActive": {
+ "type": "boolean"
+ },
+ "userId": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "key",
+ "isActive",
+ "userId",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "CreateApiKeyDto": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "example": "My API Key"
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "ScanInvoiceItemDto": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "unitPrice": {
+ "type": "number"
+ },
+ "total": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "description",
+ "quantity",
+ "unitPrice",
+ "total"
+ ]
+ },
+ "ScanInvoiceDataDto": {
+ "type": "object",
+ "properties": {
+ "sellerTIN": {
+ "type": "string"
+ },
+ "sellerName": {
+ "type": "string"
+ },
+ "invoiceNumber": {
+ "type": "string"
+ },
+ "issueDate": {
+ "type": "string"
+ },
+ "dueDate": {
+ "type": "string"
+ },
+ "totalAmount": {
+ "type": "number"
+ },
+ "taxAmount": {
+ "type": "number"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ScanInvoiceItemDto"
+ }
+ },
+ "customerName": {
+ "type": "string"
+ },
+ "customerEmail": {
+ "type": "string"
+ }
+ }
+ },
+ "ScanInvoiceResponseDto": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "invoiceId": {
+ "type": "string"
+ },
+ "imagePath": {
+ "type": "string"
+ },
+ "data": {
+ "$ref": "#/components/schemas/ScanInvoiceDataDto"
+ },
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "success"
+ ]
+ },
+ "MatchedInvoiceDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "invoiceNumber": {
+ "type": "string"
+ },
+ "amount": {
+ "type": "number"
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "invoiceNumber",
+ "amount",
+ "status"
+ ]
+ },
+ "ScanPaymentResponseDto": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "paymentId": {
+ "type": "string"
+ },
+ "imagePath": {
+ "type": "string"
+ },
+ "matchedInvoice": {
+ "$ref": "#/components/schemas/MatchedInvoiceDto"
+ },
+ "data": {
+ "type": "object",
+ "properties": {
+ "transactionId": {
+ "required": false,
+ "type": "string"
+ },
+ "amount": {
+ "required": false,
+ "type": "number"
+ },
+ "paymentDate": {
+ "required": false,
+ "type": "string"
+ },
+ "paymentMethod": {
+ "required": false,
+ "type": "string"
+ },
+ "merchantName": {
+ "required": false,
+ "type": "string"
+ },
+ "referenceNumber": {
+ "required": false,
+ "type": "string"
+ },
+ "provider": {
+ "required": false,
+ "type": "string"
+ },
+ "senderName": {
+ "required": false,
+ "type": "string"
+ },
+ "senderPhone": {
+ "required": false,
+ "type": "string"
+ }
+ }
+ },
+ "verification": {
+ "type": "object",
+ "properties": {
+ "isVerified": {
+ "required": false,
+ "type": "boolean"
+ },
+ "provider": {
+ "required": false,
+ "type": "string"
+ },
+ "verificationStatus": {
+ "required": false,
+ "type": "string"
+ },
+ "error": {
+ "required": false,
+ "type": "string"
+ }
+ }
+ },
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "success",
+ "data",
+ "verification"
+ ]
+ },
+ "Object": {
+ "type": "object",
+ "properties": {}
+ },
+ "CreateSystemSettingDto": {
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "isPublic": {
+ "type": "boolean"
+ },
+ "key": {
+ "type": "string"
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "GENERAL",
+ "EMAIL",
+ "STORAGE",
+ "PAYMENT",
+ "SECURITY",
+ "FEATURES",
+ "API"
+ ]
+ }
+ },
+ "required": [
+ "value",
+ "key",
+ "category"
+ ]
+ },
+ "UpdateSystemSettingDto": {
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "isPublic": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "value"
+ ]
+ },
+ "CreateAnnouncementDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string",
+ "default": "info"
+ },
+ "priority": {
+ "type": "number",
+ "minimum": 0,
+ "default": 0
+ },
+ "targetAudience": {
+ "type": "string",
+ "default": "all"
+ },
+ "startsAt": {
+ "type": "string"
+ },
+ "endsAt": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "message"
+ ]
+ },
+ "ProformaRequestItemResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "itemName": {
+ "type": "string"
+ },
+ "itemDescription": {
+ "type": "string"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "unitOfMeasure": {
+ "type": "string"
+ },
+ "technicalSpecifications": {
+ "type": "object"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "itemName",
+ "quantity",
+ "unitOfMeasure",
+ "createdAt"
+ ]
+ },
+ "ProformaRequestResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "requesterId": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "category": {
+ "type": "string",
+ "enum": [
+ "EQUIPMENT",
+ "SERVICE",
+ "MIXED"
+ ]
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "DRAFT",
+ "OPEN",
+ "UNDER_REVIEW",
+ "REVISION_REQUESTED",
+ "CLOSED",
+ "CANCELLED"
+ ]
+ },
+ "submissionDeadline": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "allowRevisions": {
+ "type": "boolean"
+ },
+ "paymentTerms": {
+ "type": "string"
+ },
+ "incoterms": {
+ "type": "string"
+ },
+ "taxIncluded": {
+ "type": "boolean"
+ },
+ "discountStructure": {
+ "type": "string"
+ },
+ "validityPeriod": {
+ "type": "number"
+ },
+ "attachments": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaRequestItemResponseDto"
+ }
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "requesterId",
+ "title",
+ "category",
+ "status",
+ "allowRevisions",
+ "taxIncluded",
+ "items",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "ProformaSubmissionItemResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "proformaRequestItemId": {
+ "type": "string"
+ },
+ "unitPrice": {
+ "type": "number"
+ },
+ "totalPrice": {
+ "type": "number"
+ },
+ "deliveryTime": {
+ "type": "number"
+ },
+ "warrantyOrServiceTerms": {
+ "type": "string"
+ },
+ "remarks": {
+ "type": "string"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "proformaRequestItemId",
+ "unitPrice",
+ "totalPrice",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "ProformaSubmissionResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "proformaRequestId": {
+ "type": "string"
+ },
+ "respondentId": {
+ "type": "string"
+ },
+ "respondentName": {
+ "type": "string"
+ },
+ "version": {
+ "type": "number"
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "SUBMITTED",
+ "REVISION_REQUESTED",
+ "REVISED",
+ "REJECTED",
+ "ACCEPTED"
+ ]
+ },
+ "totalPrice": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "notes": {
+ "type": "string"
+ },
+ "autoBusinessSnapshot": {
+ "type": "object"
+ },
+ "autoLicenseSnapshot": {
+ "type": "object"
+ },
+ "paymentTerms": {
+ "type": "string"
+ },
+ "incoterms": {
+ "type": "string"
+ },
+ "taxIncluded": {
+ "type": "boolean"
+ },
+ "discountStructure": {
+ "type": "string"
+ },
+ "validityPeriod": {
+ "type": "number"
+ },
+ "attachments": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "submissionItems": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProformaSubmissionItemResponseDto"
+ }
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "proformaRequestId",
+ "respondentId",
+ "version",
+ "status",
+ "totalPrice",
+ "currency",
+ "autoBusinessSnapshot",
+ "taxIncluded",
+ "submissionItems",
+ "createdAt",
+ "updatedAt"
+ ]
+ },
+ "ComparisonDataItemDto": {
+ "type": "object",
+ "properties": {
+ "itemId": {
+ "type": "string"
+ },
+ "itemName": {
+ "type": "string"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "unitOfMeasure": {
+ "type": "string"
+ },
+ "submissions": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ }
+ },
+ "required": [
+ "itemId",
+ "itemName",
+ "quantity",
+ "unitOfMeasure",
+ "submissions"
+ ]
+ },
+ "ComparisonDataDto": {
+ "type": "object",
+ "properties": {
+ "proformaRequestId": {
+ "type": "string"
+ },
+ "requestTitle": {
+ "type": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ComparisonDataItemDto"
+ }
+ },
+ "summary": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ }
+ },
+ "required": [
+ "proformaRequestId",
+ "requestTitle",
+ "items",
+ "summary"
+ ]
+ },
+ "CreateAdminDto": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "description": "Admin email address",
+ "example": "admin@example.com"
+ },
+ "phone": {
+ "type": "string",
+ "description": "Admin phone number",
+ "example": "+1234567890"
+ },
+ "password": {
+ "type": "string",
+ "minLength": 8,
+ "pattern": "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]/",
+ "description": "Admin password (minimum 8 characters, must contain uppercase, lowercase, number, and special character)",
+ "example": "AdminPass@123"
+ },
+ "firstName": {
+ "type": "string",
+ "description": "Admin first name",
+ "example": "John"
+ },
+ "lastName": {
+ "type": "string",
+ "description": "Admin last name",
+ "example": "Doe"
+ },
+ "notes": {
+ "type": "string",
+ "description": "Optional notes about the admin",
+ "example": "System administrator"
+ }
+ },
+ "required": [
+ "email",
+ "phone",
+ "password",
+ "firstName",
+ "lastName"
+ ]
+ },
+ "CreateProformaRequestItemDto": {
+ "type": "object",
+ "properties": {
+ "itemName": {
+ "type": "string",
+ "example": "Laptop Computer"
+ },
+ "itemDescription": {
+ "type": "string",
+ "example": "High-performance laptop for development"
+ },
+ "quantity": {
+ "type": "number",
+ "default": 1,
+ "minimum": 0,
+ "example": 10
+ },
+ "unitOfMeasure": {
+ "type": "string",
+ "default": "unit",
+ "example": "unit"
+ },
+ "technicalSpecifications": {
+ "type": "object",
+ "example": {
+ "processor": "Intel i7",
+ "ram": "16GB",
+ "storage": "512GB SSD"
+ }
+ }
+ },
+ "required": [
+ "itemName"
+ ]
+ },
+ "CreateProformaRequestDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "example": "Office Equipment Procurement 2024"
+ },
+ "description": {
+ "type": "string",
+ "example": "Request for quotation for office equipment"
+ },
+ "category": {
+ "type": "string",
+ "default": "MIXED",
+ "enum": [
+ "EQUIPMENT",
+ "SERVICE",
+ "MIXED"
+ ]
+ },
+ "submissionDeadline": {
+ "type": "string",
+ "example": "2024-12-31T23:59:59Z"
+ },
+ "allowRevisions": {
+ "type": "boolean",
+ "default": true,
+ "example": true
+ },
+ "paymentTerms": {
+ "type": "string",
+ "example": "Net 30 days"
+ },
+ "incoterms": {
+ "type": "string",
+ "example": "EXW"
+ },
+ "taxIncluded": {
+ "type": "boolean",
+ "default": false,
+ "example": false
+ },
+ "discountStructure": {
+ "type": "string",
+ "example": "5% discount for orders > 100 units"
+ },
+ "validityPeriod": {
+ "type": "number",
+ "minimum": 1,
+ "example": 30,
+ "description": "Validity period in days"
+ },
+ "attachments": {
+ "example": [
+ {
+ "name": "spec.pdf",
+ "url": "/uploads/spec.pdf"
+ }
+ ],
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CreateProformaRequestItemDto"
+ }
+ }
+ },
+ "required": [
+ "title",
+ "items"
+ ]
+ },
+ "UpdateProformaRequestDto": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "example": "Office Equipment Procurement 2024"
+ },
+ "description": {
+ "type": "string",
+ "example": "Request for quotation for office equipment"
+ },
+ "category": {
+ "type": "string",
+ "default": "MIXED",
+ "enum": [
+ "EQUIPMENT",
+ "SERVICE",
+ "MIXED"
+ ]
+ },
+ "submissionDeadline": {
+ "type": "string",
+ "example": "2024-12-31T23:59:59Z"
+ },
+ "allowRevisions": {
+ "type": "boolean",
+ "default": true,
+ "example": true
+ },
+ "paymentTerms": {
+ "type": "string",
+ "example": "Net 30 days"
+ },
+ "incoterms": {
+ "type": "string",
+ "example": "EXW"
+ },
+ "taxIncluded": {
+ "type": "boolean",
+ "default": false,
+ "example": false
+ },
+ "discountStructure": {
+ "type": "string",
+ "example": "5% discount for orders > 100 units"
+ },
+ "validityPeriod": {
+ "type": "number",
+ "minimum": 1,
+ "example": 30,
+ "description": "Validity period in days"
+ },
+ "attachments": {
+ "example": [
+ {
+ "name": "spec.pdf",
+ "url": "/uploads/spec.pdf"
+ }
+ ],
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CreateProformaRequestItemDto"
+ }
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "DRAFT",
+ "OPEN",
+ "UNDER_REVIEW",
+ "REVISION_REQUESTED",
+ "CLOSED",
+ "CANCELLED"
+ ]
+ }
+ }
+ },
+ "CreateProformaSubmissionItemDto": {
+ "type": "object",
+ "properties": {
+ "proformaRequestItemId": {
+ "type": "string",
+ "example": "item-id-123"
+ },
+ "unitPrice": {
+ "type": "number",
+ "minimum": 0,
+ "example": 999.99
+ },
+ "totalPrice": {
+ "type": "number",
+ "minimum": 0,
+ "example": 9999.99
+ },
+ "deliveryTime": {
+ "type": "number",
+ "minimum": 0,
+ "example": 30,
+ "description": "Delivery time in days"
+ },
+ "warrantyOrServiceTerms": {
+ "type": "string",
+ "example": "1 year warranty, on-site service"
+ },
+ "remarks": {
+ "type": "string",
+ "example": "Bulk pricing available for orders > 50 units"
+ }
+ },
+ "required": [
+ "proformaRequestItemId",
+ "unitPrice",
+ "totalPrice"
+ ]
+ },
+ "CreateProformaSubmissionDto": {
+ "type": "object",
+ "properties": {
+ "totalPrice": {
+ "type": "number",
+ "minimum": 0,
+ "example": 12500.5
+ },
+ "currency": {
+ "type": "string",
+ "default": "USD",
+ "example": "USD"
+ },
+ "notes": {
+ "type": "string",
+ "example": "All items in stock, ready for immediate shipment"
+ },
+ "paymentTerms": {
+ "type": "string",
+ "example": "Net 30 days"
+ },
+ "incoterms": {
+ "type": "string",
+ "example": "EXW"
+ },
+ "taxIncluded": {
+ "type": "boolean",
+ "default": false,
+ "example": false
+ },
+ "discountStructure": {
+ "type": "string",
+ "example": "5% early payment discount"
+ },
+ "validityPeriod": {
+ "type": "number",
+ "minimum": 1,
+ "example": 30,
+ "description": "Validity period in days"
+ },
+ "attachments": {
+ "example": [
+ {
+ "name": "quote.pdf",
+ "url": "/uploads/quote.pdf"
+ }
+ ],
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CreateProformaSubmissionItemDto"
+ }
+ }
+ },
+ "required": [
+ "totalPrice",
+ "items"
+ ]
+ },
+ "CreateRevisionRequestDto": {
+ "type": "object",
+ "properties": {
+ "revisionReason": {
+ "type": "string",
+ "example": "Please review pricing for item #3 and provide better delivery terms"
+ },
+ "requestedChanges": {
+ "type": "object",
+ "example": {
+ "items": [
+ {
+ "itemId": "item-123",
+ "requestedChanges": "Reduce price by 10%"
+ },
+ {
+ "itemId": "item-456",
+ "requestedChanges": "Improve delivery time from 30 to 15 days"
+ }
+ ]
+ }
+ }
+ },
+ "required": [
+ "revisionReason"
+ ]
+ },
+ "CreateDeclarationDto": {
+ "type": "object",
+ "properties": {
+ "declarationNumber": {
+ "type": "string",
+ "description": "Declaration number (must be unique)",
+ "example": "DECL-2024-001"
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of declaration",
+ "enum": [
+ "CUSTOMS",
+ "TAX",
+ "IMPORT",
+ "EXPORT",
+ "VAT",
+ "EXCISE",
+ "INCOME_TAX",
+ "BUSINESS_LICENSE",
+ "OTHER"
+ ],
+ "example": "VAT"
+ },
+ "period": {
+ "type": "string",
+ "description": "Declaration period",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "SEMI_ANNUAL",
+ "ANNUAL",
+ "ONE_TIME"
+ ],
+ "example": "MONTHLY"
+ },
+ "title": {
+ "type": "string",
+ "description": "Declaration title",
+ "example": "VAT Declaration - January 2024"
+ },
+ "description": {
+ "type": "string",
+ "description": "Declaration description",
+ "example": "Monthly VAT declaration for business operations"
+ },
+ "dueDate": {
+ "type": "string",
+ "description": "Due date for declaration submission",
+ "example": "2024-02-15T00:00:00.000Z"
+ },
+ "totalValue": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Total value of the declaration",
+ "example": 50000
+ },
+ "currency": {
+ "type": "string",
+ "description": "Currency code",
+ "example": "USD",
+ "default": "USD"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Tax amount",
+ "example": 5000
+ },
+ "dutyAmount": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Duty amount",
+ "example": 1000
+ },
+ "notes": {
+ "type": "string",
+ "description": "Additional notes",
+ "example": "Special considerations for this declaration"
+ },
+ "customsOffice": {
+ "type": "string",
+ "description": "Customs office",
+ "example": "Main Customs Office"
+ },
+ "referenceNumber": {
+ "type": "string",
+ "description": "Reference number",
+ "example": "REF-2024-001"
+ },
+ "isRecurring": {
+ "type": "boolean",
+ "description": "Whether this is a recurring declaration",
+ "example": true,
+ "default": false
+ },
+ "nextDueDate": {
+ "type": "string",
+ "description": "Next due date for recurring declarations",
+ "example": "2024-03-15T00:00:00.000Z"
+ }
+ },
+ "required": [
+ "declarationNumber",
+ "type",
+ "period",
+ "title",
+ "dueDate"
+ ]
+ },
+ "DeclarationResponseDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Declaration ID",
+ "example": "123e4567-e89b-12d3-a456-426614174000"
+ },
+ "declarationNumber": {
+ "type": "string",
+ "description": "Declaration number",
+ "example": "DECL-2024-001"
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of declaration",
+ "enum": [
+ "CUSTOMS",
+ "TAX",
+ "IMPORT",
+ "EXPORT",
+ "VAT",
+ "EXCISE",
+ "INCOME_TAX",
+ "BUSINESS_LICENSE",
+ "OTHER"
+ ],
+ "example": "VAT"
+ },
+ "status": {
+ "type": "string",
+ "description": "Declaration status",
+ "enum": [
+ "PENDING_UPLOAD",
+ "UPLOADED",
+ "PROCESSING",
+ "PROCESSED",
+ "OVERDUE",
+ "REJECTED",
+ "ARCHIVED"
+ ],
+ "example": "PENDING_UPLOAD"
+ },
+ "period": {
+ "type": "string",
+ "description": "Declaration period",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "SEMI_ANNUAL",
+ "ANNUAL",
+ "ONE_TIME"
+ ],
+ "example": "MONTHLY"
+ },
+ "title": {
+ "type": "string",
+ "description": "Declaration title",
+ "example": "VAT Declaration - January 2024"
+ },
+ "description": {
+ "type": "string",
+ "description": "Declaration description",
+ "example": "Monthly VAT declaration for business operations"
+ },
+ "filePath": {
+ "type": "string",
+ "description": "File path of uploaded declaration",
+ "example": "/uploads/declarations/decl-2024-001.pdf"
+ },
+ "fileName": {
+ "type": "string",
+ "description": "Original file name",
+ "example": "vat-declaration-jan-2024.pdf"
+ },
+ "fileSize": {
+ "type": "number",
+ "description": "File size in bytes",
+ "example": 1024000
+ },
+ "uploadedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Upload timestamp",
+ "example": "2024-01-15T10:30:00.000Z"
+ },
+ "dueDate": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Due date for declaration submission",
+ "example": "2024-02-15T00:00:00.000Z"
+ },
+ "reminderSentAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Reminder sent timestamp",
+ "example": "2024-02-10T09:00:00.000Z"
+ },
+ "overdueNotifiedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Overdue notification timestamp",
+ "example": "2024-02-16T09:00:00.000Z"
+ },
+ "processedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Processing completion timestamp",
+ "example": "2024-01-15T11:00:00.000Z"
+ },
+ "extractedData": {
+ "type": "object",
+ "description": "OCR extracted data",
+ "example": {
+ "totalAmount": 50000,
+ "taxAmount": 5000
+ }
+ },
+ "processingNotes": {
+ "type": "string",
+ "description": "Processing notes",
+ "example": "Successfully processed with high confidence"
+ },
+ "totalValue": {
+ "type": "number",
+ "description": "Total value of the declaration",
+ "example": 50000
+ },
+ "currency": {
+ "type": "string",
+ "description": "Currency code",
+ "example": "USD"
+ },
+ "taxAmount": {
+ "type": "number",
+ "description": "Tax amount",
+ "example": 5000
+ },
+ "dutyAmount": {
+ "type": "number",
+ "description": "Duty amount",
+ "example": 1000
+ },
+ "notes": {
+ "type": "string",
+ "description": "Additional notes",
+ "example": "Special considerations for this declaration"
+ },
+ "customsOffice": {
+ "type": "string",
+ "description": "Customs office",
+ "example": "Main Customs Office"
+ },
+ "referenceNumber": {
+ "type": "string",
+ "description": "Reference number",
+ "example": "REF-2024-001"
+ },
+ "isRecurring": {
+ "type": "boolean",
+ "description": "Whether this is a recurring declaration",
+ "example": true
+ },
+ "nextDueDate": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Next due date for recurring declarations",
+ "example": "2024-03-15T00:00:00.000Z"
+ },
+ "isActive": {
+ "type": "boolean",
+ "description": "Whether the declaration is active",
+ "example": true
+ },
+ "userId": {
+ "type": "string",
+ "description": "User ID who owns this declaration",
+ "example": "123e4567-e89b-12d3-a456-426614174000"
+ },
+ "createdAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Creation timestamp",
+ "example": "2024-01-01T00:00:00.000Z"
+ },
+ "updatedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Last update timestamp",
+ "example": "2024-01-15T10:30:00.000Z"
+ },
+ "daysUntilDue": {
+ "type": "number",
+ "description": "Days until due date (negative if overdue)",
+ "example": 5
+ },
+ "isOverdue": {
+ "type": "boolean",
+ "description": "Whether the declaration is overdue",
+ "example": false
+ }
+ },
+ "required": [
+ "id",
+ "declarationNumber",
+ "type",
+ "status",
+ "period",
+ "title",
+ "dueDate",
+ "currency",
+ "taxAmount",
+ "dutyAmount",
+ "isRecurring",
+ "isActive",
+ "userId",
+ "createdAt",
+ "updatedAt",
+ "daysUntilDue",
+ "isOverdue"
+ ]
+ },
+ "UpdateDeclarationDto": {
+ "type": "object",
+ "properties": {
+ "declarationNumber": {
+ "type": "string",
+ "description": "Declaration number (must be unique)",
+ "example": "DECL-2024-001"
+ },
+ "type": {
+ "type": "string",
+ "description": "Type of declaration",
+ "enum": [
+ "CUSTOMS",
+ "TAX",
+ "IMPORT",
+ "EXPORT",
+ "VAT",
+ "EXCISE",
+ "INCOME_TAX",
+ "BUSINESS_LICENSE",
+ "OTHER"
+ ],
+ "example": "VAT"
+ },
+ "period": {
+ "type": "string",
+ "description": "Declaration period",
+ "enum": [
+ "MONTHLY",
+ "QUARTERLY",
+ "SEMI_ANNUAL",
+ "ANNUAL",
+ "ONE_TIME"
+ ],
+ "example": "MONTHLY"
+ },
+ "title": {
+ "type": "string",
+ "description": "Declaration title",
+ "example": "VAT Declaration - January 2024"
+ },
+ "description": {
+ "type": "string",
+ "description": "Declaration description",
+ "example": "Monthly VAT declaration for business operations"
+ },
+ "dueDate": {
+ "type": "string",
+ "description": "Due date for declaration submission",
+ "example": "2024-02-15T00:00:00.000Z"
+ },
+ "totalValue": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Total value of the declaration",
+ "example": 50000
+ },
+ "currency": {
+ "type": "string",
+ "description": "Currency code",
+ "example": "USD",
+ "default": "USD"
+ },
+ "taxAmount": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Tax amount",
+ "example": 5000
+ },
+ "dutyAmount": {
+ "type": "number",
+ "minimum": 0,
+ "description": "Duty amount",
+ "example": 1000
+ },
+ "notes": {
+ "type": "string",
+ "description": "Additional notes",
+ "example": "Special considerations for this declaration"
+ },
+ "customsOffice": {
+ "type": "string",
+ "description": "Customs office",
+ "example": "Main Customs Office"
+ },
+ "referenceNumber": {
+ "type": "string",
+ "description": "Reference number",
+ "example": "REF-2024-001"
+ },
+ "isRecurring": {
+ "type": "boolean",
+ "description": "Whether this is a recurring declaration",
+ "example": true,
+ "default": false
+ },
+ "nextDueDate": {
+ "type": "string",
+ "description": "Next due date for recurring declarations",
+ "example": "2024-03-15T00:00:00.000Z"
+ }
+ }
+ },
+ "DeclarationUploadResponseDto": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "description": "Upload success status",
+ "example": true
+ },
+ "filePath": {
+ "type": "string",
+ "description": "File path where the declaration is stored",
+ "example": "uploads/declarations/123e4567-e89b-12d3-a456-426614174000.pdf"
+ },
+ "fileName": {
+ "type": "string",
+ "description": "Original file name",
+ "example": "vat-declaration-jan-2024.pdf"
+ },
+ "fileSize": {
+ "type": "number",
+ "description": "File size in bytes",
+ "example": 1024000
+ },
+ "uploadedAt": {
+ "format": "date-time",
+ "type": "string",
+ "description": "Upload timestamp",
+ "example": "2024-01-15T10:30:00.000Z"
+ },
+ "message": {
+ "type": "string",
+ "description": "Success message",
+ "example": "Declaration file uploaded successfully"
+ }
+ },
+ "required": [
+ "success",
+ "filePath",
+ "fileName",
+ "fileSize",
+ "uploadedAt",
+ "message"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file