mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 15:44:02 +00:00
feat(finance): add billing correction APIs and cycle rollover
This commit is contained in:
@@ -46,12 +46,17 @@ import {
|
||||
createMiniAppUpsertUtilityCategoryHandler
|
||||
} from './miniapp-admin'
|
||||
import {
|
||||
createMiniAppAddPaymentHandler,
|
||||
createMiniAppAddUtilityBillHandler,
|
||||
createMiniAppBillingCycleHandler,
|
||||
createMiniAppCloseCycleHandler,
|
||||
createMiniAppDeletePaymentHandler,
|
||||
createMiniAppDeletePurchaseHandler,
|
||||
createMiniAppDeleteUtilityBillHandler,
|
||||
createMiniAppOpenCycleHandler,
|
||||
createMiniAppRentUpdateHandler,
|
||||
createMiniAppUpdatePaymentHandler,
|
||||
createMiniAppUpdatePurchaseHandler,
|
||||
createMiniAppUpdateUtilityBillHandler
|
||||
} from './miniapp-billing'
|
||||
import { createMiniAppLocalePreferenceHandler } from './miniapp-locale'
|
||||
@@ -268,6 +273,9 @@ const reminderJobs = runtime.reminderJobsEnabled
|
||||
return createReminderJobsHandler({
|
||||
listReminderTargets: () =>
|
||||
householdConfigurationRepositoryClient!.repository.listReminderTargets(),
|
||||
ensureBillingCycle: async ({ householdId, at }) => {
|
||||
await financeServiceForHousehold(householdId).ensureExpectedCycle(at)
|
||||
},
|
||||
releaseReminderDispatch: (input) =>
|
||||
reminderRepositoryClient.repository.releaseReminderDispatch(input),
|
||||
sendReminderMessage: async (target, text) => {
|
||||
@@ -483,6 +491,51 @@ const server = createBotWebhookServer({
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppUpdatePurchase: householdOnboardingService
|
||||
? createMiniAppUpdatePurchaseHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
botToken: runtime.telegramBotToken,
|
||||
onboardingService: householdOnboardingService,
|
||||
financeServiceForHousehold,
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppDeletePurchase: householdOnboardingService
|
||||
? createMiniAppDeletePurchaseHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
botToken: runtime.telegramBotToken,
|
||||
onboardingService: householdOnboardingService,
|
||||
financeServiceForHousehold,
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppAddPayment: householdOnboardingService
|
||||
? createMiniAppAddPaymentHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
botToken: runtime.telegramBotToken,
|
||||
onboardingService: householdOnboardingService,
|
||||
financeServiceForHousehold,
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppUpdatePayment: householdOnboardingService
|
||||
? createMiniAppUpdatePaymentHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
botToken: runtime.telegramBotToken,
|
||||
onboardingService: householdOnboardingService,
|
||||
financeServiceForHousehold,
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppDeletePayment: householdOnboardingService
|
||||
? createMiniAppDeletePaymentHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
botToken: runtime.telegramBotToken,
|
||||
onboardingService: householdOnboardingService,
|
||||
financeServiceForHousehold,
|
||||
logger: getLogger('miniapp-billing')
|
||||
})
|
||||
: undefined,
|
||||
miniAppLocalePreference: householdOnboardingService
|
||||
? createMiniAppLocalePreferenceHandler({
|
||||
allowedOrigins: runtime.miniAppAllowedOrigins,
|
||||
|
||||
@@ -135,6 +135,11 @@ function onboardingRepository(): HouseholdConfigurationRepository {
|
||||
function createFinanceServiceStub(): FinanceCommandService {
|
||||
return {
|
||||
getMemberByTelegramUserId: async () => null,
|
||||
ensureExpectedCycle: async () => ({
|
||||
id: 'cycle-2026-03',
|
||||
period: '2026-03',
|
||||
currency: 'USD'
|
||||
}),
|
||||
getOpenCycle: async () => ({
|
||||
id: 'cycle-2026-03',
|
||||
period: '2026-03',
|
||||
@@ -187,6 +192,24 @@ function createFinanceServiceStub(): FinanceCommandService {
|
||||
currency: 'USD'
|
||||
}),
|
||||
deleteUtilityBill: async () => true,
|
||||
updatePurchase: async () => ({
|
||||
purchaseId: 'purchase-1',
|
||||
amount: Money.fromMinor(3000n, 'USD'),
|
||||
currency: 'USD'
|
||||
}),
|
||||
deletePurchase: async () => true,
|
||||
addPayment: async () => ({
|
||||
paymentId: 'payment-1',
|
||||
amount: Money.fromMinor(10000n, 'USD'),
|
||||
currency: 'USD',
|
||||
period: '2026-03'
|
||||
}),
|
||||
updatePayment: async () => ({
|
||||
paymentId: 'payment-1',
|
||||
amount: Money.fromMinor(10000n, 'USD'),
|
||||
currency: 'USD'
|
||||
}),
|
||||
deletePayment: async () => true,
|
||||
generateDashboard: async () => null,
|
||||
generateStatement: async () => null
|
||||
}
|
||||
|
||||
@@ -283,6 +283,101 @@ async function readUtilityBillDeletePayload(request: Request): Promise<{
|
||||
}
|
||||
}
|
||||
|
||||
async function readPurchaseMutationPayload(request: Request): Promise<{
|
||||
initData: string
|
||||
purchaseId: string
|
||||
description?: string
|
||||
amountMajor?: string
|
||||
currency?: string
|
||||
}> {
|
||||
const parsed = await parseJsonBody<{
|
||||
initData?: string
|
||||
purchaseId?: string
|
||||
description?: string
|
||||
amountMajor?: string
|
||||
currency?: string
|
||||
}>(request)
|
||||
const initData = parsed.initData?.trim()
|
||||
if (!initData) {
|
||||
throw new Error('Missing initData')
|
||||
}
|
||||
const purchaseId = parsed.purchaseId?.trim()
|
||||
if (!purchaseId) {
|
||||
throw new Error('Missing purchase id')
|
||||
}
|
||||
|
||||
return {
|
||||
initData,
|
||||
purchaseId,
|
||||
...(parsed.description !== undefined
|
||||
? {
|
||||
description: parsed.description.trim()
|
||||
}
|
||||
: {}),
|
||||
...(parsed.amountMajor !== undefined
|
||||
? {
|
||||
amountMajor: parsed.amountMajor.trim()
|
||||
}
|
||||
: {}),
|
||||
...(parsed.currency?.trim()
|
||||
? {
|
||||
currency: parsed.currency.trim()
|
||||
}
|
||||
: {})
|
||||
}
|
||||
}
|
||||
|
||||
async function readPaymentMutationPayload(request: Request): Promise<{
|
||||
initData: string
|
||||
paymentId?: string
|
||||
memberId?: string
|
||||
kind?: 'rent' | 'utilities'
|
||||
amountMajor?: string
|
||||
currency?: string
|
||||
}> {
|
||||
const parsed = await parseJsonBody<{
|
||||
initData?: string
|
||||
paymentId?: string
|
||||
memberId?: string
|
||||
kind?: 'rent' | 'utilities'
|
||||
amountMajor?: string
|
||||
currency?: string
|
||||
}>(request)
|
||||
const initData = parsed.initData?.trim()
|
||||
if (!initData) {
|
||||
throw new Error('Missing initData')
|
||||
}
|
||||
|
||||
return {
|
||||
initData,
|
||||
...(parsed.paymentId?.trim()
|
||||
? {
|
||||
paymentId: parsed.paymentId.trim()
|
||||
}
|
||||
: {}),
|
||||
...(parsed.memberId?.trim()
|
||||
? {
|
||||
memberId: parsed.memberId.trim()
|
||||
}
|
||||
: {}),
|
||||
...(parsed.kind
|
||||
? {
|
||||
kind: parsed.kind
|
||||
}
|
||||
: {}),
|
||||
...(parsed.amountMajor?.trim()
|
||||
? {
|
||||
amountMajor: parsed.amountMajor.trim()
|
||||
}
|
||||
: {}),
|
||||
...(parsed.currency?.trim()
|
||||
? {
|
||||
currency: parsed.currency.trim()
|
||||
}
|
||||
: {})
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppBillingCycleHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
@@ -718,3 +813,285 @@ export function createMiniAppDeleteUtilityBillHandler(options: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppUpdatePurchaseHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
financeServiceForHousehold: (householdId: string) => FinanceCommandService
|
||||
onboardingService: HouseholdOnboardingService
|
||||
logger?: Logger
|
||||
}): {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
} {
|
||||
const sessionService = createMiniAppSessionService({
|
||||
botToken: options.botToken,
|
||||
onboardingService: options.onboardingService
|
||||
})
|
||||
|
||||
return {
|
||||
handler: async (request) => {
|
||||
const origin = allowedMiniAppOrigin(request, options.allowedOrigins)
|
||||
if (request.method === 'OPTIONS') {
|
||||
return miniAppJsonResponse({ ok: true }, 204, origin)
|
||||
}
|
||||
if (request.method !== 'POST') {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Method Not Allowed' }, 405, origin)
|
||||
}
|
||||
|
||||
try {
|
||||
const auth = await authenticateAdminSession(
|
||||
request.clone() as Request,
|
||||
sessionService,
|
||||
origin
|
||||
)
|
||||
if (auth instanceof Response) {
|
||||
return auth
|
||||
}
|
||||
|
||||
const payload = await readPurchaseMutationPayload(request)
|
||||
if (!payload.description || !payload.amountMajor) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Missing purchase fields' }, 400, origin)
|
||||
}
|
||||
|
||||
const service = options.financeServiceForHousehold(auth.member.householdId)
|
||||
const updated = await service.updatePurchase(
|
||||
payload.purchaseId,
|
||||
payload.description,
|
||||
payload.amountMajor,
|
||||
payload.currency
|
||||
)
|
||||
|
||||
if (!updated) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Purchase not found' }, 404, origin)
|
||||
}
|
||||
|
||||
return miniAppJsonResponse({ ok: true, authorized: true }, 200, origin)
|
||||
} catch (error) {
|
||||
return miniAppErrorResponse(error, origin, options.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppDeletePurchaseHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
financeServiceForHousehold: (householdId: string) => FinanceCommandService
|
||||
onboardingService: HouseholdOnboardingService
|
||||
logger?: Logger
|
||||
}): {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
} {
|
||||
const sessionService = createMiniAppSessionService({
|
||||
botToken: options.botToken,
|
||||
onboardingService: options.onboardingService
|
||||
})
|
||||
|
||||
return {
|
||||
handler: async (request) => {
|
||||
const origin = allowedMiniAppOrigin(request, options.allowedOrigins)
|
||||
if (request.method === 'OPTIONS') {
|
||||
return miniAppJsonResponse({ ok: true }, 204, origin)
|
||||
}
|
||||
if (request.method !== 'POST') {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Method Not Allowed' }, 405, origin)
|
||||
}
|
||||
|
||||
try {
|
||||
const auth = await authenticateAdminSession(
|
||||
request.clone() as Request,
|
||||
sessionService,
|
||||
origin
|
||||
)
|
||||
if (auth instanceof Response) {
|
||||
return auth
|
||||
}
|
||||
|
||||
const payload = await readPurchaseMutationPayload(request)
|
||||
const service = options.financeServiceForHousehold(auth.member.householdId)
|
||||
const deleted = await service.deletePurchase(payload.purchaseId)
|
||||
|
||||
if (!deleted) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Purchase not found' }, 404, origin)
|
||||
}
|
||||
|
||||
return miniAppJsonResponse({ ok: true, authorized: true }, 200, origin)
|
||||
} catch (error) {
|
||||
return miniAppErrorResponse(error, origin, options.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppAddPaymentHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
financeServiceForHousehold: (householdId: string) => FinanceCommandService
|
||||
onboardingService: HouseholdOnboardingService
|
||||
logger?: Logger
|
||||
}): {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
} {
|
||||
const sessionService = createMiniAppSessionService({
|
||||
botToken: options.botToken,
|
||||
onboardingService: options.onboardingService
|
||||
})
|
||||
|
||||
return {
|
||||
handler: async (request) => {
|
||||
const origin = allowedMiniAppOrigin(request, options.allowedOrigins)
|
||||
if (request.method === 'OPTIONS') {
|
||||
return miniAppJsonResponse({ ok: true }, 204, origin)
|
||||
}
|
||||
if (request.method !== 'POST') {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Method Not Allowed' }, 405, origin)
|
||||
}
|
||||
|
||||
try {
|
||||
const auth = await authenticateAdminSession(
|
||||
request.clone() as Request,
|
||||
sessionService,
|
||||
origin
|
||||
)
|
||||
if (auth instanceof Response) {
|
||||
return auth
|
||||
}
|
||||
|
||||
const payload = await readPaymentMutationPayload(request)
|
||||
if (!payload.memberId || !payload.kind || !payload.amountMajor) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Missing payment fields' }, 400, origin)
|
||||
}
|
||||
|
||||
const service = options.financeServiceForHousehold(auth.member.householdId)
|
||||
const payment = await service.addPayment(
|
||||
payload.memberId,
|
||||
payload.kind,
|
||||
payload.amountMajor,
|
||||
payload.currency
|
||||
)
|
||||
|
||||
if (!payment) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'No open billing cycle' }, 409, origin)
|
||||
}
|
||||
|
||||
return miniAppJsonResponse({ ok: true, authorized: true }, 200, origin)
|
||||
} catch (error) {
|
||||
return miniAppErrorResponse(error, origin, options.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppUpdatePaymentHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
financeServiceForHousehold: (householdId: string) => FinanceCommandService
|
||||
onboardingService: HouseholdOnboardingService
|
||||
logger?: Logger
|
||||
}): {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
} {
|
||||
const sessionService = createMiniAppSessionService({
|
||||
botToken: options.botToken,
|
||||
onboardingService: options.onboardingService
|
||||
})
|
||||
|
||||
return {
|
||||
handler: async (request) => {
|
||||
const origin = allowedMiniAppOrigin(request, options.allowedOrigins)
|
||||
if (request.method === 'OPTIONS') {
|
||||
return miniAppJsonResponse({ ok: true }, 204, origin)
|
||||
}
|
||||
if (request.method !== 'POST') {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Method Not Allowed' }, 405, origin)
|
||||
}
|
||||
|
||||
try {
|
||||
const auth = await authenticateAdminSession(
|
||||
request.clone() as Request,
|
||||
sessionService,
|
||||
origin
|
||||
)
|
||||
if (auth instanceof Response) {
|
||||
return auth
|
||||
}
|
||||
|
||||
const payload = await readPaymentMutationPayload(request)
|
||||
if (!payload.paymentId || !payload.memberId || !payload.kind || !payload.amountMajor) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Missing payment fields' }, 400, origin)
|
||||
}
|
||||
|
||||
const service = options.financeServiceForHousehold(auth.member.householdId)
|
||||
const payment = await service.updatePayment(
|
||||
payload.paymentId,
|
||||
payload.memberId,
|
||||
payload.kind,
|
||||
payload.amountMajor,
|
||||
payload.currency
|
||||
)
|
||||
|
||||
if (!payment) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Payment not found' }, 404, origin)
|
||||
}
|
||||
|
||||
return miniAppJsonResponse({ ok: true, authorized: true }, 200, origin)
|
||||
} catch (error) {
|
||||
return miniAppErrorResponse(error, origin, options.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createMiniAppDeletePaymentHandler(options: {
|
||||
allowedOrigins: readonly string[]
|
||||
botToken: string
|
||||
financeServiceForHousehold: (householdId: string) => FinanceCommandService
|
||||
onboardingService: HouseholdOnboardingService
|
||||
logger?: Logger
|
||||
}): {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
} {
|
||||
const sessionService = createMiniAppSessionService({
|
||||
botToken: options.botToken,
|
||||
onboardingService: options.onboardingService
|
||||
})
|
||||
|
||||
return {
|
||||
handler: async (request) => {
|
||||
const origin = allowedMiniAppOrigin(request, options.allowedOrigins)
|
||||
if (request.method === 'OPTIONS') {
|
||||
return miniAppJsonResponse({ ok: true }, 204, origin)
|
||||
}
|
||||
if (request.method !== 'POST') {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Method Not Allowed' }, 405, origin)
|
||||
}
|
||||
|
||||
try {
|
||||
const auth = await authenticateAdminSession(
|
||||
request.clone() as Request,
|
||||
sessionService,
|
||||
origin
|
||||
)
|
||||
if (auth instanceof Response) {
|
||||
return auth
|
||||
}
|
||||
|
||||
const payload = await readPaymentMutationPayload(request)
|
||||
if (!payload.paymentId) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Missing payment id' }, 400, origin)
|
||||
}
|
||||
|
||||
const service = options.financeServiceForHousehold(auth.member.householdId)
|
||||
const deleted = await service.deletePayment(payload.paymentId)
|
||||
|
||||
if (!deleted) {
|
||||
return miniAppJsonResponse({ ok: false, error: 'Payment not found' }, 404, origin)
|
||||
}
|
||||
|
||||
return miniAppJsonResponse({ ok: true, authorized: true }, 200, origin)
|
||||
} catch (error) {
|
||||
return miniAppErrorResponse(error, origin, options.logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ import { buildMiniAppInitData } from './telegram-miniapp-test-helpers'
|
||||
function repository(
|
||||
member: Awaited<ReturnType<FinanceRepository['getMemberByTelegramUserId']>>
|
||||
): FinanceRepository {
|
||||
const cycle = {
|
||||
id: 'cycle-1',
|
||||
period: '2026-03',
|
||||
currency: 'GEL' as const
|
||||
}
|
||||
|
||||
return {
|
||||
getMemberByTelegramUserId: async () => member,
|
||||
listMembers: async () => [
|
||||
@@ -29,25 +35,29 @@ function repository(
|
||||
isAdmin: true
|
||||
}
|
||||
],
|
||||
getOpenCycle: async () => ({
|
||||
id: 'cycle-1',
|
||||
period: '2026-03',
|
||||
currency: 'GEL'
|
||||
}),
|
||||
getCycleByPeriod: async () => null,
|
||||
getLatestCycle: async () => ({
|
||||
id: 'cycle-1',
|
||||
period: '2026-03',
|
||||
currency: 'GEL'
|
||||
}),
|
||||
getOpenCycle: async () => cycle,
|
||||
getCycleByPeriod: async (period) => (period === cycle.period ? cycle : null),
|
||||
getLatestCycle: async () => cycle,
|
||||
openCycle: async () => {},
|
||||
closeCycle: async () => {},
|
||||
saveRentRule: async () => {},
|
||||
getCycleExchangeRate: async () => null,
|
||||
saveCycleExchangeRate: async (input) => input,
|
||||
addUtilityBill: async () => {},
|
||||
updateParsedPurchase: async () => null,
|
||||
deleteParsedPurchase: async () => false,
|
||||
updateUtilityBill: async () => null,
|
||||
deleteUtilityBill: async () => false,
|
||||
addPaymentRecord: async (input) => ({
|
||||
id: 'payment-new',
|
||||
memberId: input.memberId,
|
||||
kind: input.kind,
|
||||
amountMinor: input.amountMinor,
|
||||
currency: input.currency,
|
||||
recordedAt: input.recordedAt
|
||||
}),
|
||||
updatePaymentRecord: async () => null,
|
||||
deletePaymentRecord: async () => false,
|
||||
getRentRuleForPeriod: async () => ({
|
||||
amountMinor: 70000n,
|
||||
currency: 'USD'
|
||||
|
||||
@@ -111,6 +111,7 @@ export function createMiniAppDashboardHandler(options: {
|
||||
id: entry.id,
|
||||
kind: entry.kind,
|
||||
title: entry.title,
|
||||
memberId: entry.memberId,
|
||||
paymentKind: entry.paymentKind,
|
||||
amountMajor: entry.amount.toMajorString(),
|
||||
currency: entry.currency,
|
||||
|
||||
@@ -76,6 +76,7 @@ async function readBody(request: Request): Promise<ReminderJobRequestBody> {
|
||||
|
||||
export function createReminderJobsHandler(options: {
|
||||
listReminderTargets: () => Promise<readonly ReminderTarget[]>
|
||||
ensureBillingCycle?: (input: { householdId: string; at: Temporal.Instant }) => Promise<void>
|
||||
releaseReminderDispatch: (input: {
|
||||
householdId: string
|
||||
period: string
|
||||
@@ -132,6 +133,11 @@ export function createReminderJobsHandler(options: {
|
||||
}> = []
|
||||
|
||||
for (const target of targets) {
|
||||
await options.ensureBillingCycle?.({
|
||||
householdId: target.householdId,
|
||||
at: currentInstant
|
||||
})
|
||||
|
||||
if (!requestedPeriod && !isReminderDueToday(target, reminderType, currentInstant)) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -104,6 +104,36 @@ export interface BotWebhookServerOptions {
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppUpdatePurchase?:
|
||||
| {
|
||||
path?: string
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppDeletePurchase?:
|
||||
| {
|
||||
path?: string
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppAddPayment?:
|
||||
| {
|
||||
path?: string
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppUpdatePayment?:
|
||||
| {
|
||||
path?: string
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppDeletePayment?:
|
||||
| {
|
||||
path?: string
|
||||
handler: (request: Request) => Promise<Response>
|
||||
}
|
||||
| undefined
|
||||
miniAppLocalePreference?:
|
||||
| {
|
||||
path?: string
|
||||
@@ -169,6 +199,15 @@ export function createBotWebhookServer(options: BotWebhookServerOptions): {
|
||||
options.miniAppUpdateUtilityBill?.path ?? '/api/miniapp/admin/utility-bills/update'
|
||||
const miniAppDeleteUtilityBillPath =
|
||||
options.miniAppDeleteUtilityBill?.path ?? '/api/miniapp/admin/utility-bills/delete'
|
||||
const miniAppUpdatePurchasePath =
|
||||
options.miniAppUpdatePurchase?.path ?? '/api/miniapp/admin/purchases/update'
|
||||
const miniAppDeletePurchasePath =
|
||||
options.miniAppDeletePurchase?.path ?? '/api/miniapp/admin/purchases/delete'
|
||||
const miniAppAddPaymentPath = options.miniAppAddPayment?.path ?? '/api/miniapp/admin/payments/add'
|
||||
const miniAppUpdatePaymentPath =
|
||||
options.miniAppUpdatePayment?.path ?? '/api/miniapp/admin/payments/update'
|
||||
const miniAppDeletePaymentPath =
|
||||
options.miniAppDeletePayment?.path ?? '/api/miniapp/admin/payments/delete'
|
||||
const miniAppLocalePreferencePath =
|
||||
options.miniAppLocalePreference?.path ?? '/api/miniapp/preferences/locale'
|
||||
const schedulerPathPrefix = options.scheduler
|
||||
@@ -257,6 +296,26 @@ export function createBotWebhookServer(options: BotWebhookServerOptions): {
|
||||
return await options.miniAppDeleteUtilityBill.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppUpdatePurchase && url.pathname === miniAppUpdatePurchasePath) {
|
||||
return await options.miniAppUpdatePurchase.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppDeletePurchase && url.pathname === miniAppDeletePurchasePath) {
|
||||
return await options.miniAppDeletePurchase.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppAddPayment && url.pathname === miniAppAddPaymentPath) {
|
||||
return await options.miniAppAddPayment.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppUpdatePayment && url.pathname === miniAppUpdatePaymentPath) {
|
||||
return await options.miniAppUpdatePayment.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppDeletePayment && url.pathname === miniAppDeletePaymentPath) {
|
||||
return await options.miniAppDeletePayment.handler(request)
|
||||
}
|
||||
|
||||
if (options.miniAppLocalePreference && url.pathname === miniAppLocalePreferencePath) {
|
||||
return await options.miniAppLocalePreference.handler(request)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user