Refactor OrderFulfillmentController for improved readability and consistency
- Consolidated import statements for better clarity. - Streamlined API operation and parameter definitions for enhanced readability. - Cleaned up response schemas and error handling for consistency across API responses. - Improved logging messages for better context during order fulfillment requests.
This commit is contained in:
parent
98f998db51
commit
bb6593c9a3
@ -1,13 +1,4 @@
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
Param,
|
||||
Body,
|
||||
Headers,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
UseGuards,
|
||||
} from "@nestjs/common";
|
||||
import { Controller, Post, Param, Body, Headers, HttpCode, HttpStatus, UseGuards } from "@nestjs/common";
|
||||
import { ApiTags, ApiOperation, ApiParam, ApiResponse, ApiHeader } from "@nestjs/swagger";
|
||||
import { ThrottlerGuard } from "@nestjs/throttler";
|
||||
import { Logger } from "nestjs-pino";
|
||||
@ -30,38 +21,37 @@ export class OrderFulfillmentController {
|
||||
@UseGuards(ThrottlerGuard, EnhancedWebhookSignatureGuard)
|
||||
@ApiOperation({
|
||||
summary: "Fulfill order from Salesforce",
|
||||
description:
|
||||
"Secure endpoint called by Salesforce Quick Action to fulfill orders in WHMCS. Handles complete flow: SF Order → WHMCS AddOrder/AcceptOrder → SF Status Update",
|
||||
description: "Secure endpoint called by Salesforce Quick Action to fulfill orders in WHMCS. Handles complete flow: SF Order → WHMCS AddOrder/AcceptOrder → SF Status Update"
|
||||
})
|
||||
@ApiParam({
|
||||
name: "sfOrderId",
|
||||
type: String,
|
||||
description: "Salesforce Order ID to provision",
|
||||
example: "8014x000000ABCDXYZ",
|
||||
example: "8014x000000ABCDXYZ"
|
||||
})
|
||||
@ApiHeader({
|
||||
name: "X-SF-Signature",
|
||||
description: "HMAC-SHA256 signature of request body using shared secret",
|
||||
required: true,
|
||||
example: "a1b2c3d4e5f6...",
|
||||
example: "a1b2c3d4e5f6..."
|
||||
})
|
||||
@ApiHeader({
|
||||
name: "X-SF-Timestamp",
|
||||
description: "ISO timestamp of request (max 5 minutes old)",
|
||||
required: true,
|
||||
example: "2024-01-15T10:30:00Z",
|
||||
example: "2024-01-15T10:30:00Z"
|
||||
})
|
||||
@ApiHeader({
|
||||
name: "X-SF-Nonce",
|
||||
description: "Unique nonce to prevent replay attacks",
|
||||
required: true,
|
||||
example: "abc123def456",
|
||||
example: "abc123def456"
|
||||
})
|
||||
@ApiHeader({
|
||||
name: "Idempotency-Key",
|
||||
description: "Unique key for safe retries",
|
||||
required: true,
|
||||
example: "provision_8014x000000ABCDXYZ_1705312200000",
|
||||
example: "provision_8014x000000ABCDXYZ_1705312200000"
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@ -70,16 +60,12 @@ export class OrderFulfillmentController {
|
||||
type: "object",
|
||||
properties: {
|
||||
success: { type: "boolean", example: true },
|
||||
status: {
|
||||
type: "string",
|
||||
enum: ["Provisioned", "Already Provisioned"],
|
||||
example: "Provisioned",
|
||||
},
|
||||
status: { type: "string", enum: ["Provisioned", "Already Provisioned"], example: "Provisioned" },
|
||||
whmcsOrderId: { type: "string", example: "12345" },
|
||||
whmcsServiceIds: { type: "array", items: { type: "number" }, example: [67890, 67891] },
|
||||
message: { type: "string", example: "Order provisioned successfully in WHMCS" },
|
||||
},
|
||||
},
|
||||
message: { type: "string", example: "Order provisioned successfully in WHMCS" }
|
||||
}
|
||||
}
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 400,
|
||||
@ -90,13 +76,13 @@ export class OrderFulfillmentController {
|
||||
success: { type: "boolean", example: false },
|
||||
status: { type: "string", example: "Failed" },
|
||||
message: { type: "string", example: "Salesforce order not found" },
|
||||
errorCode: { type: "string", example: "ORDER_NOT_FOUND" },
|
||||
},
|
||||
},
|
||||
errorCode: { type: "string", example: "ORDER_NOT_FOUND" }
|
||||
}
|
||||
}
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 401,
|
||||
description: "Invalid signature or authentication",
|
||||
description: "Invalid signature or authentication"
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 409,
|
||||
@ -106,20 +92,17 @@ export class OrderFulfillmentController {
|
||||
properties: {
|
||||
success: { type: "boolean", example: false },
|
||||
status: { type: "string", example: "Failed" },
|
||||
message: {
|
||||
type: "string",
|
||||
example: "Payment method missing - client must add payment method before provisioning",
|
||||
},
|
||||
errorCode: { type: "string", example: "PAYMENT_METHOD_MISSING" },
|
||||
},
|
||||
},
|
||||
message: { type: "string", example: "Payment method missing - client must add payment method before provisioning" },
|
||||
errorCode: { type: "string", example: "PAYMENT_METHOD_MISSING" }
|
||||
}
|
||||
}
|
||||
})
|
||||
async fulfillOrder(
|
||||
@Param("sfOrderId") sfOrderId: string,
|
||||
@Body() payload: OrderFulfillmentRequest,
|
||||
@Headers("idempotency-key") idempotencyKey: string
|
||||
) {
|
||||
this.logger.log("Salesforce fulfillment request received", {
|
||||
this.logger.log("Salesforce order fulfillment request received", {
|
||||
sfOrderId,
|
||||
idempotencyKey,
|
||||
timestamp: payload.timestamp,
|
||||
@ -150,6 +133,7 @@ export class OrderFulfillmentController {
|
||||
...(result.errorCode && { errorCode: result.errorCode }),
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error("Salesforce provisioning failed", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user