feat(convex): add implementation rules and configuration for backend functions
- Introduced a comprehensive markdown document outlining implementation rules for Convex functions, including syntax, registration, HTTP endpoints, and TypeScript usage. - Created a new configuration file for the Convex app, integrating the Resend service. - Added a new HTTP route for handling Shippo webhooks to ensure proper response handling. - Implemented integration tests for order timeline events, covering various scenarios including order fulfillment and status changes. - Enhanced existing functions with type safety improvements and additional validation logic. This commit establishes clear guidelines for backend development and improves the overall structure and reliability of the Convex application.
This commit is contained in:
@@ -1,6 +1,24 @@
|
||||
import { QueryCtx } from "../_generated/server";
|
||||
import { QueryCtx, MutationCtx } from "../_generated/server";
|
||||
import { Id, Doc } from "../_generated/dataModel";
|
||||
|
||||
export async function recordOrderTimelineEvent(
|
||||
ctx: MutationCtx,
|
||||
args: {
|
||||
orderId: Id<"orders">;
|
||||
eventType: string;
|
||||
source: string;
|
||||
fromStatus?: string;
|
||||
toStatus?: string;
|
||||
payload?: string;
|
||||
userId?: Id<"users">;
|
||||
},
|
||||
): Promise<void> {
|
||||
await ctx.db.insert("orderTimelineEvents", {
|
||||
...args,
|
||||
createdAt: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getOrderWithItems(
|
||||
ctx: QueryCtx,
|
||||
orderId: Id<"orders">,
|
||||
@@ -48,6 +66,37 @@ export function canCustomerCancel(order: Doc<"orders">): {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a customer is allowed to request a return for a given order.
|
||||
*
|
||||
* Eligibility: order must be `delivered` (customer has received the goods),
|
||||
* return not yet requested, and not already refunded.
|
||||
* Returns and cancellations are separate flows — cancellation is only available
|
||||
* on `confirmed` orders (before fulfilment begins).
|
||||
*/
|
||||
export function canCustomerRequestReturn(order: Doc<"orders">): {
|
||||
allowed: boolean;
|
||||
reason?: string;
|
||||
} {
|
||||
if (order.status !== "delivered") {
|
||||
return {
|
||||
allowed: false,
|
||||
reason:
|
||||
"Returns are only available for delivered orders.",
|
||||
};
|
||||
}
|
||||
if (order.returnRequestedAt) {
|
||||
return {
|
||||
allowed: false,
|
||||
reason: "A return has already been requested for this order.",
|
||||
};
|
||||
}
|
||||
if (order.paymentStatus === "refunded") {
|
||||
return { allowed: false, reason: "This order has already been refunded." };
|
||||
}
|
||||
return { allowed: true };
|
||||
}
|
||||
|
||||
export interface OutOfStockItem {
|
||||
variantId: Id<"productVariants">;
|
||||
requested: number;
|
||||
|
||||
Reference in New Issue
Block a user