This commit is contained in:
shafi54 2026-03-30 21:59:23 +05:30
parent b86fa8a2e0
commit 15991f46db
30 changed files with 24119 additions and 44129 deletions

View file

@ -37,6 +37,29 @@ const CONST_LABELS: Record<string, string> = {
supportEmail: 'Support Email',
};
const CONST_VISIBILITY: Record<string, boolean> = {
minRegularOrderValue: true,
freeDeliveryThreshold: true,
deliveryCharge: true,
flashFreeDeliveryThreshold: true,
flashDeliveryCharge: true,
platformFeePercent: true,
taxRate: false,
minOrderAmountForCoupon: true,
maxCouponDiscount: false,
flashDeliverySlotId: true,
readableOrderId: false,
versionNum: true,
playStoreUrl: true,
appStoreUrl: true,
popularItems: true,
allItemsOrder: true,
isFlashDeliveryEnabled: true,
supportMobile: true,
supportEmail: true,
tester: false,
};
interface ConstantInputProps {
constant: ConstantItem;
setFieldValue: (field: string, value: any) => void;
@ -49,7 +72,6 @@ const ConstantInput: React.FC<ConstantInputProps> = ({ constant, setFieldValue,
// Special handling for popularItems - show navigation button instead of input
if (constant.key === 'popularItems') {
console.log('key is allItemsOrder')
return (
<View>
<MyText style={tw`text-sm font-medium text-gray-700 mb-2`}>
@ -219,7 +241,7 @@ export default function CustomizeApp() {
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{({ handleSubmit, values, setFieldValue }) => (
<View>
{values.constants.map((constant, index) => (
{values.constants.filter((constant) => CONST_VISIBILITY[constant.key]).map((constant, index) => (
<View key={constant.key} style={tw`mb-4`}>
<ConstantInput constant={constant} setFieldValue={setFieldValue} index={index} router={router} />
</View>
@ -240,4 +262,4 @@ export default function CustomizeApp() {
</View>
</AppContainer>
);
}
}

View file

@ -3,12 +3,12 @@
// export dynamically through wrangler, or we can potentially let users directly
// add them as a sort of "plugin" system.
import ENTRY, { __INTERNAL_WRANGLER_MIDDLEWARE__ } from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-MabhKO/middleware-insertion-facade.js";
import ENTRY, { __INTERNAL_WRANGLER_MIDDLEWARE__ } from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-l1tHq1/middleware-insertion-facade.js";
import { __facade_invoke__, __facade_register__, Dispatcher } from "/Users/mohammedshafiuddin/WebDev/freshyo/node_modules/wrangler/templates/middleware/common.ts";
import type { WorkerEntrypointConstructor } from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-MabhKO/middleware-insertion-facade.js";
import type { WorkerEntrypointConstructor } from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-l1tHq1/middleware-insertion-facade.js";
// Preserve all the exports from the worker
export * from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-MabhKO/middleware-insertion-facade.js";
export * from "/Users/mohammedshafiuddin/WebDev/freshyo/apps/backend/.wrangler/tmp/bundle-l1tHq1/middleware-insertion-facade.js";
class __Facade_ScheduledController__ implements ScheduledController {
readonly #noRetry: ScheduledController["noRetry"];

File diff suppressed because one or more lines are too long

View file

@ -37,14 +37,14 @@ var __publicField = (obj, key, value) => {
return value;
};
// .wrangler/tmp/bundle-MabhKO/strip-cf-connecting-ip-header.js
// .wrangler/tmp/bundle-l1tHq1/strip-cf-connecting-ip-header.js
function stripCfConnectingIPHeader(input, init) {
const request = new Request(input, init);
request.headers.delete("CF-Connecting-IP");
return request;
}
var init_strip_cf_connecting_ip_header = __esm({
".wrangler/tmp/bundle-MabhKO/strip-cf-connecting-ip-header.js"() {
".wrangler/tmp/bundle-l1tHq1/strip-cf-connecting-ip-header.js"() {
"use strict";
__name(stripCfConnectingIPHeader, "stripCfConnectingIPHeader");
globalThis.fetch = new Proxy(globalThis.fetch, {
@ -8955,7 +8955,7 @@ var init_schema = __esm({
});
keyValStore = sqliteTable("key_val_store", {
key: text("key").primaryKey(),
value: jsonText("value")
value: text()
});
notifications = sqliteTable("notifications", {
id: integer().primaryKey({ autoIncrement: true }),
@ -9444,21 +9444,110 @@ var init_complaint = __esm({
}
});
// ../../packages/db_helper_sqlite/src/lib/const-keys.ts
var CONST_KEYS, CONST_KEYS_ARRAY, CONST_TYPES, castConstValue;
var init_const_keys = __esm({
"../../packages/db_helper_sqlite/src/lib/const-keys.ts"() {
"use strict";
init_strip_cf_connecting_ip_header();
init_modules_watch_stub();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
CONST_KEYS = {
minRegularOrderValue: "minRegularOrderValue",
freeDeliveryThreshold: "freeDeliveryThreshold",
deliveryCharge: "deliveryCharge",
flashFreeDeliveryThreshold: "flashFreeDeliveryThreshold",
flashDeliveryCharge: "flashDeliveryCharge",
platformFeePercent: "platformFeePercent",
taxRate: "taxRate",
tester: "tester",
minOrderAmountForCoupon: "minOrderAmountForCoupon",
maxCouponDiscount: "maxCouponDiscount",
flashDeliverySlotId: "flashDeliverySlotId",
readableOrderId: "readableOrderId",
versionNum: "versionNum",
cacheVersion: "cache_version",
playStoreUrl: "playStoreUrl",
appStoreUrl: "appStoreUrl",
popularItems: "popularItems",
allItemsOrder: "allItemsOrder",
isFlashDeliveryEnabled: "isFlashDeliveryEnabled",
supportMobile: "supportMobile",
supportEmail: "supportEmail"
};
CONST_KEYS_ARRAY = Object.values(CONST_KEYS);
CONST_TYPES = {
minRegularOrderValue: "number",
freeDeliveryThreshold: "number",
deliveryCharge: "number",
flashFreeDeliveryThreshold: "number",
flashDeliveryCharge: "number",
platformFeePercent: "number",
taxRate: "number",
tester: "string",
minOrderAmountForCoupon: "number",
maxCouponDiscount: "number",
flashDeliverySlotId: "number",
readableOrderId: "number",
versionNum: "string",
"cache_version": "number",
playStoreUrl: "string",
appStoreUrl: "string",
popularItems: "string",
allItemsOrder: "string",
isFlashDeliveryEnabled: "boolean",
supportMobile: "string",
supportEmail: "string"
};
castConstValue = /* @__PURE__ */ __name((key, value) => {
if (!Object.prototype.hasOwnProperty.call(CONST_TYPES, key)) {
return value;
}
const type = CONST_TYPES[key];
if (type === "number") {
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : 0;
}
if (type === "boolean") {
let newVal = value + "";
if (newVal === "0") {
return false;
} else if (newVal?.toLowerCase() === "false") {
return false;
}
return true;
}
if (value === null || value === void 0) {
return "";
}
return String(value);
}, "castConstValue");
}
});
// ../../packages/db_helper_sqlite/src/admin-apis/const.ts
async function getAllConstants() {
const constants2 = await db.select().from(keyValStore);
return constants2.map((c2) => ({
key: c2.key,
value: c2.value
value: castConstValue(c2.key, c2.value)
}));
}
async function upsertConstants(constants2) {
await db.transaction(async (tx) => {
for (const { key, value } of constants2) {
await tx.insert(keyValStore).values({ key, value }).onConflictDoUpdate({
target: keyValStore.key,
set: { value }
const castedValue = value + "";
const existing = await tx.query.keyValStore.findFirst({
where: eq(keyValStore.key, key),
columns: { key: true }
});
if (existing) {
await tx.update(keyValStore).set({ value: castedValue }).where(eq(keyValStore.key, key));
} else {
await tx.insert(keyValStore).values({ key, value: castedValue });
}
}
});
}
@ -9496,9 +9585,10 @@ var init_const = __esm({
init_db_index();
init_schema();
init_drizzle_orm();
init_const_keys();
__name(getAllConstants, "getAllConstants");
__name(upsertConstants, "upsertConstants");
CACHE_VERSION_KEY = "cache_version";
CACHE_VERSION_KEY = CONST_KEYS.cacheVersion;
parseCacheVersion = /* @__PURE__ */ __name((value) => {
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : 0;
@ -14269,8 +14359,8 @@ var init_dbService = __esm({
});
// src/lib/const-keys.ts
var CONST_KEYS, CONST_KEYS_ARRAY;
var init_const_keys = __esm({
var CONST_KEYS2, CONST_KEYS_ARRAY2;
var init_const_keys2 = __esm({
"src/lib/const-keys.ts"() {
"use strict";
init_strip_cf_connecting_ip_header();
@ -14278,7 +14368,7 @@ var init_const_keys = __esm({
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
CONST_KEYS = {
CONST_KEYS2 = {
minRegularOrderValue: "minRegularOrderValue",
freeDeliveryThreshold: "freeDeliveryThreshold",
deliveryCharge: "deliveryCharge",
@ -14292,6 +14382,7 @@ var init_const_keys = __esm({
flashDeliverySlotId: "flashDeliverySlotId",
readableOrderId: "readableOrderId",
versionNum: "versionNum",
cacheVersion: "cache_version",
playStoreUrl: "playStoreUrl",
appStoreUrl: "appStoreUrl",
popularItems: "popularItems",
@ -14300,7 +14391,7 @@ var init_const_keys = __esm({
supportMobile: "supportMobile",
supportEmail: "supportEmail"
};
CONST_KEYS_ARRAY = Object.values(CONST_KEYS);
CONST_KEYS_ARRAY2 = Object.values(CONST_KEYS2);
}
});
@ -14315,7 +14406,7 @@ var init_const_store = __esm({
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dbService();
init_const_keys();
init_const_keys2();
computeConstants = /* @__PURE__ */ __name(async () => {
try {
console.log("Computing constants from database...");
@ -14348,7 +14439,7 @@ var init_const_store = __esm({
const constants2 = await getAllKeyValStore();
const constantsMap = new Map(constants2.map((c2) => [c2.key, c2.value]));
const result = {};
for (const key of CONST_KEYS_ARRAY) {
for (const key of CONST_KEYS_ARRAY2) {
result[key] = constantsMap.get(key) ?? null;
}
return result;
@ -42318,7 +42409,7 @@ var init_product_store = __esm({
// src/stores/product-tag-store.ts
async function transformTagToStoreTag(tag2) {
const signedImageUrl = tag2.imageUrl ? await generateSignedUrlFromS3Url(tag2.imageUrl) : null;
const signedImageUrl = tag2.imageUrl ? scaffoldAssetUrl(tag2.imageUrl) : null;
return {
id: tag2.id,
tagName: tag2.tagName,
@ -63097,19 +63188,19 @@ async function scaffoldEssentialConsts() {
const consts = await getAllConstValues();
const cacheVersion = await getCacheVersion();
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",
freeDeliveryThreshold: consts[CONST_KEYS2.freeDeliveryThreshold] ?? 200,
deliveryCharge: consts[CONST_KEYS2.deliveryCharge] ?? 0,
flashFreeDeliveryThreshold: consts[CONST_KEYS2.flashFreeDeliveryThreshold] ?? 500,
flashDeliveryCharge: consts[CONST_KEYS2.flashDeliveryCharge] ?? 69,
popularItems: consts[CONST_KEYS2.popularItems],
versionNum: consts[CONST_KEYS2.versionNum],
playStoreUrl: consts[CONST_KEYS2.playStoreUrl],
appStoreUrl: consts[CONST_KEYS2.appStoreUrl],
webViewHtml: null,
isWebviewClosable: true,
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true,
supportMobile: consts[CONST_KEYS.supportMobile] ?? "",
supportEmail: consts[CONST_KEYS.supportEmail] ?? "",
isFlashDeliveryEnabled: consts[CONST_KEYS2.isFlashDeliveryEnabled] ?? false,
supportMobile: consts[CONST_KEYS2.supportMobile] ?? "",
supportEmail: consts[CONST_KEYS2.supportEmail] ?? "",
assetsDomain: getAssetsDomain(),
apiCacheKey: getApiCacheKey(),
cacheVersion
@ -63133,7 +63224,7 @@ var init_common_trpc_index = __esm({
init_s3_client();
init_api_error();
init_const_store();
init_const_keys();
init_const_keys2();
init_env_exporter();
polygon2 = polygon(mbnrGeoJson.features[0].geometry.coordinates);
__name(scaffoldEssentialConsts, "scaffoldEssentialConsts");
@ -64692,7 +64783,7 @@ async function sendAdminNotification(data) {
console.error(`Invalid Expo push token: ${token}`);
return;
}
const signedImageUrl = imageUrl ? await generateSignedUrlFromS3Url(imageUrl) : null;
const signedImageUrl = imageUrl ? scaffoldAssetUrl(imageUrl) : null;
const expo = new import_expo_server_sdk.Expo();
const message2 = {
to: token,
@ -72972,7 +73063,7 @@ var init_product3 = __esm({
const tagsWithSignedUrls = await Promise.all(
tags.map(async (tag2) => ({
...tag2,
imageUrl: tag2.imageUrl ? await generateSignedUrlFromS3Url(tag2.imageUrl) : null
imageUrl: tag2.imageUrl ? scaffoldAssetUrl(tag2.imageUrl) : null
}))
);
return {
@ -72987,7 +73078,7 @@ var init_product3 = __esm({
}
const tagWithSignedUrl = {
...tag2,
imageUrl: tag2.imageUrl ? await generateSignedUrlFromS3Url(tag2.imageUrl) : null
imageUrl: tag2.imageUrl ? scaffoldAssetUrl(tag2.imageUrl) : null
};
return {
tag: tagWithSignedUrl,
@ -73022,7 +73113,7 @@ var init_product3 = __esm({
return {
tag: {
...createdTagInfo,
imageUrl: createdTagInfo.imageUrl ? await generateSignedUrlFromS3Url(createdTagInfo.imageUrl) : null
imageUrl: createdTagInfo.imageUrl ? scaffoldAssetUrl(createdTagInfo.imageUrl) : null
},
message: "Tag created successfully"
};
@ -73061,7 +73152,7 @@ var init_product3 = __esm({
return {
tag: {
...updatedTagInfo,
imageUrl: updatedTagInfo.imageUrl ? await generateSignedUrlFromS3Url(updatedTagInfo.imageUrl) : null
imageUrl: updatedTagInfo.imageUrl ? scaffoldAssetUrl(updatedTagInfo.imageUrl) : null
},
message: "Tag updated successfully"
};
@ -75410,7 +75501,7 @@ var init_store2 = __esm({
const stores = await getAllStores();
await Promise.all(stores.map(async (store) => {
if (store.imageUrl)
store.imageUrl = await generateSignedUrlFromS3Url(store.imageUrl);
store.imageUrl = scaffoldAssetUrl(store.imageUrl);
})).catch((e2) => {
throw new ApiError("Unable to find store image urls");
});
@ -75427,7 +75518,7 @@ var init_store2 = __esm({
if (!store) {
throw new ApiError("Store not found", 404);
}
store.imageUrl = await generateSignedUrlFromS3Url(store.imageUrl);
store.imageUrl = scaffoldAssetUrl(store.imageUrl);
return {
store
};
@ -75566,7 +75657,7 @@ var init_banner2 = __esm({
try {
return {
...banner,
imageUrl: banner.imageUrl ? await generateSignedUrlFromS3Url(banner.imageUrl) : banner.imageUrl,
imageUrl: banner.imageUrl ? scaffoldAssetUrl(banner.imageUrl) : banner.imageUrl,
// Ensure productIds is always an array
productIds: banner.productIds || []
};
@ -75596,7 +75687,7 @@ var init_banner2 = __esm({
if (banner) {
try {
if (banner.imageUrl) {
banner.imageUrl = await generateSignedUrlFromS3Url(banner.imageUrl);
banner.imageUrl = scaffoldAssetUrl(banner.imageUrl);
}
} catch (error50) {
console.error(`Failed to generate signed URL for banner ${banner.id}:`, error50);
@ -75921,7 +76012,7 @@ var init_const2 = __esm({
init_trpc_index();
init_zod();
init_const_store();
init_const_keys();
init_const_keys2();
init_dbService();
constRouter = router({
getConstants: protectedProcedure.query(async () => {
@ -75935,11 +76026,12 @@ var init_const2 = __esm({
}))
})).mutation(async ({ input }) => {
const { constants: constants2 } = input;
const validKeys = Object.values(CONST_KEYS);
const validKeys = Object.values(CONST_KEYS2);
const invalidKeys = constants2.filter((c2) => !validKeys.includes(c2.key)).map((c2) => c2.key);
if (invalidKeys.length > 0) {
throw new Error(`Invalid constant keys: ${invalidKeys.join(", ")}`);
}
console.log(input);
await upsertConstants(constants2);
await computeConstants();
return {
@ -76751,14 +76843,14 @@ var init_order4 = __esm({
userNotes
} = params;
const constants2 = await getConstants([
CONST_KEYS.minRegularOrderValue,
CONST_KEYS.deliveryCharge,
CONST_KEYS.flashFreeDeliveryThreshold,
CONST_KEYS.flashDeliveryCharge
CONST_KEYS2.minRegularOrderValue,
CONST_KEYS2.deliveryCharge,
CONST_KEYS2.flashFreeDeliveryThreshold,
CONST_KEYS2.flashDeliveryCharge
]);
const isFlashDelivery = params.isFlash;
const minOrderValue = (isFlashDelivery ? constants2[CONST_KEYS.flashFreeDeliveryThreshold] : constants2[CONST_KEYS.minRegularOrderValue]) || 0;
const deliveryCharge = (isFlashDelivery ? constants2[CONST_KEYS.flashDeliveryCharge] : constants2[CONST_KEYS.deliveryCharge]) || 0;
const minOrderValue = (isFlashDelivery ? constants2[CONST_KEYS2.flashFreeDeliveryThreshold] : constants2[CONST_KEYS2.minRegularOrderValue]) || 0;
const deliveryCharge = (isFlashDelivery ? constants2[CONST_KEYS2.flashDeliveryCharge] : constants2[CONST_KEYS2.deliveryCharge]) || 0;
const orderGroupId = `${Date.now()}-${userId}`;
const address = await getAddressByIdAndUser(addressId, userId);
if (!address) {
@ -76912,7 +77004,7 @@ var init_order4 = __esm({
isFlashDelivery
} = input;
if (isFlashDelivery) {
const isFlashDeliveryEnabled = await getConstant(CONST_KEYS.isFlashDeliveryEnabled);
const isFlashDeliveryEnabled = await getConstant(CONST_KEYS2.isFlashDeliveryEnabled);
if (!isFlashDeliveryEnabled) {
throw new ApiError("Flash delivery is currently unavailable. Please opt for scheduled delivery.", 403);
}
@ -77377,7 +77469,7 @@ var init_user4 = __esm({
throw new ApiError("User not found", 404);
}
const userDetail = await getUserDetailByUserId(userId);
const profileImageSignedUrl = userDetail?.profileImage ? await generateSignedUrlFromS3Url(userDetail.profileImage) : null;
const profileImageSignedUrl = userDetail?.profileImage ? scaffoldAssetUrl(userDetail.profileImage) : null;
return {
success: true,
data: {
@ -77964,14 +78056,14 @@ var init_app = __esm({
}
});
// .wrangler/tmp/bundle-MabhKO/middleware-loader.entry.ts
// .wrangler/tmp/bundle-l1tHq1/middleware-loader.entry.ts
init_strip_cf_connecting_ip_header();
init_modules_watch_stub();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
// .wrangler/tmp/bundle-MabhKO/middleware-insertion-facade.js
// .wrangler/tmp/bundle-l1tHq1/middleware-insertion-facade.js
init_strip_cf_connecting_ip_header();
init_modules_watch_stub();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
@ -78162,7 +78254,7 @@ var jsonError = /* @__PURE__ */ __name(async (request, env2, _ctx, middlewareCtx
}, "jsonError");
var middleware_miniflare3_json_error_default = jsonError;
// .wrangler/tmp/bundle-MabhKO/middleware-insertion-facade.js
// .wrangler/tmp/bundle-l1tHq1/middleware-insertion-facade.js
var __INTERNAL_WRANGLER_MIDDLEWARE__ = [
middleware_ensure_req_body_drained_default,
middleware_miniflare3_json_error_default
@ -78199,7 +78291,7 @@ function __facade_invoke__(request, env2, ctx, dispatch, finalMiddleware) {
}
__name(__facade_invoke__, "__facade_invoke__");
// .wrangler/tmp/bundle-MabhKO/middleware-loader.entry.ts
// .wrangler/tmp/bundle-l1tHq1/middleware-loader.entry.ts
var __Facade_ScheduledController__ = class {
constructor(scheduledTime, cron, noRetry) {
this.scheduledTime = scheduledTime;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,7 @@ export const CONST_KEYS = {
flashDeliverySlotId: 'flashDeliverySlotId',
readableOrderId: 'readableOrderId',
versionNum: 'versionNum',
cacheVersion: 'cache_version',
playStoreUrl: 'playStoreUrl',
appStoreUrl: 'appStoreUrl',
popularItems: 'popularItems',
@ -35,6 +36,7 @@ export const CONST_LABELS: Record<ConstKey, string> = {
flashDeliverySlotId: 'Flash Delivery Slot ID',
readableOrderId: 'Readable Order ID',
versionNum: 'Version Number',
'cache_version': 'Cache Version',
playStoreUrl: 'Play Store URL',
appStoreUrl: 'App Store URL',
popularItems: 'Popular Items',
@ -47,3 +49,53 @@ export const CONST_LABELS: Record<ConstKey, string> = {
export type ConstKey = (typeof CONST_KEYS)[keyof typeof CONST_KEYS];
export const CONST_KEYS_ARRAY = Object.values(CONST_KEYS) as ConstKey[];
export type ConstValueType = 'string' | 'boolean' | 'number'
export const CONST_TYPES: Record<ConstKey, ConstValueType> = {
minRegularOrderValue: 'number',
freeDeliveryThreshold: 'number',
deliveryCharge: 'number',
flashFreeDeliveryThreshold: 'number',
flashDeliveryCharge: 'number',
platformFeePercent: 'number',
taxRate: 'number',
tester: 'string',
minOrderAmountForCoupon: 'number',
maxCouponDiscount: 'number',
flashDeliverySlotId: 'number',
readableOrderId: 'number',
versionNum: 'string',
'cache_version': 'number',
playStoreUrl: 'string',
appStoreUrl: 'string',
popularItems: 'string',
allItemsOrder: 'string',
isFlashDeliveryEnabled: 'boolean',
supportMobile: 'string',
supportEmail: 'string',
};
export const CONST_VISIBILITY: Record<ConstKey, boolean> = {
minRegularOrderValue: true,
freeDeliveryThreshold: true,
deliveryCharge: true,
flashFreeDeliveryThreshold: true,
flashDeliveryCharge: true,
platformFeePercent: true,
taxRate: false,
tester: false,
minOrderAmountForCoupon: true,
maxCouponDiscount: false,
flashDeliverySlotId: true,
readableOrderId: false,
versionNum: true,
'cache_version': false,
playStoreUrl: true,
appStoreUrl: true,
popularItems: true,
allItemsOrder: true,
isFlashDeliveryEnabled: true,
supportMobile: true,
supportEmail: true,
};

View file

@ -1,7 +1,7 @@
// import { Queue, Worker } from 'bullmq';
import { Expo } from 'expo-server-sdk';
// import { db } from '@/src/db/db_index'
import { generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'
import { queueDataPusher } from '@/src/lib/queue-data-pusher'
import {
NOTIFS_QUEUE,
@ -59,7 +59,7 @@ export async function sendAdminNotification(data: {
}
// Generate signed URL for image if provided
const signedImageUrl = imageUrl ? await generateSignedUrlFromS3Url(imageUrl) : null;
const signedImageUrl = imageUrl ? scaffoldAssetUrl(imageUrl) : null;
// Send notification
const expo = new Expo();

View file

@ -7,7 +7,7 @@ import {
type TagBasicData,
type TagProductMapping,
} from '@/src/dbService'
import { generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'
// Tag Type (matches getDashboardTags return)
interface Tag {
@ -30,7 +30,7 @@ async function transformTagToStoreTag(tag: {
products?: Array<{ productId: number }>
}): Promise<Tag> {
const signedImageUrl = tag.imageUrl
? await generateSignedUrlFromS3Url(tag.imageUrl)
? scaffoldAssetUrl(tag.imageUrl)
: null
return {

View file

@ -1,6 +1,6 @@
import { z } from 'zod';
import { protectedProcedure, router } from '@/src/trpc/trpc-index'
import { extractKeyFromPresignedUrl, generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { extractKeyFromPresignedUrl, scaffoldAssetUrl } from '@/src/lib/s3-client'
import { ApiError } from '@/src/lib/api-error';
import { scheduleStoreInitialization } from '@/src/stores/store-initializer'
import {
@ -36,7 +36,7 @@ export const bannerRouter = router({
try {
return {
...banner,
imageUrl: banner.imageUrl ? await generateSignedUrlFromS3Url(banner.imageUrl) : banner.imageUrl,
imageUrl: banner.imageUrl ? scaffoldAssetUrl(banner.imageUrl) : banner.imageUrl,
// Ensure productIds is always an array
productIds: banner.productIds || [],
};
@ -82,7 +82,7 @@ export const bannerRouter = router({
try {
// Convert S3 key to signed URL for client
if (banner.imageUrl) {
banner.imageUrl = await generateSignedUrlFromS3Url(banner.imageUrl);
banner.imageUrl = scaffoldAssetUrl(banner.imageUrl);
}
} catch (error) {
console.error(`Failed to generate signed URL for banner ${banner.id}:`, error);

View file

@ -43,6 +43,7 @@ export const constRouter = router({
throw new Error(`Invalid constant keys: ${invalidKeys.join(', ')}`);
}
console.log(input)
// Using dbService helper (new implementation)
await upsertConstantsInDb(constants);

View file

@ -1,7 +1,7 @@
import { router, protectedProcedure } from '@/src/trpc/trpc-index'
import { z } from 'zod'
import { ApiError } from '@/src/lib/api-error'
import { generateSignedUrlsFromS3Urls, generateSignedUrlFromS3Url, claimUploadUrl, extractKeyFromPresignedUrl, deleteImageUtil } from '@/src/lib/s3-client'
import { generateSignedUrlsFromS3Urls, scaffoldAssetUrl, claimUploadUrl, extractKeyFromPresignedUrl, deleteImageUtil } from '@/src/lib/s3-client'
import { scheduleStoreInitialization } from '@/src/stores/store-initializer'
import {
getAllProducts as getAllProductsInDb,
@ -908,7 +908,7 @@ export const productRouter = router({
const tagsWithSignedUrls = await Promise.all(
tags.map(async (tag) => ({
...tag,
imageUrl: tag.imageUrl ? await generateSignedUrlFromS3Url(tag.imageUrl) : null,
imageUrl: tag.imageUrl ? scaffoldAssetUrl(tag.imageUrl) : null,
}))
)
@ -929,7 +929,7 @@ export const productRouter = router({
const tagWithSignedUrl = {
...tag,
imageUrl: tag.imageUrl ? await generateSignedUrlFromS3Url(tag.imageUrl) : null,
imageUrl: tag.imageUrl ? scaffoldAssetUrl(tag.imageUrl) : null,
}
return {
@ -974,7 +974,7 @@ export const productRouter = router({
return {
tag: {
...createdTagInfo,
imageUrl: createdTagInfo.imageUrl ? await generateSignedUrlFromS3Url(createdTagInfo.imageUrl) : null,
imageUrl: createdTagInfo.imageUrl ? scaffoldAssetUrl(createdTagInfo.imageUrl) : null,
},
message: 'Tag created successfully',
}
@ -1024,7 +1024,7 @@ export const productRouter = router({
return {
tag: {
...updatedTagInfo,
imageUrl: updatedTagInfo.imageUrl ? await generateSignedUrlFromS3Url(updatedTagInfo.imageUrl) : null,
imageUrl: updatedTagInfo.imageUrl ? scaffoldAssetUrl(updatedTagInfo.imageUrl) : null,
},
message: 'Tag updated successfully',
}

View file

@ -1,7 +1,7 @@
import { router, protectedProcedure } from '@/src/trpc/trpc-index'
import { z } from 'zod';
import { ApiError } from '@/src/lib/api-error'
import { extractKeyFromPresignedUrl, deleteImageUtil, generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { extractKeyFromPresignedUrl, deleteImageUtil, scaffoldAssetUrl } from '@/src/lib/s3-client'
import { scheduleStoreInitialization } from '@/src/stores/store-initializer'
import {
getAllStores as getAllStoresFromDb,
@ -19,7 +19,7 @@ export const storeRouter = router({
await Promise.all(stores.map(async store => {
if(store.imageUrl)
store.imageUrl = await generateSignedUrlFromS3Url(store.imageUrl)
store.imageUrl = scaffoldAssetUrl(store.imageUrl)
})).catch((e) => {
throw new ApiError("Unable to find store image urls")
})
@ -42,7 +42,7 @@ export const storeRouter = router({
if (!store) {
throw new ApiError("Store not found", 404);
}
store.imageUrl = await generateSignedUrlFromS3Url(store.imageUrl);
store.imageUrl = scaffoldAssetUrl(store.imageUrl);
return {
store,
};

View file

@ -26,13 +26,13 @@ export async function scaffoldEssentialConsts() {
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',
popularItems: consts[CONST_KEYS.popularItems],
versionNum: consts[CONST_KEYS.versionNum],
playStoreUrl: consts[CONST_KEYS.playStoreUrl],
appStoreUrl: consts[CONST_KEYS.appStoreUrl],
webViewHtml: null,
isWebviewClosable: true,
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true,
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? false,
supportMobile: consts[CONST_KEYS.supportMobile] ?? '',
supportEmail: consts[CONST_KEYS.supportEmail] ?? '',
assetsDomain: getAssetsDomain(),

View file

@ -3,7 +3,7 @@ import { SignJWT } from 'jose'
import { z } from 'zod'
import { ApiError } from '@/src/lib/api-error'
import { getEncodedJwtSecret } from '@/src/lib/env-exporter'
import { generateSignedUrlFromS3Url } from '@/src/lib/s3-client'
import { scaffoldAssetUrl } from '@/src/lib/s3-client'
import {
getUserProfileById as getUserProfileByIdInDb,
getUserProfileDetailById as getUserProfileDetailByIdInDb,
@ -46,7 +46,7 @@ export const userRouter = router({
// Generate signed URL for profile image if it exists
const profileImageSignedUrl = userDetail?.profileImage
? await generateSignedUrlFromS3Url(userDetail.profileImage)
? scaffoldAssetUrl(userDetail.profileImage)
: null;
return {

View file

@ -427,11 +427,14 @@ export default function Dashboard() {
const sortedSlots = useMemo(() => {
if (!slotsData?.slots) return [];
return [...slotsData.slots].sort((a, b) => {
const deliveryDiff = dayjs(a.deliveryTime).diff(dayjs(b.deliveryTime));
if (deliveryDiff !== 0) return deliveryDiff;
return dayjs(a.freezeTime).diff(dayjs(b.freezeTime));
});
const now = dayjs();
return [...slotsData.slots]
.filter(slot => dayjs(slot.deliveryTime).isAfter(now))
.sort((a, b) => {
const deliveryDiff = dayjs(a.deliveryTime).diff(dayjs(b.deliveryTime));
if (deliveryDiff !== 0) return deliveryDiff;
return dayjs(a.freezeTime).diff(dayjs(b.freezeTime));
});
}, [slotsData]);
const popularProducts = useMemo(() => {

View file

@ -36,7 +36,7 @@ function useCacheUrl(filename: string): string | null {
export function useAllProducts() {
const cacheUrl = useCacheUrl(CACHE_FILENAMES.products)
console.log({cacheUrl})
return useQuery<ProductsResponse>({
queryKey: ['all-products', cacheUrl],
queryFn: async () => {
@ -54,6 +54,7 @@ export function useAllProducts() {
export function useStores() {
const cacheUrl = useCacheUrl(CACHE_FILENAMES.stores)
console.log(cacheUrl)
return useQuery<StoresResponse>({
queryKey: ['stores', cacheUrl],
queryFn: async () => {

View file

@ -1,6 +1,7 @@
import { db } from '../db/db_index'
import { keyValStore } from '../db/schema'
import { eq } from 'drizzle-orm'
import { CONST_KEYS, castConstValue } from '../lib/const-keys'
export interface Constant {
key: string
@ -12,24 +13,33 @@ export async function getAllConstants(): Promise<Constant[]> {
return constants.map(c => ({
key: c.key,
value: c.value,
value: castConstValue(c.key, c.value),
}))
}
export async function upsertConstants(constants: Constant[]): Promise<void> {
await db.transaction(async (tx) => {
for (const { key, value } of constants) {
await tx.insert(keyValStore)
.values({ key, value })
.onConflictDoUpdate({
target: keyValStore.key,
set: { value },
})
// const castedValue = castConstValue(key, value)
const castedValue = value+'';
const existing = await tx.query.keyValStore.findFirst({
where: eq(keyValStore.key, key),
columns: { key: true },
})
if (existing) {
await tx.update(keyValStore)
.set({ value: castedValue })
.where(eq(keyValStore.key, key))
} else {
await tx.insert(keyValStore)
.values({ key, value: castedValue })
}
}
})
}
const CACHE_VERSION_KEY = 'cache_version'
const CACHE_VERSION_KEY = CONST_KEYS.cacheVersion
const parseCacheVersion = (value: unknown) => {
const parsed = Number(value)

View file

@ -387,7 +387,7 @@ export const refunds = sqliteTable('refunds', {
export const keyValStore = sqliteTable('key_val_store', {
key: text('key').primaryKey(),
value: jsonText<unknown>('value'),
value: text(),
})
export const notifications = sqliteTable('notifications', {

View file

@ -1,5 +1,7 @@
import { db } from '../db/db_index'
import { keyValStore } from '../db/schema'
import { eq } from 'drizzle-orm'
import { castConstValue } from '../lib/const-keys'
export interface Constant {
key: string
@ -11,19 +13,27 @@ export async function getAllConstants(): Promise<Constant[]> {
return constants.map(c => ({
key: c.key,
value: c.value,
value: castConstValue(c.key, c.value),
}))
}
export async function upsertConstants(constants: Constant[]): Promise<void> {
await db.transaction(async (tx) => {
for (const { key, value } of constants) {
await tx.insert(keyValStore)
.values({ key, value })
.onConflictDoUpdate({
target: keyValStore.key,
set: { value },
})
const castedValue = castConstValue(key, value)
const existing = await tx.query.keyValStore.findFirst({
where: eq(keyValStore.key, key),
columns: { key: true },
})
if (existing) {
await tx.update(keyValStore)
.set({ value: castedValue })
.where(eq(keyValStore.key, key))
} else {
await tx.insert(keyValStore)
.values({ key, value: castedValue })
}
}
})
}

View file

@ -12,6 +12,7 @@ export const CONST_KEYS = {
flashDeliverySlotId: 'flashDeliverySlotId',
readableOrderId: 'readableOrderId',
versionNum: 'versionNum',
cacheVersion: 'cache_version',
playStoreUrl: 'playStoreUrl',
appStoreUrl: 'appStoreUrl',
popularItems: 'popularItems',
@ -35,6 +36,7 @@ export const CONST_LABELS: Record<ConstKey, string> = {
flashDeliverySlotId: 'Flash Delivery Slot ID',
readableOrderId: 'Readable Order ID',
versionNum: 'Version Number',
'cache_version': 'Cache Version',
playStoreUrl: 'Play Store URL',
appStoreUrl: 'App Store URL',
popularItems: 'Popular Items',
@ -47,3 +49,83 @@ export const CONST_LABELS: Record<ConstKey, string> = {
export type ConstKey = (typeof CONST_KEYS)[keyof typeof CONST_KEYS]
export const CONST_KEYS_ARRAY = Object.values(CONST_KEYS) as ConstKey[]
export type ConstValueType = 'string' | 'boolean' | 'number'
export const CONST_TYPES: Record<ConstKey, ConstValueType> = {
minRegularOrderValue: 'number',
freeDeliveryThreshold: 'number',
deliveryCharge: 'number',
flashFreeDeliveryThreshold: 'number',
flashDeliveryCharge: 'number',
platformFeePercent: 'number',
taxRate: 'number',
tester: 'string',
minOrderAmountForCoupon: 'number',
maxCouponDiscount: 'number',
flashDeliverySlotId: 'number',
readableOrderId: 'number',
versionNum: 'string',
'cache_version': 'number',
playStoreUrl: 'string',
appStoreUrl: 'string',
popularItems: 'string',
allItemsOrder: 'string',
isFlashDeliveryEnabled: 'boolean',
supportMobile: 'string',
supportEmail: 'string',
}
export const CONST_VISIBILITY: Record<ConstKey, boolean> = {
minRegularOrderValue: true,
freeDeliveryThreshold: true,
deliveryCharge: true,
flashFreeDeliveryThreshold: true,
flashDeliveryCharge: true,
platformFeePercent: true,
taxRate: false,
tester: false,
minOrderAmountForCoupon: true,
maxCouponDiscount: false,
flashDeliverySlotId: true,
readableOrderId: false,
versionNum: true,
'cache_version': false,
playStoreUrl: true,
appStoreUrl: true,
popularItems: true,
allItemsOrder: true,
isFlashDeliveryEnabled: true,
supportMobile: true,
supportEmail: true,
}
export const castConstValue = (key: string, value: unknown) => {
if (!Object.prototype.hasOwnProperty.call(CONST_TYPES, key)) {
return value
}
const type = CONST_TYPES[key as ConstKey]
if (type === 'number') {
const parsed = Number(value)
return Number.isFinite(parsed) ? parsed : 0
}
if (type === 'boolean') {
let newVal = value+'';
if(newVal === '0') {
return false;
}
else if(newVal?.toLowerCase() === 'false') {
return false;
}
return true;
}
if (value === null || value === undefined) {
return ''
}
return String(value)
}

View file

@ -0,0 +1,96 @@
# Local D1 Import (FKs preserved, temporarily disabled)
This guide migrates Postgres -> local D1 while keeping FK definitions and disabling enforcement during import.
## 1) Run Postgres -> SQLite migrator
Ensure schema is `mf` in `packages/migrator/src/config.ts`, then run the migrator to produce:
- `packages/migrator/data/migrated.db`
- `apps/backend/migrated.sql`
Command:
```
cd packages/migrator
npm run migrate:pg-to-sqlite
```
## Dump SQLite DB to SQL
Command:
```
sqlite3 packages/migrator/data/migrated.db ".output apps/backend/migrated.sql" ".dump" ".exit"
```
## 2) Wrap SQL dump to disable FK during inserts
Create `apps/backend/migrated_with_fk_disabled.sql`:
```sql
PRAGMA foreign_keys = OFF;
BEGIN;
-- contents of migrated.sql go here
COMMIT;
PRAGMA foreign_keys = ON;
PRAGMA foreign_key_check;
```
Command (macOS/Linux):
```
cd /Users/mohammedshafiuddin/WebDev/freshyo
{
echo "PRAGMA foreign_keys = OFF;";
echo "BEGIN;";
cat apps/backend/migrated.sql;
echo "COMMIT;";
echo "PRAGMA foreign_keys = ON;";
echo "PRAGMA foreign_key_check;";
} > apps/backend/migrated_with_fk_disabled.sql
```
## 3) Reset local D1 (Miniflare)
Delete local D1 sqlite files:
`apps/backend/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite*`
Command:
```
rm -f apps/backend/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite*
```
Alternative (clean local D1 using wrangler):
```
wrangler d1 execute freshyo-dev --command "DROP TABLE IF EXISTS \"__drizzle_migrations\";"
```
Initialize empty local D1 file:
```
wrangler d1 execute freshyo-dev --command "SELECT 1;"
```
## 4) Import into local D1
```
wrangler d1 execute freshyo-dev --file apps/backend/migrated_with_fk_disabled.sql
```
## 5) Verify
Run:
```sql
PRAGMA foreign_key_check;
```
Command:
```
wrangler d1 execute freshyo-dev --command "PRAGMA foreign_key_check;"
```
## 6) Spot-check counts
```sql
SELECT count(*) FROM product_info;
SELECT count(*) FROM orders;
SELECT count(*) FROM delivery_slot_info;
```
Command:
```
wrangler d1 execute freshyo-dev --command "SELECT count(*) FROM product_info;"
wrangler d1 execute freshyo-dev --command "SELECT count(*) FROM orders;"
wrangler d1 execute freshyo-dev --command "SELECT count(*) FROM delivery_slot_info;"
```

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,8 @@
// PostgreSQL Configuration
export const postgresConfig = {
connectionString: 'postgresql://postgres:meatfarmer_master_password@57.128.212.174:7447/meatfarmer',
connectionString: 'postgresql://postgres:meatfarmer_master_password@raw.freshyo.in:7447/meatfarmer',
// connectionString: 'postgresql://postgres:meatfarmer_master_password@57.128.212.174:7447/meatfarmer',
ssl: false as boolean | { rejectUnauthorized: boolean },
schema: 'mf',
};