feat: architecture refactor — core layer, spreadsheet engine, envelope bidding, tests
CI / quality (push) Waiting to run

- Add src/core/ (config, errors, events, http, observability, storage, query)
- Add src/Spreadsheet/ engine with native POI backend and Excel bridge
- Add Envelope C spreadsheet flow and tender bidding envelope modules
- Consolidate components into src/components/, remove legacy Component/ and Hooks/
- Add registration state/validation, auth session guard, profile edit modules
- Add unit tests across axios, redux, bidding, registration, encryption, core
- Add CI workflow, docs (architecture, audit, DSC API spec), keystore example
- Remove tracked keystore binary; ignore scripts.zip

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Abin Toppo
2026-07-16 10:20:22 +05:30
co-authored by Claude Fable 5
parent 9acec328a7
commit 1d7646d938
217 changed files with 11068 additions and 6855 deletions
+3 -3
View File
@@ -6,11 +6,11 @@ import {
Animated,
Dimensions,
} from 'react-native';
import { InsideHeader } from '../../Component/Index';
import { InsideHeader } from '../../components';
import { useFetchLiveAuction, useFetchPurchaseAuction } from '../../Services/ApiCall/Hooks';
import LiveAuction from './LiveAuction';
import PurchaseAuction from './PurchaseAuction';
import { ShoppingCart, Lock, Radio, Package } from 'lucide-react-native';
import { ShoppingCart, Radio, Package } from 'lucide-react-native';
import { useNavigation } from '@react-navigation/native';
import NavigationString from '../../Constant/NavigationString';
import { useSelector } from 'react-redux';
@@ -28,7 +28,7 @@ const Auction = () => {
const { data: liveAuctionData = {} }: any = useFetchLiveAuction();
const { data: purchaseAuctionData = {} } = useFetchPurchaseAuction();
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
const reduxToken = useSelector((state: any) => state.token?.token);
useSelector((state: any) => state.token?.token);
const liveCount = Array.isArray(liveAuctionData?.result)
? liveAuctionData?.pages?.[0]?.totalCount
+8 -7
View File
@@ -7,12 +7,11 @@ import {
StyleSheet,
} from 'react-native';
import Animated, { FadeInDown, FadeOutUp } from 'react-native-reanimated';
import { RefreshCw } from 'lucide-react-native';
import LiveAuctionTile from './LiveAuctionTile';
import { useFetchLiveAuction } from '../../Services/ApiCall/Hooks';
import { SearchInput } from '../../Component/Serach/SeacrhInput';
import { Skelton } from '../../Component/Index';
import SkeltonList from '../../Component/Skelton/SkeltonList';
import { SearchInput } from '../../components/SearchInput';
import { Skeleton } from '../../components';
import SkeletonList from '../../components/SkeletonList';
import { useDispatch, useSelector } from 'react-redux';
import { togglePurchaseAuction } from '../../Redux/Slices/selectPurchaseAuction';
import { useTheme } from '../../Hooks/useTheme';
@@ -20,7 +19,7 @@ import AppText from '../../components/AppText';
const LiveAuction = () => {
const Dispatch = useDispatch();
const { colors, spacing, shadows } = useTheme();
const { colors, shadows } = useTheme();
const user = useSelector((state: any) => state.token?.token);
const onEndReachedCalledDuringMomentum = useRef(true);
const SelectedPurchaseList = useSelector((state: any) => state.selectPurchaseAuction);
@@ -64,6 +63,8 @@ const LiveAuction = () => {
/>
);
},
// Intentionally runs only on SelectedPurchaseList changes; other deps are stable or recreated each render.
// eslint-disable-next-line react-hooks/exhaustive-deps
[SelectedPurchaseList],
);
@@ -108,7 +109,7 @@ const LiveAuction = () => {
}, [data, hasNextPage, isFetchingNextPage, isPending]);
if (isLoading) {
return <Skelton />;
return <Skeleton />;
}
return (
@@ -138,7 +139,7 @@ const LiveAuction = () => {
{/* List */}
{isPending ? (
<SkeltonList />
<SkeletonList />
) : (
<FlatList
data={data?.result ?? []}
-1
View File
@@ -9,7 +9,6 @@ import {
Calendar,
Clock,
ShoppingCart,
Trash2,
CheckCircle2,
XCircle,
} from 'lucide-react-native';
+2 -4
View File
@@ -15,10 +15,6 @@ import {
Eye,
Layers,
ArrowLeft,
Clock,
IndianRupee,
Wrench,
Mail,
} from 'lucide-react-native';
import { useAuctionItem, useGetAuciton, useGetAucitonDocument } from '../../../Services/ApiCall/Hooks';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
@@ -91,6 +87,8 @@ const AuctionFullDetail: React.FC<Props> = ({ visible, onClose, data }) => {
},
},
);
// Intentionally runs only on auction number/document changes; other deps are stable or recreated each render.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data.auctionNumber, auctionDocuments]);
const isAmended = auctionData?.auctionStatus === 'Amended';
@@ -1,11 +1,11 @@
import React, { memo, useState, useMemo } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, ScrollView, Platform, Modal } from 'react-native';
import { View, StyleSheet, TouchableOpacity, ScrollView, Platform, Modal } from 'react-native';
import { Package, IndianRupee, FileText, Download, ArrowLeft, Info, } from 'lucide-react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useAucitonItemDetail } from '../../../Services/ApiCall/Hooks';
import ReactNativeBlobUtil from 'react-native-blob-util';
import { AUCTION_ITEM_DOCUMENT_DOWNLOAD } from '../../../Services/ApiCall/ApiUrls';
import { Loader } from '../../../Component/Index';
import { Loader } from '../../../components';
import { useTheme } from '../../../Hooks/useTheme';
import AppText from '../../../components/AppText';
@@ -48,7 +48,7 @@ const AuctionItemDetail: React.FC<Props> = ({ visible, onClose, data }) => {
const downloadUrl = `${AUCTION_ITEM_DOCUMENT_DOWNLOAD}?auctionItemId=${id}`;
const response = await ReactNativeBlobUtil.config({
await ReactNativeBlobUtil.config({
fileCache: false,
addAndroidDownloads: {
useDownloadManager: true,
@@ -63,7 +63,7 @@ const AuctionItemDetail: React.FC<Props> = ({ visible, onClose, data }) => {
Accept: 'application/pdf',
});
const stat = await ReactNativeBlobUtil.fs.stat(path);
await ReactNativeBlobUtil.fs.stat(path);
} catch (error: any) {
console.log('Error:', error?.message || error);
+8 -9
View File
@@ -1,14 +1,13 @@
import React, { useEffect, useState, useCallback, memo, useRef } from 'react';
import { View, Text, StyleSheet, FlatList, RefreshControl, ActivityIndicator } from 'react-native';
import LiveAuctionTile from './LiveAuctionTile';
import React, { useState, useCallback, useRef } from 'react';
import { View, FlatList, RefreshControl, ActivityIndicator } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import moment from 'moment';
import { useFetchLiveAuctionPage, useFetchPurchaseAuction } from '../../Services/ApiCall/Hooks';
import { useFetchLiveAuctionPage } from '../../Services/ApiCall/Hooks';
import PurchaseAuctionTile from './PurchaseAuctionTile';
import { useDispatch } from 'react-redux';
import { setAuction } from '../../Redux/Slices/SelectedAuction';
import { SearchInput } from '../../Component/Serach/SeacrhInput';
import { Skelton } from '../../Component/Index';
import { SearchInput } from '../../components/SearchInput';
import { Skeleton } from '../../components';
import { allBooleanProps } from './types/types';
import FilterModal from './Modal/FilterModal';
import NavigationString from '../../Constant/NavigationString';
@@ -20,7 +19,7 @@ const PurchaseAuction = () => {
const Dispatch = useDispatch()
const onEndReachedCalledDuringMomentum = useRef(true);
const [filter, setFilter] = useState({})
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, isRefetching, refetch, isPending }: any = useFetchLiveAuctionPage(filter);
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isRefetching, refetch, isPending }: any = useFetchLiveAuctionPage(filter);
const [allBoolean, setAllBoolean] = useState<allBooleanProps>({ isShowFilter: false })
const format = 'DD-MM-YYYY HH:mm:ss';
@@ -65,11 +64,11 @@ const PurchaseAuction = () => {
return (
<View style={{ flex: 1 }}>
<SearchInput onChange={(val) => { setFilter(prev => ({ ...prev, auctionNumber: val })) }} placeholder='Search....' filterPress={() => { setAllBoolean((prev: any) => ({ ...prev, isShowFilter: !prev.isShowFilter })) }} filter={false} />
{isPending ? <Skelton />
{isPending ? <Skeleton />
:
<FlatList
data={data.result ?? []}
renderItem={({ item, index }) => (
renderItem={({ item }) => (
<PurchaseAuctionTile
item={item}
onPressDetails={() => {
+4 -4
View File
@@ -15,17 +15,15 @@ import {
Receipt,
CheckCircle2,
Gavel,
Building2,
BadgeIndianRupee,
} from 'lucide-react-native';
import { InsideHeader } from '../../Component/Index';
import { InsideHeader } from '../../components';
import { useDispatch, useSelector } from 'react-redux';
import { useOfflineAuctionPurchase, usePurchaseAuctionList } from '../../Services/ApiCall/Hooks';
import { showSuccessAlert } from '../../Constant/ShowDailog';
import { clearPurchaseAuction } from '../../Redux/Slices/selectPurchaseAuction';
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
import NavigationString from '../../Constant/NavigationString';
import Skeleton from '../../Component/Skelton/Skelton';
import Skeleton from '../../components/Skeleton';
import { useTheme } from '../../Hooks/useTheme';
import AppText from '../../components/AppText';
@@ -115,6 +113,8 @@ const PurchaseAuctionList = () => {
useFocusEffect(
React.useCallback(() => {
getPurchaseList();
// Intentionally runs only on SelectedPurchaseList changes; other deps are stable or recreated each render.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [SelectedPurchaseList]),
);
+1 -6
View File
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import Animated, { FadeInUp, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import moment from 'moment';
import CountdownTimer from '../../Component/Counter/CountdownTimer';
import CountdownTimer from '../../components/CountdownTimer';
import AuctionDetail from './Modal/AuctionDetail';
import AppText from '../../components/AppText';
import { useTheme } from '../../Hooks/useTheme';
@@ -18,7 +18,6 @@ import {
const PurchaseAuctionTile = ({
item,
onPressDetails,
onStartBidding,
buttonEnable,
isAuctionEnd,
@@ -38,10 +37,6 @@ const PurchaseAuctionTile = ({
const biddingEnd = isAmended
? item?.amendedkeyDates?.auctionBidding?.endDateTime?.replace(' kk', '')
: item?.keyDates?.auctionBidding?.endDateTime?.replace(' kk', '');
const biddingStart = isAmended
? item?.amendedkeyDates?.auctionBidding?.startDateTime?.replace(' kk', '')
: item?.keyDates?.auctionBidding?.startDateTime?.replace(' kk', '');
const statusConfig = useMemo(() => {
if (isAuctionEnd) return { label: 'ENDED', color: colors.error, bg: `${colors.error}15`, Icon: TimerOff };
if (buttonEnable) return { label: 'LIVE', color: colors.success, bg: `${colors.success}15`, Icon: CircleDot };
+4 -2
View File
@@ -5,7 +5,7 @@ import {
ScrollView,
TouchableOpacity,
} from 'react-native';
import Animated, {
import Animated, {
FadeIn,
FadeOut,
FadeInDown,
@@ -15,7 +15,7 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';
import { ChevronDown, ChevronRight, Trash2, ShoppingBag, Gavel, Tag } from 'lucide-react-native';
import { InsideHeader } from '../../Component/Index';
import { InsideHeader } from '../../components';
import { useNavigation } from '@react-navigation/native';
import NavigationString from '../../Constant/NavigationString';
import { useDispatch, useSelector } from 'react-redux';
@@ -38,6 +38,8 @@ const PurchaseList = () => {
if (!SelectedPurchaseList || SelectedPurchaseList.length < 1) {
Navigation.goBack();
}
// Intentionally runs only on SelectedPurchaseList changes; other deps are stable or recreated each render.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [SelectedPurchaseList]);
const styles = makeStyles(colors, spacing, shadows);