Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/api/admin/ama/bookings/[bookingId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ import {
getAmaAdminServices,
ownerRequestAuthenticator,
} from '~/lib/ama/admin/server'
import { kickAmaOperations } from '~/lib/ama/booking/server'

export const maxDuration = 60

export async function POST(
request: Request,
{ params }: { params: Promise<{ bookingId: string }> },
) {
const { bookingId } = await params
const { bookingAdmin, security, baseUrl } = getAmaAdminServices()
return createAdminBookingActionHandler({
const response = await createAdminBookingActionHandler({
authenticator: ownerRequestAuthenticator,
service: bookingAdmin,
security,
baseUrl,
})(request, bookingId)
if (response.ok) kickAmaOperations()
return response
}
7 changes: 6 additions & 1 deletion app/api/admin/ama/operations/[operationId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ import {
getAmaAdminServices,
ownerRequestAuthenticator,
} from '~/lib/ama/admin/server'
import { kickAmaOperations } from '~/lib/ama/booking/server'

export const maxDuration = 60

export async function POST(
request: Request,
{ params }: { params: Promise<{ operationId: string }> },
) {
const { operationId } = await params
const { bookingAdmin, security, baseUrl } = getAmaAdminServices()
return createAdminOperationActionHandler({
const response = await createAdminOperationActionHandler({
authenticator: ownerRequestAuthenticator,
service: bookingAdmin,
security,
baseUrl,
})(request, operationId)
if (response.ok) kickAmaOperations()
return response
}
14 changes: 12 additions & 2 deletions app/api/ama/manage/[token]/cancel/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { createManageCancelHandler } from '~/lib/ama/booking/http'
import { getAmaBookingServices } from '~/lib/ama/booking/server'
import {
getAmaBookingServices,
kickAmaOperations,
} from '~/lib/ama/booking/server'
import { protectAmaLaunchBoundary } from '~/lib/ama/security/launch-boundary-server'

export const maxDuration = 60

export async function POST(
request: Request,
{ params }: { params: Promise<{ token: string }> },
Expand All @@ -13,5 +18,10 @@ export async function POST(
if (blocked) return blocked
const { token } = await params
const { manage, guard } = getAmaBookingServices()
return createManageCancelHandler({ manage, guard })(request, token)
const response = await createManageCancelHandler({ manage, guard })(
request,
token,
)
if (response.ok) kickAmaOperations()
return response
}
14 changes: 12 additions & 2 deletions app/api/ama/manage/[token]/reschedule/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { createManageRescheduleHandler } from '~/lib/ama/booking/http'
import { getAmaBookingServices } from '~/lib/ama/booking/server'
import {
getAmaBookingServices,
kickAmaOperations,
} from '~/lib/ama/booking/server'
import { protectAmaLaunchBoundary } from '~/lib/ama/security/launch-boundary-server'

export const maxDuration = 60

export async function POST(
request: Request,
{ params }: { params: Promise<{ token: string }> },
Expand All @@ -13,5 +18,10 @@ export async function POST(
if (blocked) return blocked
const { token } = await params
const { manage, guard } = getAmaBookingServices()
return createManageRescheduleHandler({ manage, guard })(request, token)
const response = await createManageRescheduleHandler({ manage, guard })(
request,
token,
)
if (response.ok) kickAmaOperations()
return response
}
11 changes: 9 additions & 2 deletions app/api/ama/stripe/webhook/route.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { createStripeWebhookHandler, json } from '~/lib/ama/booking/http'
import { getAmaBookingServices } from '~/lib/ama/booking/server'
import {
getAmaBookingServices,
kickAmaOperations,
} from '~/lib/ama/booking/server'
import { protectAmaLaunchBoundary } from '~/lib/ama/security/launch-boundary-server'

export const maxDuration = 60

export async function POST(request: Request) {
const blocked = protectAmaLaunchBoundary(request, ['payments'])
if (blocked) return blocked
const { booking, stripeWebhookSecret } = getAmaBookingServices()
if (!stripeWebhookSecret) return json(503, { error: 'feature_disabled' })
return createStripeWebhookHandler({
const response = await createStripeWebhookHandler({
service: booking,
signingSecret: stripeWebhookSecret,
})(request)
if (response.ok) kickAmaOperations()
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Outdated
return response
}
18 changes: 18 additions & 0 deletions lib/ama/booking/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'server-only'

import { waitUntil } from '@vercel/functions'

import { createRateLimiter } from '~/lib/rate-limit/server'

import { availabilityRepository } from '../availability/repository'
Expand Down Expand Up @@ -227,3 +229,19 @@ export function getAmaBookingServices() {
services ??= createServices()
return services
}

/**
* Starts a background drain of due durable operations inside the current
* invocation, so work enqueued by a mutation (booking emails, Finalizing
* Booking recovery, refunds) begins immediately instead of waiting for the
* next scheduled sweep. The scheduled endpoint remains the sole driver for
* reminders, retry backoff, and expired Slot Hold release.
*/
export function kickAmaOperations() {
const { runner } = getAmaBookingServices()
waitUntil(
runner.run().catch((error) => {
console.error('ama: inline operations drain failed', error)
}),
)
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
4 changes: 2 additions & 2 deletions vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"crons": [
{
"path": "/api/internal/media/reconcile",
"schedule": "*/15 * * * *"
"schedule": "0 * * * *"
},
{
"path": "/api/internal/ama/work",
"schedule": "*/5 * * * *"
"schedule": "*/30 * * * *"
}
]
}