Files
my2/server/api/orders/[id].get.ts
Bastian Masanek 527379a2cd Enhance checkout flow with new components and validation
- Added AddressForm and CheckoutForm components for user input during checkout.
- Implemented validation using Zod and VeeValidate for billing address fields.
- Created OrderSummary and MockPayPalButton components for order confirmation and payment simulation.
- Updated CartSheet and CartSidebar to navigate to the new checkout page at '/kasse'.
- Introduced new API endpoints for validating checkout data and creating orders.
- Enhanced user experience with responsive design and error handling.

These changes complete the checkout functionality, allowing users to enter billing information, simulate payment, and confirm orders.
2025-11-03 15:38:16 +01:00

90 lines
2.0 KiB
TypeScript

/**
* GET /api/orders/[id]
*
* Fetch order details by ID
*
* Security:
* - Requires authentication
* - Users can only access their own orders
*
* Response:
* {
* id: string
* orderNumber: string
* totalAmount: string
* status: string
* billingAddress: BillingAddress
* items: OrderItem[]
* createdAt: Date
* }
*/
import { eq, and } from 'drizzle-orm'
import { orders, orderItems } from '../../database/schema'
export default defineEventHandler(async (event) => {
// Require authentication
const { user } = await requireUserSession(event)
// Get order ID from URL parameter
const orderId = getRouterParam(event, 'id')
if (!orderId) {
throw createError({
statusCode: 400,
statusMessage: 'Order ID is required',
})
}
const db = useDatabase()
// Fetch order with items
const order = await db.query.orders.findFirst({
where: and(eq(orders.id, orderId), eq(orders.userId, user.id)),
with: {
items: {
with: {
product: true,
},
},
},
})
if (!order) {
throw createError({
statusCode: 404,
statusMessage: 'Order not found',
})
}
// Transform items to include price and product snapshot data
const transformedItems = order.items.map((item: any) => ({
id: item.id,
orderId: item.orderId,
productId: item.productId,
quantity: item.quantity,
priceSnapshot: item.priceSnapshot,
productSnapshot: item.productSnapshot,
product: {
id: item.product.id,
name: item.product.name,
description: item.product.description,
imageUrl: item.product.imageUrl,
},
subtotal: Number.parseFloat(item.priceSnapshot) * item.quantity,
}))
return {
id: order.id,
orderNumber: order.orderNumber,
totalAmount: order.totalAmount,
status: order.status,
billingAddress: order.billingAddress,
items: transformedItems,
paymentId: order.paymentId,
paymentCompletedAt: order.paymentCompletedAt,
createdAt: order.createdAt,
updatedAt: order.updatedAt,
}
})