From 7ad1b8135684c5b950bb2d748a68637254318f49 Mon Sep 17 00:00:00 2001 From: shafi54 <108669266+shafi-aviz@users.noreply.github.com> Date: Sat, 5 Sep 2026 11:12:47 +0530 Subject: [PATCH] enh --- .gitignore | 1 + .../dashboard/product-groupings/index.tsx | 10 +- .../(drawer)/dashboard/product-tags/add.tsx | 9 +- apps/admin-ui/components/ProductGroupForm.tsx | 2 +- apps/admin-ui/src/components/TagForm.tsx | 2 +- .../src/trpc/apis/user-apis/apis/auth.ts | 15 +- .../src/components/AuthWrapper.tsx | 7 +- .../src/components/SuperAdminGuard.tsx | 7 +- apps/fallback-ui/tsconfig.json | 6 + .../user-ui/app/(drawer)/(tabs)/home/cart.tsx | 5 +- .../app/(drawer)/(tabs)/home/checkout.tsx | 5 +- .../app/(drawer)/(tabs)/home/index.tsx | 7 +- .../(drawer)/(tabs)/me/complaints/index.tsx | 5 +- .../app/(drawer)/(tabs)/order-again/index.tsx | 10 +- apps/user-ui/components/ComplaintForm.tsx | 7 +- apps/user-ui/components/FirstUserWrapper.tsx | 7 +- apps/user-ui/components/HealthTestWrapper.tsx | 7 +- .../components/LocationTestWrapper.tsx | 9 +- apps/user-ui/components/UpdateChecker.tsx | 7 +- apps/user-ui/components/WebViewWrapper.tsx | 7 +- .../services/notif-service/notif-context.tsx | 8 +- apps/user-ui/src/components/AddressForm.tsx | 20 +-- .../components/CentralStoreInitializer.tsx | 7 +- apps/user-ui/src/contexts/AuthContext.tsx | 9 +- apps/user-ui/src/store/cartStore.ts | 12 +- apps/user-ui/src/store/flashCartStore.ts | 6 +- apps/user-ui/src/store/storeHeaderStore.ts | 6 +- apps/web-ui/src/components/AddressForm.tsx | 20 +-- apps/web-ui/src/components/ComplaintForm.tsx | 7 +- apps/web-ui/src/lib/stores/cart-store.ts | 12 +- .../src/lib/stores/store-header-store.ts | 6 +- apps/web-ui/src/routes/flash.tsx | 7 +- apps/web-ui/src/routes/me.complaints.tsx | 5 +- apps/web-ui/src/routes/offers.tsx | 10 +- apps/web-ui/src/routes/slot-view.tsx | 7 +- change-log.txt | 130 ++++++++++++++++++ .../db_helper_postgres/src/user-apis/order.ts | 45 +----- .../db_helper_sqlite/src/user-apis/order.ts | 48 +------ packages/shared/types/admin.ts | 12 +- packages/shared/types/app-common.types.ts | 91 ++++++------ packages/shared/types/cache.types.ts | 18 --- packages/shared/types/index.ts | 1 + packages/shared/types/primitives.types.ts | 14 +- packages/shared/types/seed.types.ts | 9 +- packages/shared/types/user.ts | 26 +--- packages/ui/src/components/app-container.tsx | 7 +- .../src/components/image-carousel.tsx | 2 +- .../src/components/image-gallery.tsx | 6 +- scripts/dead-code/user-ui-files.js | 48 ------- scripts/dead-code/user-ui-store-actions.js | 34 ----- scripts/dead-code/user-ui-store-final.js | 36 ----- scripts/dead-code/user-ui-store-precise.js | 33 ----- scripts/dead-code/user-ui-suspects.js | 54 -------- scripts/dead-code/user-ui-symbols.js | 62 --------- 54 files changed, 261 insertions(+), 692 deletions(-) delete mode 100644 scripts/dead-code/user-ui-files.js delete mode 100644 scripts/dead-code/user-ui-store-actions.js delete mode 100644 scripts/dead-code/user-ui-store-final.js delete mode 100644 scripts/dead-code/user-ui-store-precise.js delete mode 100644 scripts/dead-code/user-ui-suspects.js delete mode 100644 scripts/dead-code/user-ui-symbols.js diff --git a/.gitignore b/.gitignore index d550c42..42935ab 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,4 @@ dist .pnp.* +type-clusters/* \ No newline at end of file diff --git a/apps/admin-ui/app/(drawer)/dashboard/product-groupings/index.tsx b/apps/admin-ui/app/(drawer)/dashboard/product-groupings/index.tsx index de4806c..e547cc0 100644 --- a/apps/admin-ui/app/(drawer)/dashboard/product-groupings/index.tsx +++ b/apps/admin-ui/app/(drawer)/dashboard/product-groupings/index.tsx @@ -15,15 +15,7 @@ import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { LinearGradient } from "expo-linear-gradient"; import dayjs from "dayjs"; import { useRouter } from "expo-router"; - -interface ProductGroup { - id: number; - groupName: string; - description: string | null; - createdAt: string; - products: any[]; - productCount: number; -} +import type { ProductGroup } from "@/components/ProductGroupForm"; const GroupItem = ({ group, diff --git a/apps/admin-ui/app/(drawer)/dashboard/product-tags/add.tsx b/apps/admin-ui/app/(drawer)/dashboard/product-tags/add.tsx index 32b8c34..effe66e 100644 --- a/apps/admin-ui/app/(drawer)/dashboard/product-tags/add.tsx +++ b/apps/admin-ui/app/(drawer)/dashboard/product-tags/add.tsx @@ -5,14 +5,7 @@ import { AppContainer, MyText, tw, type ImageUploaderNeoItem } from 'common-ui'; import TagForm from '@/src/components/TagForm'; import { trpc } from '@/src/trpc-client'; import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStore'; - -interface TagFormData { - tagName: string; - tagDescription: string; - isDashboardTag: boolean; - relatedStores: number[]; - productIds: number[]; -} +import type { TagFormData } from '@/src/components/TagForm'; export default function AddTag() { const router = useRouter(); diff --git a/apps/admin-ui/components/ProductGroupForm.tsx b/apps/admin-ui/components/ProductGroupForm.tsx index 216a93d..d8fbd12 100644 --- a/apps/admin-ui/components/ProductGroupForm.tsx +++ b/apps/admin-ui/components/ProductGroupForm.tsx @@ -6,7 +6,7 @@ import ProductsSelector from './ProductsSelector'; import { trpc } from '../src/trpc-client'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -interface ProductGroup { +export interface ProductGroup { id: number; groupName: string; description: string | null; diff --git a/apps/admin-ui/src/components/TagForm.tsx b/apps/admin-ui/src/components/TagForm.tsx index f54f77e..63a0f0e 100644 --- a/apps/admin-ui/src/components/TagForm.tsx +++ b/apps/admin-ui/src/components/TagForm.tsx @@ -13,7 +13,7 @@ import type { IdName } from '@packages/shared'; type StoreOption = IdName; -interface TagFormData { +export interface TagFormData { tagName: string; tagDescription: string; isDashboardTag: boolean; diff --git a/apps/backend/src/trpc/apis/user-apis/apis/auth.ts b/apps/backend/src/trpc/apis/user-apis/apis/auth.ts index af5a4e1..712e178 100644 --- a/apps/backend/src/trpc/apis/user-apis/apis/auth.ts +++ b/apps/backend/src/trpc/apis/user-apis/apis/auth.ts @@ -25,21 +25,10 @@ import type { UserOtpVerifyResponse, UserPasswordUpdateResponse, UserDeleteAccountResponse, + LoginRequest, + RegisterRequest, } from '@packages/shared' -interface LoginRequest { - identifier: string; - password: string; -} - -interface RegisterRequest { - name: string; - email: string; - mobile: string; - password: string; - profileImageUrl?: string | null; -} - const generateToken = async (userId: number): Promise => { return await new SignJWT({ userId }) .setProtectedHeader({ alg: 'HS256' }) diff --git a/apps/fallback-ui/src/components/AuthWrapper.tsx b/apps/fallback-ui/src/components/AuthWrapper.tsx index 4af3353..6103f92 100644 --- a/apps/fallback-ui/src/components/AuthWrapper.tsx +++ b/apps/fallback-ui/src/components/AuthWrapper.tsx @@ -3,12 +3,9 @@ import { useNavigate } from '@tanstack/react-router' import { trpc } from '@/trpc/client' import { useUserStore } from '@/stores/userStore' import { getCurrentUserId } from '@/services/auth' +import type { ReactParentComponent } from '@packages/shared' -interface AuthWrapperProps { - children: React.ReactNode -} - -export function AuthWrapper({ children }: AuthWrapperProps) { +export function AuthWrapper({ children }: ReactParentComponent) { const navigate = useNavigate() const { setUser, setLoading, setError, user, isLoading } = useUserStore() diff --git a/apps/fallback-ui/src/components/SuperAdminGuard.tsx b/apps/fallback-ui/src/components/SuperAdminGuard.tsx index 1c1231e..e4fea0a 100644 --- a/apps/fallback-ui/src/components/SuperAdminGuard.tsx +++ b/apps/fallback-ui/src/components/SuperAdminGuard.tsx @@ -1,10 +1,7 @@ import { useUserStore } from '@/stores/userStore'; +import type { ReactParentComponent } from '@packages/shared'; -interface SuperAdminGuardProps { - children: React.ReactNode; -} - -export function SuperAdminGuard({ children }: SuperAdminGuardProps) { +export function SuperAdminGuard({ children }: ReactParentComponent) { const { user } = useUserStore(); const allowedRoles = ['super_admin']; // Only super_admin role can access super admin features diff --git a/apps/fallback-ui/tsconfig.json b/apps/fallback-ui/tsconfig.json index 42f4600..b56e6b1 100644 --- a/apps/fallback-ui/tsconfig.json +++ b/apps/fallback-ui/tsconfig.json @@ -26,6 +26,12 @@ ], "@/src/*": [ "../backend/src/*" + ], + "@packages/shared": [ + "../../packages/shared" + ], + "@packages/shared/*": [ + "../../packages/shared/*" ] }, "types": [ diff --git a/apps/user-ui/app/(drawer)/(tabs)/home/cart.tsx b/apps/user-ui/app/(drawer)/(tabs)/home/cart.tsx index b4d61d3..00e68c2 100644 --- a/apps/user-ui/app/(drawer)/(tabs)/home/cart.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/home/cart.tsx @@ -1,10 +1,7 @@ import CartPage from '@/components/cart-page' import React from 'react' -interface Props {} - -function Cart(props: Props) { - const {} = props +function Cart() { return ( diff --git a/apps/user-ui/app/(drawer)/(tabs)/home/checkout.tsx b/apps/user-ui/app/(drawer)/(tabs)/home/checkout.tsx index 0d40fb1..01a34f5 100644 --- a/apps/user-ui/app/(drawer)/(tabs)/home/checkout.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/home/checkout.tsx @@ -1,10 +1,7 @@ import CheckoutPage from '@/components/checkout-page'; import React from 'react'; -interface Props {} - -function Checkout(props: Props) { - const {} = props; +function Checkout() { return ; } diff --git a/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx index b4ee60b..bdd4065 100755 --- a/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/home/index.tsx @@ -325,12 +325,7 @@ const TagScene = memo(({ ); }); -interface ExploreProductItemProps { - item: any; - onPress: (id: number) => void; -} - -const ExploreProductItem = memo(({ item, onPress }: ExploreProductItemProps) => { +const ExploreProductItem = memo(({ item, onPress }: ProductItemProps) => { const handlePress = useCallback(() => onPress(item.id), [item.id, onPress]); return ( diff --git a/apps/user-ui/app/(drawer)/(tabs)/me/complaints/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/me/complaints/index.tsx index 67240ff..a8f5516 100644 --- a/apps/user-ui/app/(drawer)/(tabs)/me/complaints/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/me/complaints/index.tsx @@ -7,10 +7,7 @@ import { trpc } from '@/src/trpc-client'; import { useGetEssentialConsts } from '@/src/hooks/prominent-api-hooks'; import dayjs from 'dayjs'; import { useRouter } from 'expo-router'; - -interface ComplaintItemProps { - item: any; -} +import type { ComplaintItemProps } from '@packages/shared'; const ComplaintItem: React.FC = ({ item }) => ( diff --git a/apps/user-ui/app/(drawer)/(tabs)/order-again/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/order-again/index.tsx index 800abe5..805329b 100644 --- a/apps/user-ui/app/(drawer)/(tabs)/order-again/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/order-again/index.tsx @@ -10,6 +10,7 @@ import { MyTouchableOpacity, } from "common-ui"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; +import type { OffersSectionProps } from '@packages/shared'; import ProductCard from "@/components/ProductCard"; import { useAllProducts } from "@/src/hooks/prominent-api-hooks"; import FloatingCartBar from "@/components/floating-cart-bar"; @@ -20,15 +21,6 @@ const { width: screenWidth } = Dimensions.get("window"); const heroItemWidth = (screenWidth - 72) / 3; const SHOW_MORE_STEP = 6; -interface OffersSectionProps { - title: string; - subtitle: string; - products: any[]; - expanded: boolean; - onExpand: () => void; - onProductPress: (id: number) => void; -} - // Grid section (home page style): shows the first SHOW_MORE_STEP products // with a "Show More" button to reveal the rest. const OffersSection = ({ diff --git a/apps/user-ui/components/ComplaintForm.tsx b/apps/user-ui/components/ComplaintForm.tsx index 61b91e6..403f964 100644 --- a/apps/user-ui/components/ComplaintForm.tsx +++ b/apps/user-ui/components/ComplaintForm.tsx @@ -4,12 +4,7 @@ import { MaterialIcons } from '@expo/vector-icons' import { MyText, ImageUploaderNeo, tw, MyTouchableOpacity, type ImageUploaderNeoItem, type ImageUploaderNeoPayload } from 'common-ui' import { trpc } from '@/src/trpc-client' import { useUploadToObjectStorage } from '../hooks/useUploadToObjectStore' - -interface ComplaintFormProps { - open: boolean; - onClose: () => void; - orderId: number; -} +import type { ComplaintFormProps } from '@packages/shared' export default function ComplaintForm({ open, onClose, orderId }: ComplaintFormProps) { const [complaintBody, setComplaintBody] = useState(''); diff --git a/apps/user-ui/components/FirstUserWrapper.tsx b/apps/user-ui/components/FirstUserWrapper.tsx index 38ce3ec..a6d624b 100644 --- a/apps/user-ui/components/FirstUserWrapper.tsx +++ b/apps/user-ui/components/FirstUserWrapper.tsx @@ -1,12 +1,9 @@ import React, { useState, useEffect } from 'react' import { View } from 'react-native' import { MyButton, StorageServiceCasual, tw, MyText } from 'common-ui' +import type { ReactParentComponent } from '@packages/shared' -interface Props { - children: React.ReactNode -} - -const FirstUserWrapper: React.FC = ({ children }) => { +const FirstUserWrapper: React.FC = ({ children }) => { const [isFirstTime, setIsFirstTime] = useState(null) useEffect(() => { diff --git a/apps/user-ui/components/HealthTestWrapper.tsx b/apps/user-ui/components/HealthTestWrapper.tsx index bc8387f..6d24ad8 100644 --- a/apps/user-ui/components/HealthTestWrapper.tsx +++ b/apps/user-ui/components/HealthTestWrapper.tsx @@ -5,12 +5,9 @@ import { trpc, trpcClient } from '@/src/trpc-client'; import { useGetEssentialConsts } from '@/src/hooks/prominent-api-hooks'; import Constants from 'expo-constants'; import * as Linking from 'expo-linking'; +import type { ReactParentComponent } from '@packages/shared'; -interface HealthTestWrapperProps { - children: React.ReactNode; -} - -const HealthTestWrapper: React.FC = ({ children }) => { +const HealthTestWrapper: React.FC = ({ children }) => { const { data, isLoading, error, refetch } = trpc.common.healthCheck.useQuery(); const { data: backendConsts } = useGetEssentialConsts(); diff --git a/apps/user-ui/components/LocationTestWrapper.tsx b/apps/user-ui/components/LocationTestWrapper.tsx index b6c2a9d..d85a70f 100644 --- a/apps/user-ui/components/LocationTestWrapper.tsx +++ b/apps/user-ui/components/LocationTestWrapper.tsx @@ -1,7 +1,8 @@ -import React, { useState, useEffect, ReactNode } from 'react'; +import React, { useState, useEffect } from 'react'; import * as Location from 'expo-location'; import { BackHandler, Platform } from 'react-native'; import { ConfirmationDialog } from 'common-ui'; +import type { ReactParentComponent } from '@packages/shared'; import { trpc } from '../src/trpc-client'; // Emulator detection utility @@ -41,14 +42,10 @@ const isEmulator = (): boolean => { } }; -interface LocationTestWrapperProps { - children: ReactNode; -} - // Feature flag to enable/disable location warning dialogs const ENABLE_LOCATION_WARNINGS = false; -const LocationTestWrapper: React.FC = ({ children }) => { +const LocationTestWrapper: React.FC = ({ children }) => { // Skip location checks entirely for emulators if (isEmulator()) { return <>{children}; diff --git a/apps/user-ui/components/UpdateChecker.tsx b/apps/user-ui/components/UpdateChecker.tsx index e73cd18..50a3265 100644 --- a/apps/user-ui/components/UpdateChecker.tsx +++ b/apps/user-ui/components/UpdateChecker.tsx @@ -1,12 +1,9 @@ import React, { useEffect } from 'react'; import * as Updates from 'expo-updates'; import { Alert } from 'react-native'; +import type { ReactParentComponent } from '@packages/shared'; -interface UpdateCheckerProps { - children: React.ReactNode; -} - -const UpdateChecker: React.FC = ({ children }) => { +const UpdateChecker: React.FC = ({ children }) => { useEffect(() => { const checkForUpdates = async () => { try { diff --git a/apps/user-ui/components/WebViewWrapper.tsx b/apps/user-ui/components/WebViewWrapper.tsx index 8293643..9135731 100644 --- a/apps/user-ui/components/WebViewWrapper.tsx +++ b/apps/user-ui/components/WebViewWrapper.tsx @@ -5,12 +5,9 @@ import { trpc } from '@/src/trpc-client'; import { useGetEssentialConsts } from '@/src/hooks/prominent-api-hooks'; import { MyTouchableOpacity } from 'common-ui'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; +import type { ReactParentComponent } from '@packages/shared'; -interface WebViewWrapperProps { - children: React.ReactNode; -} - -export default function WebViewWrapper({ children }: WebViewWrapperProps) { +export default function WebViewWrapper({ children }: ReactParentComponent) { const { data: constsData } = useGetEssentialConsts(); const [isClosed, setIsClosed] = useState(false); diff --git a/apps/user-ui/services/notif-service/notif-context.tsx b/apps/user-ui/services/notif-service/notif-context.tsx index 9af8a0a..7cd583e 100755 --- a/apps/user-ui/services/notif-service/notif-context.tsx +++ b/apps/user-ui/services/notif-service/notif-context.tsx @@ -4,13 +4,13 @@ import React, { useState, useEffect, useRef, - ReactNode, } from "react"; import * as Notifications from "expo-notifications"; import { registerForPushNotificationsAsync } from "./notif-register"; import { useRouter } from "expo-router"; import { NotificationToast } from "../toaster"; import { NOTIF_PERMISSION_DENIED } from "common-ui/src/lib/const-strs"; +import type { ReactParentComponent } from '@packages/shared'; interface NotificationContextType { expoPushToken: string | null; @@ -33,11 +33,7 @@ export const useNotification = () => { return context; }; -interface NotificationProviderProps { - children: ReactNode; -} - -export const NotificationProvider: React.FC = ({ +export const NotificationProvider: React.FC = ({ children, }) => { const [expoPushToken, setExpoPushToken] = useState(null); diff --git a/apps/user-ui/src/components/AddressForm.tsx b/apps/user-ui/src/components/AddressForm.tsx index 30a45f5..f914419 100644 --- a/apps/user-ui/src/components/AddressForm.tsx +++ b/apps/user-ui/src/components/AddressForm.tsx @@ -7,25 +7,7 @@ import { tw, MyText, MyTouchableOpacity , Checkbox , MyTextInput , LoadingDialog import { trpc } from '../trpc-client'; import LocationAttacher from './LocationAttacher'; import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view'; - -interface AddressFormProps { - onSuccess: (addressId?: number) => void; - initialValues?: { - id?: number; - name: string; - phone: string; - addressLine1: string; - addressLine2: string; - city: string; - state: string; - pincode: string; - isDefault: boolean; - latitude?: number; - longitude?: number; - googleMapsUrl?: string; - }; - isEdit?: boolean; -} +import type { AddressFormProps } from '@packages/shared'; const AddressForm: React.FC = ({ onSuccess, initialValues, isEdit = false }) => { const [isSubmitting, setIsSubmitting] = useState(false); diff --git a/apps/user-ui/src/components/CentralStoreInitializer.tsx b/apps/user-ui/src/components/CentralStoreInitializer.tsx index faa6b53..312a7e6 100644 --- a/apps/user-ui/src/components/CentralStoreInitializer.tsx +++ b/apps/user-ui/src/components/CentralStoreInitializer.tsx @@ -1,12 +1,9 @@ import React from 'react'; import { useInitializeCentralSlotStore } from '@/src/store/centralSlotStore'; import { useInitializeCentralProductStore } from '@/src/store/centralProductStore'; +import type { ReactParentComponent } from '@packages/shared'; -interface CentralStoreInitializerProps { - children: React.ReactNode; -} - -export default function CentralStoreInitializer({ children }: CentralStoreInitializerProps) { +export default function CentralStoreInitializer({ children }: ReactParentComponent) { useInitializeCentralSlotStore(); useInitializeCentralProductStore(); diff --git a/apps/user-ui/src/contexts/AuthContext.tsx b/apps/user-ui/src/contexts/AuthContext.tsx index cfd7b37..def78c5 100644 --- a/apps/user-ui/src/contexts/AuthContext.tsx +++ b/apps/user-ui/src/contexts/AuthContext.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; +import React, { createContext, useContext, useState, useEffect } from 'react'; import { getAuthToken, saveAuthToken, deleteAuthToken, saveUserId, getUserId } from '../../hooks/useJWT'; import { getCurrentUserId } from '@/utils/getCurrentUserId'; import { useRegister } from '@/src/api-hooks/auth.api'; @@ -7,6 +7,7 @@ import { trpc } from '@/src/trpc-client'; import { StorageServiceCasual } from 'common-ui'; import { useRouter } from 'expo-router'; import constants from '@/src/constants'; +import type { ReactParentComponent } from '@packages/shared'; export interface RedirectState { targetUrl: string; @@ -16,11 +17,7 @@ export interface RedirectState { const AuthContext = createContext(undefined); -interface AuthProviderProps { - children: ReactNode; -} - -export const AuthProvider: React.FC = ({ children }) => { +export const AuthProvider: React.FC = ({ children }) => { const router = useRouter(); const [authState, setAuthState] = useState({ user: null, diff --git a/apps/user-ui/src/store/cartStore.ts b/apps/user-ui/src/store/cartStore.ts index 3c3394a..1981158 100644 --- a/apps/user-ui/src/store/cartStore.ts +++ b/apps/user-ui/src/store/cartStore.ts @@ -1,15 +1,5 @@ import { create } from 'zustand'; - -interface AddedToCartProduct { - productId: number; - product: any; -} - -interface CartStore { - addedToCartProduct: AddedToCartProduct | null; - setAddedToCartProduct: (product: AddedToCartProduct | null) => void; - clearAddedToCartProduct: () => void; -} +import type { AddedToCartProduct, CartStore } from '@packages/shared'; export const useCartStore = create((set) => ({ addedToCartProduct: null, diff --git a/apps/user-ui/src/store/flashCartStore.ts b/apps/user-ui/src/store/flashCartStore.ts index ac8909b..814673f 100644 --- a/apps/user-ui/src/store/flashCartStore.ts +++ b/apps/user-ui/src/store/flashCartStore.ts @@ -1,9 +1,7 @@ import { create } from 'zustand'; +import type { AddedToCartProduct } from '@packages/shared'; -interface AddedFlashProduct { - productId: number; - product: any; -} +type AddedFlashProduct = AddedToCartProduct; interface FlashCartStore { addedFlashProduct: AddedFlashProduct | null; diff --git a/apps/user-ui/src/store/storeHeaderStore.ts b/apps/user-ui/src/store/storeHeaderStore.ts index 70a4a46..b358e55 100644 --- a/apps/user-ui/src/store/storeHeaderStore.ts +++ b/apps/user-ui/src/store/storeHeaderStore.ts @@ -1,9 +1,5 @@ import { create } from 'zustand'; - -interface StoreHeaderState { - title: string; - setTitle: (title: string) => void; -} +import type { StoreHeaderState } from '@packages/shared'; export const useStoreHeaderStore = create((set) => ({ title: '', diff --git a/apps/web-ui/src/components/AddressForm.tsx b/apps/web-ui/src/components/AddressForm.tsx index cd98465..7fb2f8b 100644 --- a/apps/web-ui/src/components/AddressForm.tsx +++ b/apps/web-ui/src/components/AddressForm.tsx @@ -3,25 +3,7 @@ import { trpc } from '../lib/trpc-client' import { p, pInput, MyButton, div } from 'web-components' import { MapPin, X, Plus } from 'lucide-react' import * as Yup from 'yup' - -interface AddressFormProps { - onSuccess: (addressId?: number) => void - initialValues?: { - id?: number - name: string - phone: string - addressLine1: string - addressLine2: string - city: string - state: string - pincode: string - isDefault: boolean - latitude?: number - longitude?: number - googleMapsUrl?: string - } - isEdit?: boolean -} +import type { AddressFormProps } from '@packages/shared' const validationSchema = Yup.object({ name: Yup.string().required('Name is required'), diff --git a/apps/web-ui/src/components/ComplaintForm.tsx b/apps/web-ui/src/components/ComplaintForm.tsx index 3f1a1eb..76456f0 100644 --- a/apps/web-ui/src/components/ComplaintForm.tsx +++ b/apps/web-ui/src/components/ComplaintForm.tsx @@ -2,12 +2,7 @@ import { useState, useRef } from 'react' import { X, Upload, ImageIcon, Loader2 } from 'lucide-react' import { trpc } from '../lib/trpc-client' import { useUploadToObjectStorage } from '../hooks/useUploadToObjectStorage' - -interface ComplaintFormProps { - open: boolean - onClose: () => void - orderId: number -} +import type { ComplaintFormProps } from '@packages/shared' interface ComplaintImage { imgUrl: string diff --git a/apps/web-ui/src/lib/stores/cart-store.ts b/apps/web-ui/src/lib/stores/cart-store.ts index 65ba029..86e53da 100644 --- a/apps/web-ui/src/lib/stores/cart-store.ts +++ b/apps/web-ui/src/lib/stores/cart-store.ts @@ -1,15 +1,5 @@ import { create } from 'zustand' - -interface AddedToCartProduct { - productId: number - product: any -} - -interface CartStore { - addedToCartProduct: AddedToCartProduct | null - setAddedToCartProduct: (product: AddedToCartProduct | null) => void - clearAddedToCartProduct: () => void -} +import type { AddedToCartProduct, CartStore } from '@packages/shared' export const useCartStore = create((set) => ({ addedToCartProduct: null, diff --git a/apps/web-ui/src/lib/stores/store-header-store.ts b/apps/web-ui/src/lib/stores/store-header-store.ts index 4536380..73b916b 100644 --- a/apps/web-ui/src/lib/stores/store-header-store.ts +++ b/apps/web-ui/src/lib/stores/store-header-store.ts @@ -1,9 +1,7 @@ import { create } from 'zustand' +import type { StoreHeaderState } from '@packages/shared' -interface StoreHeaderStore { - title: string - setTitle: (title: string) => void -} +type StoreHeaderStore = StoreHeaderState export const useStoreHeaderStore = create((set) => ({ title: '', diff --git a/apps/web-ui/src/routes/flash.tsx b/apps/web-ui/src/routes/flash.tsx index a1a67c0..fa8049a 100644 --- a/apps/web-ui/src/routes/flash.tsx +++ b/apps/web-ui/src/routes/flash.tsx @@ -9,6 +9,7 @@ import { usePopulateCentralStores } from '../hooks/usePopulateCentralStores' import { usePopulateCentralProductStore } from '../hooks/usePopulateCentralProductStore' import { AppLayout } from '../components/AppLayout' import { Zap, ShoppingCart } from 'lucide-react' +import type { CompactProductCardProps } from '@packages/shared' export const Route = createFileRoute('/flash')({ component: FlashDeliveryPage, @@ -203,12 +204,6 @@ const formatQuantity = ( return { value: `${quantity} ${unit}(s)`, display: `${quantity}${unit}` }; }; -interface CompactProductCardProps { - item: any; - handleAddToCart: (productId: number) => void; - onPress?: () => void; -} - function CompactProductCard({ item, handleAddToCart, diff --git a/apps/web-ui/src/routes/me.complaints.tsx b/apps/web-ui/src/routes/me.complaints.tsx index fc1f510..6eea4f1 100644 --- a/apps/web-ui/src/routes/me.complaints.tsx +++ b/apps/web-ui/src/routes/me.complaints.tsx @@ -6,13 +6,10 @@ import { useGetEssentialConsts } from '../hooks/prominent-api-hooks' import dayjs from 'dayjs' import { Dialog } from '../components/Dialog' import { useState } from 'react' +import type { ComplaintItemProps } from '@packages/shared' export const Route = createFileRoute('/me/complaints')({ component: ComplaintsPage }) -interface ComplaintItemProps { - item: any -} - function ComplaintItem({ item }: ComplaintItemProps) { return (
diff --git a/apps/web-ui/src/routes/offers.tsx b/apps/web-ui/src/routes/offers.tsx index 875f5ce..b8a9545 100644 --- a/apps/web-ui/src/routes/offers.tsx +++ b/apps/web-ui/src/routes/offers.tsx @@ -4,20 +4,12 @@ import { trpc } from '../lib/trpc-client' import { Tag, Loader2, AlertCircle } from 'lucide-react' import { ProductCard } from '../components/ProductCard' import { AppLayout } from '../components/AppLayout' +import type { OffersSectionProps } from '@packages/shared' export const Route = createFileRoute('/offers')({ component: OffersPage }) const SHOW_MORE_STEP = 6 -interface OffersSectionProps { - title: string - subtitle: string - products: any[] - expanded: boolean - onExpand: () => void - onProductPress: (id: number) => void -} - function OffersSection({ title, subtitle, products, expanded, onExpand, onProductPress }: OffersSectionProps) { const visible = expanded ? products : products.slice(0, SHOW_MORE_STEP) const hasMore = products.length > SHOW_MORE_STEP && !expanded diff --git a/apps/web-ui/src/routes/slot-view.tsx b/apps/web-ui/src/routes/slot-view.tsx index 4ba45ab..528a79b 100644 --- a/apps/web-ui/src/routes/slot-view.tsx +++ b/apps/web-ui/src/routes/slot-view.tsx @@ -28,6 +28,7 @@ import { usePopulateCentralProductStore } from "../hooks/usePopulateCentralProdu import { AppLayout } from "../components/AppLayout"; import { Truck, Store, Grid3X3, ChevronLeft, ShoppingCart, Clock, ChevronDown } from "lucide-react"; import { Dialog } from "../components/Dialog"; +import type { CompactProductCardProps } from '@packages/shared'; export const Route = createFileRoute("/slot-view")({ component: SlotViewPage, @@ -397,12 +398,6 @@ const formatQuantity = ( return { value: `${quantity} ${unit}(s)`, display: `${quantity}${unit}` }; }; -interface CompactProductCardProps { - item: any; - handleAddToCart: (productId: number) => void; - onPress?: () => void; -} - function CompactProductCard({ item, handleAddToCart, diff --git a/change-log.txt b/change-log.txt index d9c90a7..bdc0a3e 100644 --- a/change-log.txt +++ b/change-log.txt @@ -854,3 +854,133 @@ Centralized in @packages/shared and re-used: - Fixed as found: app-common.types.ts added to shared index star-exports; AvailabilityEntry export added in user-ui hooks; 3 dangling store-helpers re-exports repaired Verification: backend 11, sqlite 4, user-ui 106, admin-ui 122 (all = baselines); pg 45 = 40 + 5 pg-coupon casts that reproduce with byte-restored admin.ts (pre-existing drift from prior session, documented in report §8). Zero errors mention any unified name. Deliberately NOT unified (documented in repeat_types_glm.md §8 + change-log): drifted input types (coupon/tag/slot/product), InferSelectModel *Row aliases (schema-bound), ui<->web-components (no cross-dep), migrator ColumnInfo (field names differ per direction), CartData (element types differ), backend banner-store Banner (subset shape), const-keys files (different key sets). + +[2026-09-05 00:24:25] PHASE 5: unify remaining verified exact-duplicate types. +- shared primitives.types.ts: added BasicSuccessResponse {success: boolean} +- shared admin.ts: AdminDeleteProductResult, AdminSlotDeleteResult → aliases of MessageResponse; AdminSlotUpdateResult → alias of AdminSlotCreateResult +- shared user.ts: UserSavePushTokenResponse → alias of BasicSuccessResponse; UserDeliverySlot → alias of AdminDeliverySlot (+import from ./admin; no cycle — admin.ts does not import user.ts) +- shared app-common.types.ts: DELETED zero-consumer stale CartData (wrong element type), DropdownOption, CartIconProps; REPLACED stale AddressFormProps with the real current shape; ADDED StoreHeaderState, CartStore, AddedToCartProduct, CompactProductCardProps, ComplaintItemProps +- admin-ui TagForm.tsx: exported TagFormData; product-tags/add.tsx: deleted local, imports it (edit/index.tsx extended version untouched) +- admin-ui ProductGroupForm.tsx: exported ProductGroup; product-groupings/index.tsx: deleted local, imports it +- user-ui + web-ui AddressForm: deleted locals, import shared AddressFormProps +- user-ui + web-ui ComplaintForm: deleted locals, import shared ComplaintFormProps +- web-ui flash.tsx + slot-view.tsx: deleted local CompactProductCardProps, import shared +- user-ui complaints/index.tsx + web-ui me.complaints.tsx: deleted local ComplaintItemProps, import shared +- user-ui cartStore + web-ui cart-store: deleted local AddedToCartProduct + CartStore, import shared; flashCartStore: AddedFlashProduct → alias of shared AddedToCartProduct +- user-ui storeHeaderStore + web-ui store-header-store: deleted local state interfaces, import shared StoreHeaderState; web-ui keeps hook name via type StoreHeaderStore = StoreHeaderState +- user-ui home/index.tsx: deleted ExploreProductItemProps, uses ProductItemProps +- user-ui cart.tsx + checkout.tsx: deleted empty Props{} + dropped unused props params +- backend order.ts: deleted second DeliveryStatus/OrderStatus pair (lines ~477-478), first pair serves both scopes +NOT unified (verified different or out of scope, documented): ChipProps/TagChipProps (different Tag element types), Tag pair (productIds? vs imageUrl), ProductsResponse family (backend-circular), CartData element types, StoreHeaderSt— n/a, migrator ColumnInfo, ui<->web props, fallback-ui 3d props, ProductsResponseAlias/ProductsResponse placeholders. + +[2026-09-05 00:30:00] CORRECTION: reverted deletion of backend order.ts second DeliveryStatus/OrderStatus pair — both pairs are function-scoped (different closures), not file duplicates. No change needed there; cluster 49/50 verdict in types_inventory was wrong on scope. + +[2026-09-05 00:35:00] PHASE 5 (continued): unify remaining verified exact-duplicates; CORRECTIONS for two over-eager aliases. +- shared primitives.types.ts: added BasicSuccessResponse {success: boolean} +- shared admin.ts: AdminSlotUpdateResult → alias of AdminSlotCreateResult; AdminOrderBasicResult → alias of BasicSuccessResponse +- shared user.ts: UserDeliverySlot → alias of AdminDeliverySlot (+import; no cycle) +- shared app-common.types.ts rewritten: DELETED zero-consumer stale CartData (wrong element type), DropdownOption, CartIconProps, RedirectState, VendorSnippetProduct, ProductsResponseAlias/ProductsResponse placeholders; REPLACED stale AddressFormProps with real shape; ADDED StoreHeaderState, CartStore, AddedToCartProduct, CompactProductCardProps, ComplaintItemProps +- user-ui + web-ui cart stores: local AddedToCartProduct + CartStore deleted, import shared; flashCartStore AddedFlashProduct → alias +- user-ui storeHeaderStore + web-ui store-header-store: locals deleted, import shared StoreHeaderState (web-ui keeps name via alias) +- user-ui + web-ui AddressForm/ComplaintForm: locals deleted, import shared +- web-ui flash.tsx + slot-view.tsx: local CompactProductCardProps deleted, import shared +- user-ui complaints + web-ui me.complaints: local ComplaintItemProps deleted, import shared +- admin-ui TagForm.tsx: TagFormData exported; product-tags/add.tsx imports it (edit/index extended version untouched) +- admin-ui ProductGroupForm.tsx: ProductGroup exported; product-groupings/index.tsx imports it +- user-ui home/index.tsx: ExploreProductItemProps deleted (uses ProductItemProps) +- user-ui cart.tsx + checkout.tsx: empty Props{} + unused props params deleted +- CORRECTION 1: reverted AdminDeleteProductResult/AdminSlotDeleteResult → MessageResponse aliases — backend procedures return {message} without success; aliasing changed the contract (tsc proved it). Restored local {message} interfaces. ({success,message}×9 aliases unaffected — identical contracts.) +- CORRECTION 2: removed accidentally-duplicated UserSavePushTokenResponse alias line in user.ts (duplicate identifier). +- CORRECTION 3: reverted backend order.ts DeliveryStatus/OrderStatus deletion — both pairs are function-scoped, not file duplicates. +- NOT unified (verified): ChipProps/TagChipProps (different Tag element types), Tag pair, ProductsResponse family (backend-circular), StoreHeader n/a, AdminCancelOrderError (union, not same shape), OffersSectionProps (single def), Props usage n/a. + +[2026-09-05 00:40:00] CREATED analysis script scripts/subset-types.js (read-only subset/superset scanner; outputs scripts/subset-types-raw.json). No source changes in this entry. + +[2026-09-05 00:47:00] PHASE 6: unify remaining verified exact-duplicates. +- shared seed.types.ts: KeyValSeedData → alias of Constant (+import from ./const.types; no cycle — const.types has no imports) +- shared user.ts: UserProductStoreInfo → alias of StoreSummary (+import from ./store.types; no cycle) +- shared cache.types.ts: DELETED PlacedOrderShape (zero consumers repo-wide; db PlacedOrder in order.types.ts is canonical) +- backend auth.ts: deleted local LoginRequest/RegisterRequest, import from '@packages/shared' (same treatment user-ui got) +- sqlite+pg user-apis/order.ts: OrderDetailWithRelations → alias of OrderWithRelations (verified byte-identical bodies 879/879 and 820/820) +- shared app-common.types.ts: added FlashDeliveryProps {isFlashDelivery?: boolean} +- user-ui cart-page/checkout-page + web-ui FloatingCartBar: {isFlashDelivery?} prop interfaces → aliases of shared FlashDeliveryProps +- user-ui home/index.tsx: deleted RenderStoreProps, uses SlotItemProps (same file, identical) +- web-components image-gallery.tsx: ImageGalleryProps → alias of ImageCarouselProps (same package) +NOT unified (verified): Tag pair user-ui/web-ui (name-collision risk with backend's richer Tag — same judgment as ChipProps pair); DropdownOption pair (ui has extra disabled?); ImageUploader/quantifier/dialog/checkbox/profile/search props (independent RN/web packages); CharactersProps (fallback-ui, out of scope); ProductsResponse family (backend-circular); migrator TableInfo (ColumnInfo differs); AndSnippets vs Base (verified DIFFERENT — WithAccess vs plain vendor snippets); SkuSummary admin-ui (sqlite's not exported via index); RegisterRequest backend done above. + +[2026-09-05 10:01:39] COMPLETED Phase 6 second wave + full verification. +- shared: KeyValSeedData→Constant, UserProductStoreInfo→StoreSummary, AdminOrderBasicResult+UserSavePushTokenResponse→BasicSuccessResponse (new primitive), AdminSlotUpdateResult→AdminSlotCreateResult, UserDeliverySlot→AdminDeliverySlot, AdminDeleteProductResult + AdminSlotDeleteResult restored as local {message} (contract — backend returns message-only), app-common rewritten (real AddressFormProps; added StoreHeaderState/CartStore/AddedToCartProduct/CompactProductCardProps/ComplaintItemProps; deleted stale CartData/DropdownOption/CartIconProps/RedirectState/VendorSnippetProduct/placeholders) +- backend auth.ts: LoginRequest/RegisterRequest → shared imports +- db packages: OrderDetailWithRelations → alias (both, byte-identical verified); PlacedOrderShape deleted (zero consumers) +- admin-ui: TagFormData/ProductGroup canonical in form components; VendorSnippetProduct/StoreOption/Staff → IdName aliases +- user-ui + web-ui: cart/header stores, AddressForm, ComplaintForm, CompactProductCardProps, ComplaintItemProps → shared; ExploreProductItemProps/Props{}/RenderStoreProps removed +- web-ui store-header keeps hook name via alias +Verification: backend 11, sqlite 4, pg 45 (40+5 pre-existing coupon casts), user-ui 106, admin-ui 122 — all baselines hold; web-ui 150 (no baseline; errors are pre-existing JSX friction, none touch unified names). +Left deliberately (verified): Tag pair (backend name-collision risk), DropdownOption pair (ui has extra disabled?), ui<->web prop mirrors (independent packages), ChipProps pair, ProductsResponse family, migrator ColumnInfo, AndSnippets vs Base (verified DIFFERENT), fallback-ui (out of scope), drifted inputs, InferSelectModel rows, SkuSummary (not exported via index), DeliveryStatus/OrderStatus (function-scoped), OffersSectionProps (single), Props usage n/a. + +[2026-09-05 10:10:00] Regen unification: OffersSectionProps (web-ui offers.tsx + user-ui order-again/index.tsx, verified identical) → shared app-common.types.ts; both routes import it. + +[2026-09-05 10:20:00] Regen unification round 2: OffersSectionProps → shared app-common (web-ui offers + user-ui order-again import it); ImageGalleryProps → alias of ImageCarouselProps (same package web-components). + +[2026-09-05 10:22:00] web-components image-carousel.tsx: exported ImageCarouselProps (needed by image-gallery.tsx alias). + +[2026-09-05 10:30:00] Regen catch: packages/shared/types/cache.types.ts declared ProductTagData TWICE (bad merge) — deleted the duplicate second copy. No consumers affected (same shape). + +[2026-09-05 10:35:00] REGENERATED types_inventory.md via new scripts/gen-inventory.js + scripts/render-inventory.js (read-only analysis scripts). +- Fresh harvest: 562 files, 620 declarations, 490 unique names, 42 single-identifier aliases (classified separately), 98 duplicate names, 56 clusters, 698 any-hits. +- Harvest fixes vs 09-03 edition: import/export-block lines never harvested (~17 bogus clusters gone); aliases excluded from shape clustering (new Unified Aliases section); React. qualifier stripped; optionality ignored (documented). +- Fixed as found during regen: duplicate ProductTagData in shared cache.types.ts (deleted 2nd copy); ImageGalleryProps → alias of ImageCarouselProps (+export added); OffersSectionProps → shared app-common (web-ui + user-ui import it). +- Verification: backend 11, sqlite 4, user-ui 106, admin-ui 122, pg 45 (40+5 pre-existing) — all baselines hold; web-components 3 pre-existing JSX errors, untouched by edits. + +[2026-09-05 10:45:00] CREATED analysis scripts (read-only): scripts/gen-inventory.js (types harvest + clustering), scripts/render-inventory.js (md renderer with per-cluster verdicts), scripts/gen-cluster-files.js (per-cluster md files with full defs + consumers), scripts/update-inventory.js (one-off patch helper for the 09-03 edition; superseded by regeneration). +GENERATED: type-clusters/ folder (56 cluster files + README index). +REGENERATED: types_inventory.md from current tree (replaces 09-03 snapshot + manual annotations). + +[2026-09-05 10:57:13] DELETE all agent-created analysis scripts (user request — remove, not needed; nothing references them in code or configs). +Deleted files in scripts/: +- gen-cluster-files.js, gen-inventory.js, render-inventory.js, update-inventory.js +- subset-types.js, subset-types-raw.json, types-inventory-data.json +Deleted directory scripts/dead-code/ entirely (contained only agent-created files): +- user-ui-files.js, user-ui-symbols.js, user-ui-suspects.js, user-ui-store-actions.js, user-ui-store-final.js, user-ui-store-precise.js +KEPT (pre-existing, not mine): scripts/clear-db-old.sql, scripts/clear-db.sql, scripts/s3-cleaner.js, scripts/s3-sync.js +Follow-up md-only cleanup: subset_types_glm.md lines referencing the deleted scripts reworded (no code impact). + +[2026-09-05 11:03:50] ADD shared ReactParentComponent for Cluster-1 unification. +=== packages/shared/types/primitives.types.ts === +- added type-only react import + new interface (appended): + import type { ReactNode } from 'react' + export interface ReactParentComponent { + children: ReactNode + } +- header comment updated: leaf module rule now reads "no runtime imports (type-only imports erased at compile are fine)". + +[2026-09-05 11:06:00] Cluster-1 unification: replace 9 local children-only interfaces with shared ReactParentComponent (user-ui + ui). +- LocationTestWrapper.tsx: delete lines 44-46 (interface LocationTestWrapperProps); add shared type import; `: LocationTestWrapperProps` → `: ReactParentComponent` at use site line 51 +- HealthTestWrapper.tsx: delete lines 9-11 (interface HealthTestWrapperProps); add import; `React.FC` → `React.FC` +- WebViewWrapper.tsx: delete lines 9-11; add import; `{ children }: WebViewWrapperProps` → `{ children }: ReactParentComponent` +- FirstUserWrapper.tsx: delete lines 5-7 (interface Props); add import; `React.FC` → `React.FC` +- UpdateChecker.tsx: delete lines 5-7; add import; `React.FC` → `React.FC` +- notif-context.tsx: delete lines 36-38; add import; `React.FC` → `React.FC` +- AuthContext.tsx: delete lines 19-21; add import; `React.FC` → `React.FC` +- CentralStoreInitializer.tsx: delete lines 5-7; add import; `{ children }: CentralStoreInitializerProps` → `{ children }: ReactParentComponent` +- ui app-container.tsx: delete lines 7-9 (interface Props); add import; `(props: Props)` → `(props: ReactParentComponent)` +Import line used everywhere: import type { ReactParentComponent } from '@packages/shared' +Excluded: MyTouchableOpacityProps (optional children + extends — different shape); other files' same-named Props (different interfaces, verified). + +[2026-09-05 11:10:00] CORRECTION (LocationTestWrapper): my first edit inserted a duplicate component declaration (interface did not directly precede the component). Repaired — file now has single component with ReactParentComponent annotation, interface + comment preserved correctly. + +[2026-09-05 11:07:29] Cluster-1 fallback-ui: add @packages/shared path mapping to tsconfig (mirrors user-ui mapping), replace SuperAdminGuardProps + AuthWrapperProps with shared ReactParentComponent. +- apps/fallback-ui/tsconfig.json paths: added "@packages/shared": ["../../packages/shared"], "@packages/shared/*": ["../../packages/shared/*"] +- SuperAdminGuard.tsx: deleted lines 3-5 interface; added shared type import; `{ children }: SuperAdminGuardProps` → `{ children }: ReactParentComponent` +- AuthWrapper.tsx: deleted lines 7-9 interface; added shared type import; `{ children }: AuthWrapperProps` → `{ children }: ReactParentComponent` + +[2026-09-05 11:08:15] Cluster-1 cleanup: remove now-unused ReactNode named imports (orphaned by interface deletions). +- notif-context.tsx: removed `ReactNode,` from react import block +- AuthContext.tsx: removed `ReactNode` from react import list + +[2026-09-05 11:09:00] Cluster-1 cleanup: remove orphaned ReactNode named import in LocationTestWrapper.tsx (only remaining ReactNode use was the deleted interface). + +[2026-09-05 11:12:00] FIX: shared/types/index.ts never starred primitives.types (existing MessageResponse/IdName only surfaced via admin.ts re-export). Added export type * from './primitives.types'; so ReactParentComponent resolves from '@packages/shared'. + +[2026-09-05 11:15:00] COMPLETED Cluster-1 ReactParentComponent unification (11 files + shared def + fallback-ui tsconfig). +Verification: user-ui 106, admin-ui 122, backend 11 (all = baselines); fallback-ui 107 total with zero errors in touched files. Zero leftover local interfaces. Docs: cluster-01 file + types_inventory status section marked resolved. diff --git a/packages/db_helper_postgres/src/user-apis/order.ts b/packages/db_helper_postgres/src/user-apis/order.ts index c5b34ae..b14273f 100644 --- a/packages/db_helper_postgres/src/user-apis/order.ts +++ b/packages/db_helper_postgres/src/user-apis/order.ts @@ -67,50 +67,7 @@ export interface OrderWithRelations { }> } -export interface OrderDetailWithRelations { - id: number - userId: number - addressId: number - slotId: number | null - totalAmount: string - deliveryCharge: string - isCod: boolean - isOnlinePayment: boolean - isFlashDelivery: boolean - userNotes: string | null - createdAt: Date - orderItems: Array<{ - id: number - productId: number - quantity: string - price: string - discountedPrice: string | null - is_packaged: boolean - product: { - id: number - name: string - images: unknown - } - }> - slot: { - deliveryTime: Date - } | null - paymentInfo: { - id: number - status: string - } | null - orderStatus: Array<{ - id: number - isCancelled: boolean - isDelivered: boolean - paymentStatus: string - cancelReason: string | null - }> - refunds: Array<{ - refundStatus: string - refundAmount: string | null - }> -} +export type OrderDetailWithRelations = OrderWithRelations; export interface CouponValidationResult { id: number diff --git a/packages/db_helper_sqlite/src/user-apis/order.ts b/packages/db_helper_sqlite/src/user-apis/order.ts index c171ca5..6b7c985 100644 --- a/packages/db_helper_sqlite/src/user-apis/order.ts +++ b/packages/db_helper_sqlite/src/user-apis/order.ts @@ -74,53 +74,7 @@ export interface OrderWithRelations { }> } -export interface OrderDetailWithRelations { - id: number - userId: number - addressId: number - slotId: number | null - totalAmount: string - deliveryCharge: string - isCod: boolean - isOnlinePayment: boolean - isFlashDelivery: boolean - userNotes: string | null - createdAt: Date - orderItems: Array<{ - id: number - skuId: number - quantity: string - price: string - discountedPrice: string | null - is_packaged: boolean - sku: { - id: number - name: string | null - images: unknown - product: { - name: string - } | null - } | null - }> - slot: { - deliveryTime: Date - } | null - paymentInfo: { - id: number - status: string - } | null - orderStatus: Array<{ - id: number - isCancelled: boolean - isDelivered: boolean - paymentStatus: string - cancelReason: string | null - }> - refunds: Array<{ - refundStatus: string - refundAmount: string | null - }> -} +export type OrderDetailWithRelations = OrderWithRelations; export interface CouponValidationResult { id: number diff --git a/packages/shared/types/admin.ts b/packages/shared/types/admin.ts index 1492d22..a99178e 100644 --- a/packages/shared/types/admin.ts +++ b/packages/shared/types/admin.ts @@ -2,7 +2,7 @@ // (Entity shapes live in the dedicated per-domain files — re-exported here // so existing `@packages/shared` consumers keep working from one surface.) -import type { MessageResponse, IdName } from './primitives.types' +import type { MessageResponse, BasicSuccessResponse, IdName } from './primitives.types' export type { Banner } from './banner.types' export type { Complaint, ComplaintWithUser } from './complaint.types' export type { Constant, ConstantUpdateResult } from './const.types' @@ -189,9 +189,7 @@ export interface AdminOrderItemPackagingResult { export type AdminOrderMessageResult = MessageResponse -export interface AdminOrderBasicResult { - success: boolean; -} +export type AdminOrderBasicResult = BasicSuccessResponse export interface AdminSlotOrderItem { id: number; @@ -595,11 +593,7 @@ export interface AdminSlotCreateResult { message: string; } -export interface AdminSlotUpdateResult { - slot: AdminDeliverySlot; - createdSnippets: AdminVendorSnippet[]; - message: string; -} +export type AdminSlotUpdateResult = AdminSlotCreateResult export interface AdminSlotDeleteResult { message: string; diff --git a/packages/shared/types/app-common.types.ts b/packages/shared/types/app-common.types.ts index 3f1588e..0b307b5 100644 --- a/packages/shared/types/app-common.types.ts +++ b/packages/shared/types/app-common.types.ts @@ -1,16 +1,9 @@ /** * App-Common Types - * Duplicated identically across apps (admin-ui / user-ui / web-ui / ui). + * Duplicated identically across apps (admin-ui / user-ui / web-ui). * Kept in @packages/shared so all apps import one source. */ -// --- Upload / prominent hooks (already in upload.types.ts, but also include the indexed aliases) --- -// AvailabilityEntry is `AvailabilityApiType['availability'][number]` — not shareable generically; -// apps keep that local. The truly shared hook aliases are the response type aliases: -export type ProductsResponseAlias = import('./user').UserProductDetailData -// For the literal alias trio that were copy-pasted across user-ui ↔ web-ui: -export type ProductsResponse = import('./user').UserProductDetailData // placeholder — apps re-export via AllProductsApiType - // --- Forms / shared UI --- export interface LoginFormInputs { mobile: string @@ -24,62 +17,62 @@ export interface ComplaintFormProps { orderId: number } -// Duplicate across user-ui hooks ↔ web-ui hooks -export interface CartData { - items: import('./user').CartItem[] - totalAmount: number - totalItems: number -} - -// Cart icon props duplicated in user-ui ↔ ui -export interface CartIconProps { - color: string - focused: boolean - size: number -} - -// Address form props duplicated user-ui ↔ web-ui +// Address form props — identical in user-ui + web-ui AddressForm components export interface AddressFormProps { - addressLine1: string - addressLine2: string - city: string - googleMapsUrl?: string - id?: number + onSuccess: (addressId?: number) => void initialValues?: { + id?: number + name: string + phone: string addressLine1: string addressLine2: string city: string + state: string + pincode: string + isDefault: boolean + latitude?: number + longitude?: number googleMapsUrl?: string } - isDefault: boolean + isEdit?: boolean } -// Shared UI dropdown — duplicated ui ↔ web-components -export interface DropdownOption { - label: string - value: string | number +// Complaint item — identical in user-ui + web-ui complaints lists +export interface ComplaintItemProps { + item: any } -// ImageUploaderNeo — duplicated ui ↔ web-components -export interface ImageUploaderNeoItem { - imgUrl: string - mimeType: string | null +// Compact product card — identical in web-ui flash.tsx + slot-view.tsx +export interface CompactProductCardProps { + item: any + handleAddToCart: (productId: number) => void + onPress?: () => void } -export interface ImageUploaderNeoPayload { - url: string - mimeType: string | null +// Offers section — identical in web-ui offers.tsx + user-ui order-again/index.tsx +export interface OffersSectionProps { + title: string + subtitle: string + products: any[] + expanded: boolean + onExpand: () => void + onProductPress: (id: number) => void } -// Navigation redirect state — duplicated in user-ui hooks ↔ contexts -export interface RedirectState { - targetUrl: string - queryParams: Record - timestamp: number +// --- Cart stores (zustand state shapes, identical user-ui ↔ web-ui) --- +export interface AddedToCartProduct { + productId: number + product: any } -// Vendor snippet product — duplicated admin-ui components ↔ types -export interface VendorSnippetProduct { - id: number - name: string +export interface CartStore { + addedToCartProduct: AddedToCartProduct | null + setAddedToCartProduct: (product: AddedToCartProduct | null) => void + clearAddedToCartProduct: () => void +} + +// --- Store header (zustand state shape, identical user-ui ↔ web-ui) --- +export interface StoreHeaderState { + title: string + setTitle: (title: string) => void } diff --git a/packages/shared/types/cache.types.ts b/packages/shared/types/cache.types.ts index 5720384..ead6714 100644 --- a/packages/shared/types/cache.types.ts +++ b/packages/shared/types/cache.types.ts @@ -21,21 +21,3 @@ export interface UserNegativityData { userId: number totalNegativityScore: number } - -export interface PlacedOrderShape { - id: number - userId: number - addressId: number - slotId: number | null - totalAmount: string - deliveryCharge: string - isCod: boolean - isOnlinePayment: boolean - paymentInfoId: number | null - readableId: number - userNotes: string | null - orderGroupId: string - orderGroupProportion: string - isFlashDelivery: boolean - createdAt: Date -} diff --git a/packages/shared/types/index.ts b/packages/shared/types/index.ts index d88e642..f22497b 100644 --- a/packages/shared/types/index.ts +++ b/packages/shared/types/index.ts @@ -9,6 +9,7 @@ export type * from './user'; export type * from './store.types'; // Shared cross-cutting types — import from '@packages/shared' anywhere: +export type * from './primitives.types'; // MessageResponse, BasicSuccessResponse, IdName, ReactParentComponent export type * from './upload.types'; // ContextString, UploadInput, UploadBatchInput, UploadResult export type * from './app-common.types'; // LoginFormInputs, DropdownOption, CartIconProps, AddressFormProps, CartData export type * from './order.types'; // PlacedOrder, CouponUsageWithCoupon, GetAllOrdersInput diff --git a/packages/shared/types/primitives.types.ts b/packages/shared/types/primitives.types.ts index 104e069..43189a2 100644 --- a/packages/shared/types/primitives.types.ts +++ b/packages/shared/types/primitives.types.ts @@ -1,15 +1,25 @@ /** * Primitive shared shapes - * Leaf module (no imports) — safe to import from anywhere without cycles. - * Domain types that are exactly these shapes alias them instead of redeclaring. + * Leaf module (no runtime imports — type-only imports are erased at compile, + * so they cannot create cycles). Domain types that are exactly these shapes + * alias them instead of redeclaring. */ +import type { ReactNode } from 'react' export interface MessageResponse { success: boolean message: string } +export interface BasicSuccessResponse { + success: boolean +} + export interface IdName { id: number name: string } + +export interface ReactParentComponent { + children: ReactNode +} diff --git a/packages/shared/types/seed.types.ts b/packages/shared/types/seed.types.ts index 8c62eb6..240acb8 100644 --- a/packages/shared/types/seed.types.ts +++ b/packages/shared/types/seed.types.ts @@ -22,8 +22,7 @@ export interface RolePermissionAssignment { permissionName: StaffPermissionName } -// Generic key-value seed for `keyValStore` -export interface KeyValSeedData { - key: string - value: any -} +import type { Constant } from './const.types' + +// Generic key-value seed for `keyValStore` — exactly the shared Constant shape +export type KeyValSeedData = Constant diff --git a/packages/shared/types/user.ts b/packages/shared/types/user.ts index 3279a2a..d649ff9 100644 --- a/packages/shared/types/user.ts +++ b/packages/shared/types/user.ts @@ -1,6 +1,7 @@ // User-related types -import type { MessageResponse } from './primitives.types' +import type { MessageResponse, BasicSuccessResponse } from './primitives.types' +import type { AdminDeliverySlot } from './admin' import type { Banner } from './banner.types' @@ -230,11 +231,9 @@ export interface UserStoreDetailData { products: UserStoreProductData[]; } -export interface UserProductStoreInfo { - id: number; - name: string; - description: string | null; -} +import type { StoreSummary } from './store.types' + +export type UserProductStoreInfo = StoreSummary export interface UserProductDeliverySlot { id: number; @@ -324,16 +323,7 @@ export interface UserSlotAvailability { isOutOfStock: boolean; } -export interface UserDeliverySlot { - id: number; - deliveryTime: Date; - freezeTime: Date; - isActive: boolean; - isFlash: boolean; - isCapacityFull: boolean; - deliverySequence: unknown; - groupIds: unknown; -} +export type UserDeliverySlot = AdminDeliverySlot export interface UserSlotsResponse { slots: UserSlotWithProducts[]; @@ -498,9 +488,7 @@ export interface UserProfileCompleteResponse { isComplete: boolean; } -export interface UserSavePushTokenResponse { - success: boolean; -} +export type UserSavePushTokenResponse = BasicSuccessResponse export interface UserOrderItemSummary { productName: string; diff --git a/packages/ui/src/components/app-container.tsx b/packages/ui/src/components/app-container.tsx index 4302842..c22938c 100755 --- a/packages/ui/src/components/app-container.tsx +++ b/packages/ui/src/components/app-container.tsx @@ -3,12 +3,9 @@ import React from "react"; import { KeyboardAvoidingView, Platform, ScrollView, View, RefreshControl } from "react-native"; import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import { useRefresh } from "../lib/refresh-context"; +import type { ReactParentComponent } from '@packages/shared'; -interface Props { - children: React.ReactNode; -} - -function AppContainer(props: Props) { +function AppContainer(props: ReactParentComponent) { const { children } = props; const { refreshAll } = useRefresh(); diff --git a/packages/web-components/src/components/image-carousel.tsx b/packages/web-components/src/components/image-carousel.tsx index 735460b..125159b 100644 --- a/packages/web-components/src/components/image-carousel.tsx +++ b/packages/web-components/src/components/image-carousel.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { cn } from '../lib/utils' -interface ImageCarouselProps { +export interface ImageCarouselProps { images: { uri?: string }[] className?: string } diff --git a/packages/web-components/src/components/image-gallery.tsx b/packages/web-components/src/components/image-gallery.tsx index 597fa01..dceede9 100644 --- a/packages/web-components/src/components/image-gallery.tsx +++ b/packages/web-components/src/components/image-gallery.tsx @@ -1,10 +1,8 @@ import React from 'react' import { cn } from '../lib/utils' +import type { ImageCarouselProps } from './image-carousel' -interface ImageGalleryProps { - images: { uri?: string }[] - className?: string -} +type ImageGalleryProps = ImageCarouselProps export function ImageGallery({ images, className }: ImageGalleryProps) { return ( diff --git a/scripts/dead-code/user-ui-files.js b/scripts/dead-code/user-ui-files.js deleted file mode 100644 index 6ffadb2..0000000 --- a/scripts/dead-code/user-ui-files.js +++ /dev/null @@ -1,48 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = '/Users/mohammedshafiuddin/WebDev/freshyo' -const APP = 'apps/user-ui' - -// all user-ui source files -const files = execSync( - `find ${APP} -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'`, - { cwd: ROOT } -).toString().trim().split('\n') - -// all ts/tsx content across the whole repo that could import these (user-ui + repo scripts) -const scannerFiles = execSync( - `find apps/user-ui scripts packages/migrator -type f \\( -name '*.ts' -o -name '*.tsx' -o -name '*.js' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'`, - { cwd: ROOT } -).toString().trim().split('\n') - -const contents = new Map() -for (const f of scannerFiles) { - try { contents.set(f, fs.readFileSync(path.join(ROOT, f), 'utf8')) } catch {} -} - -// route files are entry points (expo-router) — exclude from "never imported" check -const isRoute = (f) => f.startsWith(`${APP}/app/`) && !f.includes('+api') -const isConfig = (f) => /metro\.config|eslint\.config|tsconfig|expo-env/.test(f) - -const neverImported = [] -for (const f of files) { - if (isRoute(f) || isConfig(f)) continue - const base = path.basename(f).replace(/\.(ts|tsx)$/, '') - // special web variants - const candidates = [base] - if (base.includes('.')) candidates.push(base) // useColorScheme.web - const baseNoPlatform = base.replace(/\.web$/, '') - const re = new RegExp(`from ['"][^'"]*${baseNoPlatform.replace(/\./g, '\\.')}['"]|require\\(['"][^'"]*${baseNoPlatform.replace(/\./g, '\\.')}['"]\\)`) - const importers = [] - for (const [of, c] of contents) { - if (of === f) continue - if (re.test(c)) importers.push(of) - } - if (importers.length === 0) neverImported.push(f) -} - -console.log('=== FILES NEVER IMPORTED (excluding expo-router entry points) ===') -neverImported.forEach((f) => console.log(f)) -console.log('count:', neverImported.length) diff --git a/scripts/dead-code/user-ui-store-actions.js b/scripts/dead-code/user-ui-store-actions.js deleted file mode 100644 index 35f908f..0000000 --- a/scripts/dead-code/user-ui-store-actions.js +++ /dev/null @@ -1,34 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = process.cwd() -const storeFiles = execSync( - "find apps/user-ui/src/store apps/user-ui/components/stores -type f -name '*.ts'" -) - .toString() - .trim() - .split('\n') - -// collect all non-store user-ui code -const consumerFiles = execSync( - "find apps/user-ui -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'" -) - .toString() - .trim() - .split('\n') - .filter((f) => !f.includes('/store/')) - -const consumerCode = consumerFiles.map((f) => fs.readFileSync(path.join(ROOT, f), 'utf8')).join('\n') - -for (const f of storeFiles) { - const code = fs.readFileSync(path.join(ROOT, f), 'utf8') - // keys inside the create<...>((set) => ({ ... })) object: "name:" at 2-space indent - const keys = [...code.matchAll(/^ {2}(\w+):/gm)].map((m) => m[1]) - const dead = [] - for (const k of new Set(keys)) { - const re = new RegExp(`\\.${k}\\b`) - if (!re.test(consumerCode)) dead.push(k) - } - console.log(path.basename(f), '→ unused actions/state:', dead.length ? dead.join(', ') : 'none') -} diff --git a/scripts/dead-code/user-ui-store-final.js b/scripts/dead-code/user-ui-store-final.js deleted file mode 100644 index f76ce61..0000000 --- a/scripts/dead-code/user-ui-store-final.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = process.cwd() -const storeFiles = execSync( - "find apps/user-ui/src/store apps/user-ui/components/stores -type f -name '*.ts'" -) - .toString() - .trim() - .split('\n') - -const otherFiles = execSync( - "find apps/user-ui -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'" -) - .toString() - .trim() - .split('\n') - .filter((f) => !f.includes('/store/')) - -for (const f of storeFiles) { - const code = fs.readFileSync(path.join(ROOT, f), 'utf8') - const keys = [...new Set([...code.matchAll(/^ {2}(\w+):/gm)].map((m) => m[1]))] - const dead = [] - for (const k of keys) { - const re = new RegExp(`\\b${k}\\b`, 'g') - const ownCount = (code.match(re) || []).length // def + internal uses - let outside = 0 - for (const of of otherFiles) { - outside += (fs.readFileSync(path.join(ROOT, of), 'utf8').match(re) || []).length - } - // ownCount === 1 means only the definition line; outside === 0 means nobody else - if (ownCount <= 1 && outside === 0) dead.push(k) - } - console.log(path.basename(f), '→ TRULY unused:', dead.length ? dead.join(', ') : 'none') -} diff --git a/scripts/dead-code/user-ui-store-precise.js b/scripts/dead-code/user-ui-store-precise.js deleted file mode 100644 index f3f9446..0000000 --- a/scripts/dead-code/user-ui-store-precise.js +++ /dev/null @@ -1,33 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = process.cwd() -const storeFiles = execSync( - "find apps/user-ui/src/store apps/user-ui/components/stores -type f -name '*.ts'" -) - .toString() - .trim() - .split('\n') - -const otherFiles = execSync( - "find apps/user-ui -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'" -) - .toString() - .trim() - .split('\n') - .filter((f) => !f.includes('/store/')) - -for (const f of storeFiles) { - const lines = fs.readFileSync(path.join(ROOT, f), 'utf8').split('\n') - const keys = [...new Set(lines.map((l) => (l.match(/^ {2}(\w+):/) || [])[1]).filter(Boolean))] - const dead = [] - for (const k of keys) { - const re = new RegExp(`\\b${k}\\b`) - // own-file usage: lines where the key appears but NOT as a "key:" declaration - const internalUse = lines.some((l) => re.test(l) && !l.trimStart().startsWith(k + ':')) - const outside = otherFiles.some((of) => re.test(fs.readFileSync(path.join(ROOT, of), 'utf8'))) - if (!internalUse && !outside) dead.push(k) - } - console.log(path.basename(f), '→ DEAD members:', dead.length ? dead.join(', ') : 'none') -} diff --git a/scripts/dead-code/user-ui-suspects.js b/scripts/dead-code/user-ui-suspects.js deleted file mode 100644 index e5c3cd7..0000000 --- a/scripts/dead-code/user-ui-suspects.js +++ /dev/null @@ -1,54 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = '/Users/mohammedshafiuddin/WebDev/freshyo' -const APP = 'apps/user-ui' - -const files = execSync( - `find ${APP} -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'`, - { cwd: ROOT } -).toString().trim().split('\n') - -const codes = new Map() -for (const f of files) codes.set(f, fs.readFileSync(path.join(ROOT, f), 'utf8')) - -const suspects = [ - 'useJWT', 'toaster', 'notif-checker', 'notif-register', 'notif-context', - 'useColorScheme', 'useUploadToObjectStore', 'useProductSlotIdentifier', - 'getCurrentUserId', 'queryClient', 'string-manipulators', - 'AddressForm', 'AddToCartDialog', 'CentralStoreInitializer', 'google-sign-in', - 'LocationAttacher', 'FirstUserWrapper', 'FlashDeliveryNote', 'HealthTestWrapper', - 'LocationTestWrapper', 'NextOrderGlimpse', 'OrderMenu', 'QuickDeliveryAddressSelector', - 'registration-form', 'TabLayoutWrapper', 'TestingPhaseNote', 'UpdateChecker', - 'WebViewWrapper', 'CheckoutAddressSelector', 'ComplaintForm', 'ProductDetail', - 'ProductCard', 'BackHandler', 'floating-cart-bar', 'cart-page', 'checkout-page', - 'PaymentAndOrderComponent', 'SlotSpecificView', 'cart-query-hooks', 'useAuthenticatedRoute', -] - -for (const name of suspects) { - const re = new RegExp(`from ['"][^'"]*/${name}['"]`) - const importers = [] - for (const [of, c] of codes) { - if (re.test(c)) importers.push(of.replace(APP + '/', '')) - } - console.log(`${name}: ${importers.length === 0 ? '*** NEVER IMPORTED ***' : importers.join(', ')}`) -} - -// store hooks usage -console.log('\n=== STORE HOOKS ===') -const storeFiles = files.filter((f) => f.includes('/store/')) -for (const sf of storeFiles) { - const code = codes.get(sf) - const m = code.match(/export\s+const\s+(use\w+)/g) || [] - const hooks = m.map((x) => x.replace('export const ', '')) - for (const h of hooks) { - let refs = 0 - const filesUsing = [] - for (const [of, oc] of codes) { - if (of === sf) continue - if (new RegExp(`\\b${h}\\b`).test(oc)) { refs++; filesUsing.push(of.replace(APP + '/', '')) } - } - console.log(`${h} (${path.basename(sf)}): ${refs === 0 ? '*** UNUSED ***' : refs + ' refs'}`) - } -} diff --git a/scripts/dead-code/user-ui-symbols.js b/scripts/dead-code/user-ui-symbols.js deleted file mode 100644 index acb10e9..0000000 --- a/scripts/dead-code/user-ui-symbols.js +++ /dev/null @@ -1,62 +0,0 @@ -const fs = require('fs') -const path = require('path') -const { execSync } = require('child_process') - -const ROOT = '/Users/mohammedshafiuddin/WebDev/freshyo' -const APP = 'apps/user-ui' - -const files = execSync( - `find ${APP} -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/.expo/*' -not -path '*/.turbo/*'`, - { cwd: ROOT } -).toString().trim().split('\n') - -const codes = new Map() -for (const f of files) codes.set(f, fs.readFileSync(path.join(ROOT, f), 'utf8')) - -function countWord(code, sym) { - const re = new RegExp(`\\b${sym.replace(/\$/g, '\\$')}\\b`, 'g') - return (code.match(re) || []).length -} - -function exportedNames(code) { - const names = new Set() - let m - const pats = [ - /export\s+(?:default\s+)?(?:async\s+)?function\s*\*?\s*(\w+)/g, - /export\s+(?:const|let|var)\s+(\w+)/g, - /export\s+(?:type|interface|class|enum)\s+(\w+)/g, - ] - for (const p of pats) while ((m = p.exec(code))) names.add(m[1]) - const br = /export\s*{([^}]*)}/g - while ((m = br.exec(code))) { - for (let part of m[1].split(',')) { - part = part.replace(/\/\/[^\n]*/g, '').trim().replace(/^type\s+/, '') - if (!part) continue - const asM = part.match(/\bas\s+(\w+)$/) - const nm = asM ? asM[1] : part.split(/\s/)[0] - if (/^[\w$]+$/.test(nm)) names.add(nm) - } - } - if (/export\s+default\s+function/.test(code) || /export\s+default\s+\w+/.test(code)) names.add('__default__') - return [...names] -} - -console.log('=== UNUSED EXPORTS per file (symbol not referenced in any OTHER user-ui file) ===') -for (const [f, code] of codes) { - if (f.startsWith(`${APP}/app/`)) continue // routes - const names = exportedNames(code) - const unused = [] - for (const sym of names) { - if (sym === '__default__') continue - let refs = 0 - for (const [of, oc] of codes) { - if (of === f) continue - refs += countWord(oc, sym) - } - if (refs === 0) unused.push(sym) - } - if (unused.length) { - console.log(`\n${f.replace(APP + '/', '')}`) - console.log(' ' + unused.join(', ')) - } -}