freshyo/apps/backend/src/trpc/apis/common-apis/common-trpc-index.ts
2026-03-07 16:24:24 +05:30

122 lines
4.4 KiB
TypeScript

import { router, publicProcedure, protectedProcedure } from '@/src/trpc/trpc-index'
import { commonRouter } from '@/src/trpc/apis/common-apis/common'
import { db } from '@/src/db/db_index'
import { keyValStore, productInfo, storeInfo } from '@/src/db/schema'
import * as turf from '@turf/turf';
import { z } from 'zod';
import { mbnrGeoJson } from '@/src/lib/mbnr-geojson'
import { generateUploadUrl } from '@/src/lib/s3-client'
import { ApiError } from '@/src/lib/api-error'
import { getAllConstValues } from '@/src/lib/const-store'
import { CONST_KEYS } from '@/src/lib/const-keys'
const polygon = turf.polygon(mbnrGeoJson.features[0].geometry.coordinates);
export const commonApiRouter = router({
product: commonRouter,
getStoresSummary: publicProcedure
.query(async () => {
const stores = await db.query.storeInfo.findMany({
columns: {
id: true,
name: true,
description: true,
},
});
return {
stores,
};
}),
checkLocationInPolygon: publicProcedure
.input(z.object({
lat: z.number().min(-90).max(90),
lng: z.number().min(-180).max(180),
}))
.query(({ input }) => {
try {
const { lat, lng } = input;
const point = turf.point([lng, lat]); // GeoJSON: [longitude, latitude]
const isInside = turf.booleanPointInPolygon(point, polygon);
return { isInside };
} catch (error) {
throw new Error('Invalid coordinates or polygon data');
}
}),
generateUploadUrls: protectedProcedure
.input(z.object({
contextString: z.enum(['review', 'product_info', 'store']),
mimeTypes: z.array(z.string()),
}))
.mutation(async ({ input }): Promise<{ uploadUrls: string[] }> => {
const { contextString, mimeTypes } = input;
const uploadUrls: string[] = [];
const keys: string[] = [];
for (const mimeType of mimeTypes) {
// Generate key based on context and mime type
let folder: string;
if (contextString === 'review') {
folder = 'review-images';
} else if (contextString === 'product_info') {
folder = 'product-images';
} else if (contextString === 'store') {
folder = 'store-images';
} else if (contextString === 'review_response') {
folder = 'review-response-images';
} else {
folder = '';
}
const extension = mimeType === 'image/jpeg' ? '.jpg' :
mimeType === 'image/png' ? '.png' :
mimeType === 'image/gif' ? '.gif' : '.jpg';
const key = `${folder}/${Date.now()}${extension}`;
try {
const uploadUrl = await generateUploadUrl(key, mimeType);
uploadUrls.push(uploadUrl);
keys.push(key);
} catch (error) {
console.error('Error generating upload URL:', error);
throw new ApiError('Failed to generate upload URL', 500);
}
}
return { uploadUrls };
}),
healthCheck: publicProcedure
.query(async () => {
// Test DB connection by selecting product names
// await db.select({ name: productInfo.name }).from(productInfo).limit(1);
await db.select({ key: keyValStore.key }).from(keyValStore).limit(1);
return {
status: "ok",
};
}),
essentialConsts: publicProcedure
.query(async () => {
const consts = await getAllConstValues();
return {
freeDeliveryThreshold: consts[CONST_KEYS.freeDeliveryThreshold] ?? 200,
deliveryCharge: consts[CONST_KEYS.deliveryCharge] ?? 0,
flashFreeDeliveryThreshold: consts[CONST_KEYS.flashFreeDeliveryThreshold] ?? 500,
flashDeliveryCharge: consts[CONST_KEYS.flashDeliveryCharge] ?? 69,
popularItems: consts[CONST_KEYS.popularItems] ?? '5,3,2,4,1',
versionNum: consts[CONST_KEYS.versionNum] ?? '1.1.0',
playStoreUrl: consts[CONST_KEYS.playStoreUrl] ?? 'https://play.google.com/store/apps/details?id=in.freshyo.app',
appStoreUrl: consts[CONST_KEYS.appStoreUrl] ?? 'https://apps.apple.com/in/app/freshyo/id6756889077',
webViewHtml: null,
isWebviewClosable: true,
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true,
supportMobile: consts[CONST_KEYS.supportMobile] ?? '',
supportEmail: consts[CONST_KEYS.supportEmail] ?? '',
};
}),
});
export type CommonApiRouter = typeof commonApiRouter;