diff --git a/apps/backend/.env b/apps/backend/.env index 1606965..92b5602 100755 --- a/apps/backend/.env +++ b/apps/backend/.env @@ -21,6 +21,7 @@ S3_BUCKET_NAME=meatfarmer EXPO_ACCESS_TOKEN=Asvpy8cByRh6T4ksnWScO6PLcio2n35-BwES5zK- JWT_SECRET=my_meatfarmer_jwt_secret_key ASSETS_DOMAIN=https://assets.freshyo.in/ +API_CACHE_KEY='api-cache' # REDIS_URL=redis://default:redis_shafi_password@5.223.55.14:6379 REDIS_URL=redis://default:redis_shafi_password@57.128.212.174:6379 APP_URL=http://localhost:4000 diff --git a/apps/backend/assets/signed-url-cache.json b/apps/backend/assets/signed-url-cache.json index a64a31f..7264388 100644 --- a/apps/backend/assets/signed-url-cache.json +++ b/apps/backend/assets/signed-url-cache.json @@ -1 +1 @@ -{"originalToSigned":{"tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105258Z&X-Amz-Expires=259200&X-Amz-Signature=a4e4226aa30b5f0fde27efca0f139c00df5d3e13d08b104c4aee12afda1f7498&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139918864},"tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=bf52ada07a10aef2f03249480efc7c918389e8711c31dec38c7bae4b922ddfd6&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919079},"tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=3e175d60bbaba792d9dd5d60d4ebad6ad395e9f5f7a00f469e6d74dccec68d59&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919523},"tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T195535Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T195535Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=5cbc2e1c88c8df749d97c59dfec911cbacc58502fd38e97723ee3627e8934d6e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919790},"tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T202804Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T202804Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=aa8adbc434acc3f5c2b8f7a43d300a56df641e21ebefe30510b7e5edbac3e36f&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139920026},"tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=5064525b43e9119a4ec0c19ca134b84697a814c54121f4bca6d2b28582c2fe01&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139920248}},"signedToOriginal":{"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105258Z&X-Amz-Expires=259200&X-Amz-Signature=a4e4226aa30b5f0fde27efca0f139c00df5d3e13d08b104c4aee12afda1f7498&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg","expiresAt":1773139918864},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=bf52ada07a10aef2f03249480efc7c918389e8711c31dec38c7bae4b922ddfd6&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp","expiresAt":1773139919079},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=3e175d60bbaba792d9dd5d60d4ebad6ad395e9f5f7a00f469e6d74dccec68d59&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png","expiresAt":1773139919523},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T195535Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=5cbc2e1c88c8df749d97c59dfec911cbacc58502fd38e97723ee3627e8934d6e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T195535Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject","expiresAt":1773139919790},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T202804Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=aa8adbc434acc3f5c2b8f7a43d300a56df641e21ebefe30510b7e5edbac3e36f&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T202804Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject","expiresAt":1773139920026},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=5064525b43e9119a4ec0c19ca134b84697a814c54121f4bca6d2b28582c2fe01&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg","expiresAt":1773139920248}}} \ No newline at end of file +{"originalToSigned":{"tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105258Z&X-Amz-Expires=259200&X-Amz-Signature=a4e4226aa30b5f0fde27efca0f139c00df5d3e13d08b104c4aee12afda1f7498&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139918864},"tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=bf52ada07a10aef2f03249480efc7c918389e8711c31dec38c7bae4b922ddfd6&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919079},"tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=3e175d60bbaba792d9dd5d60d4ebad6ad395e9f5f7a00f469e6d74dccec68d59&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919523},"tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T195535Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T195535Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=5cbc2e1c88c8df749d97c59dfec911cbacc58502fd38e97723ee3627e8934d6e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139919790},"tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T202804Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T202804Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=aa8adbc434acc3f5c2b8f7a43d300a56df641e21ebefe30510b7e5edbac3e36f&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139920026},"tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=5064525b43e9119a4ec0c19ca134b84697a814c54121f4bca6d2b28582c2fe01&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773139920248},"store-images/1770281046297.jpg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/store-images/1770281046297.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260309%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260309T193417Z&X-Amz-Expires=259200&X-Amz-Signature=271c0272ba9048bfd6785da9284c96ed15cd8f139aac094acc8883513c9adcb1&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773343997623},"store-images/1770429593455.jpg":{"value":"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/store-images/1770429593455.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260309%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260309T193417Z&X-Amz-Expires=259200&X-Amz-Signature=e28f8c17df312e020caad9b63a4af47d1c299be263bf6a2289e1755ce37a5f46&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject","expiresAt":1773343997623}},"signedToOriginal":{"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105258Z&X-Amz-Expires=259200&X-Amz-Signature=a4e4226aa30b5f0fde27efca0f139c00df5d3e13d08b104c4aee12afda1f7498&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1763835253683-c9c3e293-0bef-4c58-a976-dd49c050cd36.jpeg","expiresAt":1773139918864},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=bf52ada07a10aef2f03249480efc7c918389e8711c31dec38c7bae4b922ddfd6&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1763835293899-43b3fbe1-9b5b-441c-b4d4-d1691c3f02f3.webp","expiresAt":1773139919079},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=3e175d60bbaba792d9dd5d60d4ebad6ad395e9f5f7a00f469e6d74dccec68d59&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1768709725124-ebf421c5-ad52-49a9-b65c-1de008110b8a.png","expiresAt":1773139919523},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T195535Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105259Z&X-Amz-Expires=259200&X-Amz-Signature=5cbc2e1c88c8df749d97c59dfec911cbacc58502fd38e97723ee3627e8934d6e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770321659633-1763869265110-e22b6d94-dac9-499f-babb-1e944d90b01a.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T195535Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3D917db15bcc60cab7ac5cd5e49d85d13a960fe77b4a5e327dd449048870494cf9%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject","expiresAt":1773139919790},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%253FX-Amz-Algorithm%253DAWS4-HMAC-SHA256%2526X-Amz-Content-Sha256%253DUNSIGNED-PAYLOAD%2526X-Amz-Credential%253D8fab47503efb9547b50e4fb317e35cc7%25252F20260205%25252Fapac%25252Fs3%25252Faws4_request%2526X-Amz-Date%253D20260205T202804Z%2526X-Amz-Expires%253D259200%2526X-Amz-Signature%253Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%2526X-Amz-SignedHeaders%253Dhost%2526x-amz-checksum-mode%253DENABLED%2526x-id%253DGetObject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=aa8adbc434acc3f5c2b8f7a43d300a56df641e21ebefe30510b7e5edbac3e36f&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770323410499-1763869436182-bf82f7b4-a1f3-4113-985b-96311b7a910e.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3D8fab47503efb9547b50e4fb317e35cc7%252F20260205%252Fapac%252Fs3%252Faws4_request%26X-Amz-Date%3D20260205T202804Z%26X-Amz-Expires%3D259200%26X-Amz-Signature%3Dea436390b277935d843cae6b5cfa62aeed5799cb4a962ab31a0be4b132ca4b30%26X-Amz-SignedHeaders%3Dhost%26x-amz-checksum-mode%3DENABLED%26x-id%3DGetObject","expiresAt":1773139920026},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260307%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260307T105300Z&X-Amz-Expires=259200&X-Amz-Signature=5064525b43e9119a4ec0c19ca134b84697a814c54121f4bca6d2b28582c2fe01&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"tags/1770323560823-fd0ec463-bed0-474e-aa14-dc6480ce36af.jpeg","expiresAt":1773139920248},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/store-images/1770281046297.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260309%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260309T193417Z&X-Amz-Expires=259200&X-Amz-Signature=271c0272ba9048bfd6785da9284c96ed15cd8f139aac094acc8883513c9adcb1&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"store-images/1770281046297.jpg","expiresAt":1773343997623},"https://da9b1aa7c1951c23e2c0c3246ba68a58.r2.cloudflarestorage.com/meatfarmer/store-images/1770429593455.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8fab47503efb9547b50e4fb317e35cc7%2F20260309%2Fapac%2Fs3%2Faws4_request&X-Amz-Date=20260309T193417Z&X-Amz-Expires=259200&X-Amz-Signature=e28f8c17df312e020caad9b63a4af47d1c299be263bf6a2289e1755ce37a5f46&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject":{"value":"store-images/1770429593455.jpg","expiresAt":1773343997623}}} \ No newline at end of file diff --git a/apps/backend/src/lib/cloud_cache.ts b/apps/backend/src/lib/cloud_cache.ts new file mode 100644 index 0000000..e0a0e8c --- /dev/null +++ b/apps/backend/src/lib/cloud_cache.ts @@ -0,0 +1,19 @@ +import { scaffoldProducts } from '@/src/trpc/apis/common-apis/common' +import { imageUploadS3 } from '@/src/lib/s3-client' +import { apiCacheKey } from '@/src/lib/env-exporter' + +export async function createProductsFile(): Promise { + // Get products data from the API method + const productsData = await scaffoldProducts() + + // Convert to JSON string with pretty formatting + const jsonContent = JSON.stringify(productsData, null, 2) + + // Convert to Buffer for S3 upload + const buffer = Buffer.from(jsonContent, 'utf-8') + + // Upload to S3 at the specified path using apiCacheKey + const s3Key = await imageUploadS3(buffer, 'application/json', `${apiCacheKey}/products.json`) + + return s3Key +} diff --git a/apps/backend/src/lib/env-exporter.ts b/apps/backend/src/lib/env-exporter.ts index 57672b1..dde4f77 100755 --- a/apps/backend/src/lib/env-exporter.ts +++ b/apps/backend/src/lib/env-exporter.ts @@ -17,6 +17,8 @@ export const s3Region = process.env.S3_REGION as string export const assetsDomain = process.env.ASSETS_DOMAIN as string; +export const apiCacheKey = process.env.API_CACHE_KEY as string; + export const s3Url = process.env.S3_URL as string export const redisUrl = process.env.REDIS_URL as string diff --git a/apps/backend/src/lib/init.ts b/apps/backend/src/lib/init.ts index 654b195..0c81b3c 100755 --- a/apps/backend/src/lib/init.ts +++ b/apps/backend/src/lib/init.ts @@ -3,6 +3,7 @@ import { initializeAllStores } from '@/src/stores/store-initializer' import { initializeUserNegativityStore } from '@/src/stores/user-negativity-store' import { startOrderHandler, startCancellationHandler, publishOrder } from '@/src/lib/post-order-handler' import { deleteOrders } from '@/src/lib/delete-orders' +import { createProductsFile } from '@/src/lib/cloud_cache' /** * Initialize all application services @@ -25,6 +26,10 @@ export const initFunc = async (): Promise => { startCancellationHandler(), ]); + // Create products cache file after stores are initialized + await createProductsFile(); + console.log('Products cache file created successfully'); + console.log('Application initialization completed successfully'); } catch (error) { console.error('Application initialization failed:', error); diff --git a/apps/backend/src/trpc/apis/common-apis/common-trpc-index.ts b/apps/backend/src/trpc/apis/common-apis/common-trpc-index.ts index 5be1569..1984da5 100644 --- a/apps/backend/src/trpc/apis/common-apis/common-trpc-index.ts +++ b/apps/backend/src/trpc/apis/common-apis/common-trpc-index.ts @@ -9,6 +9,7 @@ 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' +import { assetsDomain, apiCacheKey } from '@/src/lib/env-exporter' const polygon = turf.polygon(mbnrGeoJson.features[0].geometry.coordinates); @@ -115,6 +116,8 @@ export const commonApiRouter = router({ isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true, supportMobile: consts[CONST_KEYS.supportMobile] ?? '', supportEmail: consts[CONST_KEYS.supportEmail] ?? '', + assetsDomain, + apiCacheKey, }; }), }); diff --git a/apps/backend/src/trpc/apis/common-apis/common.ts b/apps/backend/src/trpc/apis/common-apis/common.ts index 9b63dd3..574dd10 100644 --- a/apps/backend/src/trpc/apis/common-apis/common.ts +++ b/apps/backend/src/trpc/apis/common-apis/common.ts @@ -1,12 +1,10 @@ import { router, publicProcedure } from '@/src/trpc/trpc-index' import { db } from '@/src/db/db_index' -import { productInfo, units, productSlots, deliverySlotInfo, storeInfo, productTags, productTagInfo } from '@/src/db/schema' +import { productInfo, units, productSlots, deliverySlotInfo, storeInfo } from '@/src/db/schema' import { eq, gt, and, sql, inArray } from 'drizzle-orm'; import { generateSignedUrlsFromS3Urls, generateSignedUrlFromS3Url } from '@/src/lib/s3-client' -import { z } from 'zod'; import { getAllProducts as getAllProductsFromCache } from '@/src/stores/product-store' import { getDashboardTags as getDashboardTagsFromCache } from '@/src/stores/product-tag-store' -import Fuse from 'fuse.js'; export const getNextDeliveryDate = async (productId: number): Promise => { const result = await db @@ -28,9 +26,50 @@ export const getNextDeliveryDate = async (productId: number): Promise Boolean(item.id)) + // Get suspended product IDs to filter them out + const suspendedProducts = await db + .select({ id: productInfo.id }) + .from(productInfo) + .where(eq(productInfo.isSuspended, true)); + const suspendedProductIds = new Set(suspendedProducts.map(sp => sp.id)); + // Filter out suspended products + products = products.filter(product => !suspendedProductIds.has(product.id)); + + // Format products to match the expected response structure + const formattedProducts = await Promise.all( + products.map(async (product) => { + const nextDeliveryDate = await getNextDeliveryDate(product.id); + return { + id: product.id, + name: product.name, + shortDescription: product.shortDescription, + price: parseFloat(product.price), + marketPrice: product.marketPrice ? parseFloat(product.marketPrice) : null, + unit: product.unitNotation, + unitNotation: product.unitNotation, + incrementStep: product.incrementStep, + productQuantity: product.productQuantity, + storeId: product.store?.id || null, + isOutOfStock: product.isOutOfStock, + isFlashAvailable: product.isFlashAvailable, + nextDeliveryDate: nextDeliveryDate ? nextDeliveryDate.toISOString() : null, + images: product.images, + }; + }) + ); + + return { + products: formattedProducts, + count: formattedProducts.length, + }; +} export const commonRouter = router({ getDashboardTags: publicProcedure @@ -44,89 +83,8 @@ export const commonRouter = router({ }), getAllProductsSummary: publicProcedure - .input(z.object({ - searchQuery: z.string().optional(), - tagId: z.number().optional() - })) - .query(async ({ input }) => { - const { searchQuery, tagId } = input; - - // Get all products from cache - let products = await getAllProductsFromCache(); - products = products.filter(item => Boolean(item.id)) - - // Apply tag filtering if tagId is provided - if (tagId) { - // Get products that have this tag from the database - const taggedProducts = await db - .select({ productId: productTags.productId }) - .from(productTags) - .where(eq(productTags.tagId, tagId)); - - const taggedProductIds = new Set(taggedProducts.map(tp => tp.productId)); - - // Filter products based on tag - products = products.filter(product => taggedProductIds.has(product.id)); - } - - // Apply search filtering if searchQuery is provided using Fuse.js - if (searchQuery) { - const fuse = new Fuse(products, { - keys: [ - 'name', - 'shortDescription', - 'longDescription', - 'store.name', // Search in store name too - 'productTags', // Search in product tags too - ], - threshold: 0.3, // Adjust fuzziness (0.0 = exact match, 1.0 = match anything) - includeScore: true, - shouldSort: true, - }); - - const fuseResults = fuse.search(searchQuery); - products = fuseResults.map(result => result.item); - } - - // Get suspended product IDs to filter them out - const suspendedProducts = await db - .select({ id: productInfo.id }) - .from(productInfo) - .where(eq(productInfo.isSuspended, true)); - - const suspendedProductIds = new Set(suspendedProducts.map(sp => sp.id)); - - // Filter out suspended products - products = products.filter(product => !suspendedProductIds.has(product.id)); - - // Format products to match the expected response structure - const formattedProducts = await Promise.all( - products.map(async (product) => { - const nextDeliveryDate = await getNextDeliveryDate(product.id); - return { - id: product.id, - name: product.name, - shortDescription: product.shortDescription, - price: parseFloat(product.price), - marketPrice: product.marketPrice ? parseFloat(product.marketPrice) : null, - unit: product.unitNotation, - unitNotation: product.unitNotation, - incrementStep: product.incrementStep, - productQuantity: product.productQuantity, - storeId: product.store?.id || null, - isOutOfStock: product.isOutOfStock, - isFlashAvailable: product.isFlashAvailable, - nextDeliveryDate: nextDeliveryDate ? nextDeliveryDate.toISOString() : null, - images: product.images, // Already signed URLs from cache - }; - }) - ); - - - return { - products: formattedProducts, - count: formattedProducts.length, - }; + .query(async () => { + return scaffoldProducts(); }), getStoresSummary: publicProcedure diff --git a/apps/backend/src/trpc/router.ts b/apps/backend/src/trpc/router.ts index 6d357ee..54d96c6 100644 --- a/apps/backend/src/trpc/router.ts +++ b/apps/backend/src/trpc/router.ts @@ -3,6 +3,7 @@ import { z } from 'zod'; import { adminRouter } from '@/src/trpc/apis/admin-apis/apis/admin-trpc-index' import { userRouter } from '@/src/trpc/apis/user-apis/apis/user-trpc-index' import { commonApiRouter } from '@/src/trpc/apis/common-apis/common-trpc-index' +import { scaffoldProducts } from './apis/common-apis/common'; // Create the main app router export const appRouter = router({ @@ -16,5 +17,8 @@ export const appRouter = router({ common: commonApiRouter, }); + // Export type definition of API -export type AppRouter = typeof appRouter; \ No newline at end of file +export type AppRouter = typeof appRouter; + +export type AllProductsApiType = Awaited>; diff --git a/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx index d378136..fd6bb7e 100755 --- a/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx @@ -21,6 +21,7 @@ import AddToCartDialog from "@/src/components/AddToCartDialog"; import MyFlatList from "common-ui/src/components/flat-list"; import { trpc } from "@/src/trpc-client"; +import { useAllProducts } from "@/src/hooks/prominent-api-hooks"; import { useProductSlotIdentifier } from "@/hooks/useProductSlotIdentifier"; import FloatingCartBar from "@/components/floating-cart-bar"; import BannerCarousel from "@/components/BannerCarousel"; @@ -360,8 +361,6 @@ export default function Dashboard() { const router = useRouter(); const userDetails = useUserDetails(); const [inputQuery, setInputQuery] = useState(""); - const [searchQuery, setSearchQuery] = useState(""); - const [selectedTagId, setSelectedTagId] = useState(null); const [isLoadingDialogOpen, setIsLoadingDialogOpen] = useState(false); const [gradientHeight, setGradientHeight] = useState(0); const [displayedProducts, setDisplayedProducts] = useState([]); @@ -376,10 +375,7 @@ export default function Dashboard() { isLoading, error, refetch, - } = trpc.common.product.getAllProductsSummary.useQuery({ - searchQuery: searchQuery || undefined, - tagId: selectedTagId || undefined, - }); + } = useAllProducts(); const { data: essentialConsts, isLoading: isLoadingConsts, error: constsError, refetch: refetchConsts } = useGetEssentialConsts(); diff --git a/apps/user-ui/app/(drawer)/(tabs)/home/search-results/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/home/search-results/index.tsx index b7a1b17..b54b74c 100644 --- a/apps/user-ui/app/(drawer)/(tabs)/home/search-results/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/home/search-results/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect, useCallback } from "react"; +import React, { useState, useRef, useEffect, useCallback, useMemo } from "react"; import { View, Dimensions } from "react-native"; import { useRouter, useLocalSearchParams } from "expo-router"; import { @@ -10,7 +10,8 @@ import { SearchBar, } from "common-ui"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; -import { trpc } from "@/src/trpc-client"; +import Fuse from "fuse.js"; +import { useAllProducts } from "@/src/hooks/prominent-api-hooks"; import ProductCard from "@/components/ProductCard"; import FloatingCartBar from "@/components/floating-cart-bar"; @@ -51,12 +52,27 @@ export default function SearchResults() { }); }, []); - const { data: productsData, isLoading, error, refetch } = - trpc.common.product.getAllProductsSummary.useQuery({ - searchQuery: debouncedQuery || undefined, + const { data: productsData, isLoading, error, refetch } = useAllProducts(); + + const allProducts = productsData?.products || []; + + // Client-side search filtering using Fuse.js + const products = useMemo(() => { + if (!debouncedQuery.trim()) return allProducts; + + const fuse = new Fuse(allProducts, { + keys: [ + 'name', + 'shortDescription', + ], + threshold: 0.3, + includeScore: true, + shouldSort: true, }); - const products = productsData?.products || []; + const fuseResults = fuse.search(debouncedQuery); + return fuseResults.map(result => result.item); + }, [allProducts, debouncedQuery]); useManualRefresh(() => { refetch(); diff --git a/apps/user-ui/components/PaymentAndOrderComponent.tsx b/apps/user-ui/components/PaymentAndOrderComponent.tsx index 713aefe..7e9f998 100644 --- a/apps/user-ui/components/PaymentAndOrderComponent.tsx +++ b/apps/user-ui/components/PaymentAndOrderComponent.tsx @@ -6,6 +6,7 @@ import MaterialIcons from '@expo/vector-icons/MaterialIcons'; // import RazorpayCheckout from 'react-native-razorpay'; import { trpc } from '@/src/trpc-client'; +import { useAllProducts } from '@/src/hooks/prominent-api-hooks'; import { clearLocalCart } from '@/hooks/cart-query-hooks'; import { useQueryClient } from '@tanstack/react-query'; import { FontAwesome5, FontAwesome6 } from '@expo/vector-icons'; @@ -54,7 +55,7 @@ const PaymentAndOrderComponent: React.FC = ({ queryClient.invalidateQueries({ queryKey: [`local-cart-${cartType}`] }); }; - const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({}); + const { data: productsData } = useAllProducts(); // Memoized flash-eligible product IDs const flashEligibleProductIds = useMemo(() => { diff --git a/apps/user-ui/components/SlotSpecificView.tsx b/apps/user-ui/components/SlotSpecificView.tsx index 8a9c5ec..cac6b97 100644 --- a/apps/user-ui/components/SlotSpecificView.tsx +++ b/apps/user-ui/components/SlotSpecificView.tsx @@ -7,6 +7,7 @@ import { useRouter, usePathname } from 'expo-router'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { tw, theme, MyText, MyTouchableOpacity, MyFlatList, AppContainer, MiniQuantifier } from 'common-ui'; import { trpc } from '@/src/trpc-client'; +import { useAllProducts } from '@/src/hooks/prominent-api-hooks'; import { useQuickDeliveryStore } from '@/src/store/quickDeliveryStore'; import { useAddToCart, useGetCart, useUpdateCartItem, useRemoveFromCart } from '@/hooks/cart-query-hooks'; import { useHideTabNav } from '@/src/hooks/useHideTabNav'; @@ -348,7 +349,7 @@ export function SlotProducts({ slotId:slotIdParent, storeId:storeIdParent, baseU const slotQuery = trpc.user.slots.getSlotById.useQuery({ slotId: slotId! }, { enabled: !!slotId }); - const productsQuery = trpc.common.product.getAllProductsSummary.useQuery({}); + const productsQuery = useAllProducts(); const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "regular") || {}; @@ -448,7 +449,7 @@ export function FlashDeliveryProducts({ storeId:storeIdParent, baseUrl, onProduc const storeId = storeIdParent; const storeIdNum = storeId; - const productsQuery = trpc.common.product.getAllProductsSummary.useQuery({}); + const productsQuery = useAllProducts(); const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "flash") || {}; diff --git a/apps/user-ui/components/cart-page.tsx b/apps/user-ui/components/cart-page.tsx index cae6dc7..e8a58d4 100644 --- a/apps/user-ui/components/cart-page.tsx +++ b/apps/user-ui/components/cart-page.tsx @@ -24,6 +24,7 @@ import TestingPhaseNote from "@/components/TestingPhaseNote"; import dayjs from "dayjs"; import { trpc } from "@/src/trpc-client"; +import { useAllProducts } from "@/src/hooks/prominent-api-hooks"; import { useGetCart, useUpdateCartItem, useRemoveFromCart } from '@/hooks/cart-query-hooks'; import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api'; @@ -80,7 +81,7 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) { const { data: couponsRaw, error: couponsError } = trpc.user.coupon.getEligible.useQuery(); const { data: constsData } = useGetEssentialConsts(); - const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({}); + const { data: productsData } = useAllProducts(); const cartItems = cartData?.items || []; diff --git a/apps/user-ui/components/checkout-page.tsx b/apps/user-ui/components/checkout-page.tsx index 1f25ec5..d7934f2 100644 --- a/apps/user-ui/components/checkout-page.tsx +++ b/apps/user-ui/components/checkout-page.tsx @@ -8,6 +8,7 @@ import AddressForm from '@/src/components/AddressForm'; import { useAuthenticatedRoute } from '@/hooks/useAuthenticatedRoute'; import { trpc } from '@/src/trpc-client'; +import { useAllProducts } from '@/src/hooks/prominent-api-hooks'; import { useGetCart } from '@/hooks/cart-query-hooks'; import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api'; import PaymentAndOrderComponent from '@/components/PaymentAndOrderComponent'; @@ -35,7 +36,7 @@ const CheckoutPage: React.FC = ({ isFlashDelivery = false }) const { data: addresses, refetch: refetchAddresses } = trpc.user.address.getUserAddresses.useQuery(); const { data: slotsData, refetch: refetchSlots } = trpc.user.slots.getSlots.useQuery(); const { data: constsData } = useGetEssentialConsts(); - const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({}); + const { data: productsData } = useAllProducts(); useMarkDataFetchers(() => { refetchCart(); diff --git a/apps/user-ui/hooks/cart-query-hooks.tsx b/apps/user-ui/hooks/cart-query-hooks.tsx index 49d7d7e..4f975f4 100644 --- a/apps/user-ui/hooks/cart-query-hooks.tsx +++ b/apps/user-ui/hooks/cart-query-hooks.tsx @@ -1,4 +1,5 @@ import { trpc } from '@/src/trpc-client'; +import { useAllProducts } from '@/src/hooks/prominent-api-hooks'; import { Alert } from 'react-native'; import { useState, useEffect } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; @@ -133,7 +134,7 @@ export function useGetCart(options?: { }; } else { - const { data: products } = trpc.common.product.getAllProductsSummary.useQuery({}); + const { data: products } = useAllProducts(); const query = useQuery({ queryKey: [`local-cart-${cartType}`], queryFn: async () => { diff --git a/apps/user-ui/package.json b/apps/user-ui/package.json index 026136f..6c5da91 100644 --- a/apps/user-ui/package.json +++ b/apps/user-ui/package.json @@ -48,6 +48,7 @@ "expo-updates": "~0.28.17", "expo-web-browser": "~14.2.0", "formik": "^2.4.6", + "fuse.js": "^7.1.0", "jwt-decode": "^4.0.0", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/apps/user-ui/src/hooks/prominent-api-hooks.ts b/apps/user-ui/src/hooks/prominent-api-hooks.ts new file mode 100644 index 0000000..d7d4bce --- /dev/null +++ b/apps/user-ui/src/hooks/prominent-api-hooks.ts @@ -0,0 +1,34 @@ +import { useQuery } from '@tanstack/react-query' +import axios from 'axios' +import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api' +// import { AllProductsApiType } from '@backend/trpc/router' +import { AllProductsApiType } from "@backend/trpc/router"; + + +type ProductsResponse = AllProductsApiType; + +export function useAllProducts() { + const { data: essentialConsts } = useGetEssentialConsts() + + const assetsDomain = essentialConsts?.assetsDomain + const apiCacheKey = essentialConsts?.apiCacheKey + + const cacheUrl = assetsDomain && apiCacheKey + ? `${assetsDomain}${apiCacheKey}/products.json` + : null + + return useQuery({ + queryKey: ['all-products', cacheUrl], + queryFn: async () => { + if (!cacheUrl) { + throw new Error('Cache URL not available') + } + console.log(cacheUrl) + + const response = await axios.get(cacheUrl) + return response.data + }, + staleTime: 60000, // 1 minute + enabled: !!cacheUrl, + }) +} diff --git a/package-lock.json b/package-lock.json index 64a526b..1294227 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "expo-crypto": "~14.1.5", "expo-server-sdk": "^5.0.0", "expo-web-browser": "~14.2.0", + "fuse.js": "^7.1.0", "node-cron": "^4.2.1", "pg": "^8.20.0", "react": "19.0.0", @@ -507,6 +508,7 @@ "expo-updates": "~0.28.17", "expo-web-browser": "~14.2.0", "formik": "^2.4.6", + "fuse.js": "^7.1.0", "jwt-decode": "^4.0.0", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/package.json b/package.json index 569f52f..e0a27a8 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "expo-crypto": "~14.1.5", "expo-server-sdk": "^5.0.0", "expo-web-browser": "~14.2.0", + "fuse.js": "^7.1.0", "node-cron": "^4.2.1", "pg": "^8.20.0", "react": "19.0.0", diff --git a/packages/ui/index.ts b/packages/ui/index.ts index 30549a9..ac64e7d 100755 --- a/packages/ui/index.ts +++ b/packages/ui/index.ts @@ -64,9 +64,9 @@ const isDevMode = Constants.executionEnvironment !== "standalone"; // const BASE_API_URL = 'http://10.0.2.2:4000'; // const BASE_API_URL = 'http://192.168.100.101:4000'; // const BASE_API_URL = 'http://192.168.1.5:4000'; -let BASE_API_URL = "https://mf.freshyo.in"; +// let BASE_API_URL = "https://mf.freshyo.in"; // let BASE_API_URL = "https://freshyo.technocracy.ovh"; -// let BASE_API_URL = 'http://192.168.100.107:4000'; +let BASE_API_URL = 'http://192.168.100.107:4000'; // let BASE_API_URL = 'http://192.168.29.176:4000'; // if(isDevMode) {