DEAD_CODE_CLEAN #6

Merged
shafi merged 30 commits from DEAD_CODE_CLEAN into main 2026-09-14 04:29:36 +00:00
28 changed files with 291 additions and 317 deletions
Showing only changes of commit cfb84aae7a - Show all commits

View file

@ -1,11 +1,9 @@
import React from 'react'; import React from 'react';
import { View, ScrollView } from 'react-native'; import { View, ScrollView } from 'react-native';
import { BottomDialog, MyText, tw } from 'common-ui'; import { BottomDialog, MyText, tw } from 'common-ui';
import type { IdName } from '@packages/shared';
interface VendorSnippetProduct { type VendorSnippetProduct = IdName;
id: number;
name: string;
}
interface ProductListDialogProps { interface ProductListDialogProps {
open: boolean; open: boolean;

View file

@ -5,11 +5,9 @@ import { DeviceEventEmitter } from "react-native";
import { FORCE_LOGOUT_EVENT } from "common-ui/src/lib/const-strs"; import { FORCE_LOGOUT_EVENT } from "common-ui/src/lib/const-strs";
import { trpc } from "@/src/trpc-client"; import { trpc } from "@/src/trpc-client";
import { saveJWT, getJWT, deleteJWT } from "@/hooks/useJWT"; import { saveJWT, getJWT, deleteJWT } from "@/hooks/useJWT";
import type { IdName } from '@packages/shared';
interface Staff { type Staff = IdName;
id: number;
name: string;
}
interface StaffAuthContextType { interface StaffAuthContextType {
isLoggedIn: boolean; isLoggedIn: boolean;

View file

@ -9,11 +9,9 @@ import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatli
import { Image } from 'expo-image'; import { Image } from 'expo-image';
import ProductsSelector from '@/components/ProductsSelector'; import ProductsSelector from '@/components/ProductsSelector';
import { trpc } from '@/src/trpc-client'; import { trpc } from '@/src/trpc-client';
import type { IdName } from '@packages/shared';
interface StoreOption { type StoreOption = IdName;
id: number;
name: string;
}
interface TagFormData { interface TagFormData {
tagName: string; tagName: string;

View file

@ -1,7 +1,6 @@
export interface VendorSnippetProduct { import type { IdName } from '@packages/shared';
id: number;
name: string; export type VendorSnippetProduct = IdName;
}
export interface VendorSnippet { export interface VendorSnippet {
id: number; id: number;

View file

@ -10,12 +10,7 @@ import { TermsAndConditionsContent } from "@/components/TermsAndConditions";
import { LinearGradient } from "expo-linear-gradient"; import { LinearGradient } from "expo-linear-gradient";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { SafeAreaView } from "react-native-safe-area-context"; import { SafeAreaView } from "react-native-safe-area-context";
import type { LoginFormInputs } from '@packages/shared';
interface LoginFormInputs {
mobile: string;
otp?: string;
password?: string;
}
function Login() { function Login() {
const { loginWithToken } = useAuth(); const { loginWithToken } = useAuth();

View file

@ -10,35 +10,8 @@ import { orderStatusManipulator } from '@/src/lib/string-manipulators';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import OrderMenu from '@/components/OrderMenu'; import OrderMenu from '@/components/OrderMenu';
// Type definitions // Type definitions (order view models live in @/src/types/orders)
interface OrderItem { import type { Order, OrderItem } from '@/src/types/orders';
productName: string;
quantity: number;
price: number;
amount: number;
image: string | null;
}
interface Order {
id: number;
orderId: string;
orderDate: string;
deliveryStatus: string;
deliveryDate?: string;
orderStatus: string;
cancelReason: string | null;
totalAmount: number;
deliveryCharge: number;
paymentMode: string;
paymentStatus: string;
refundStatus: string;
refundAmount: number | null;
userNotes: string | null;
items: OrderItem[];
discountAmount?: number;
isFlashDelivery: boolean;
createdAt: string;
}
interface OrderFooterProps { interface OrderFooterProps {
isLoadingMore: boolean; isLoadingMore: boolean;

View file

@ -10,40 +10,12 @@ import { Image } from 'expo-image';
import { orderStatusManipulator } from '@/src/lib/string-manipulators'; import { orderStatusManipulator } from '@/src/lib/string-manipulators';
import { useGetEssentialConsts } from '@/src/hooks/prominent-api-hooks'; import { useGetEssentialConsts } from '@/src/hooks/prominent-api-hooks';
import { useUserDetails } from '@/src/contexts/AuthContext'; import { useUserDetails } from '@/src/contexts/AuthContext';
import type { Order, OrderItem } from '@/src/types/orders';
const { width: screenWidth } = Dimensions.get('window'); const { width: screenWidth } = Dimensions.get('window');
const CARD_WIDTH = (screenWidth - 48) * 0.95; // card width (24px padding each side), reduced 5% const CARD_WIDTH = (screenWidth - 48) * 0.95; // card width (24px padding each side), reduced 5%
const SNAP_INTERVAL = CARD_WIDTH + 24; // card + right margin = page width const SNAP_INTERVAL = CARD_WIDTH + 24; // card + right margin = page width
interface OrderItem {
productName: string;
quantity: number;
price: number;
amount: number;
image: string | null;
}
interface Order {
id: number;
orderId: string;
orderDate: string;
deliveryStatus: string;
deliveryDate?: string;
orderStatus: string;
cancelReason: string | null;
totalAmount: number;
deliveryCharge: number;
paymentMode: string;
paymentStatus: string;
refundStatus: string;
refundAmount: number | null;
userNotes: string | null;
items: OrderItem[];
discountAmount?: number;
isFlashDelivery: boolean;
createdAt: string;
}
interface OrderCardProps { interface OrderCardProps {
order: Order; order: Order;
onPress: () => void; onPress: () => void;

View file

@ -1,6 +1,7 @@
import { useFocusEffect } from '@react-navigation/native'; import { useFocusEffect } from '@react-navigation/native';
import { useRouter } from 'expo-router'; import { useRouter } from 'expo-router';
import { useAuth } from '@/src/contexts/AuthContext'; import { useAuth } from '@/src/contexts/AuthContext';
import type { RedirectState } from '@/src/contexts/AuthContext';
import { StorageServiceCasual } from 'common-ui'; import { StorageServiceCasual } from 'common-ui';
import constants from '@/src/constants'; import constants from '@/src/constants';
@ -9,12 +10,6 @@ interface AuthenticatedRouteOptions {
queryParams?: Record<string, any>; queryParams?: Record<string, any>;
} }
interface RedirectState {
targetUrl: string;
queryParams: Record<string, any>;
timestamp: number;
}
export function useAuthenticatedRoute(options: AuthenticatedRouteOptions = {}) { export function useAuthenticatedRoute(options: AuthenticatedRouteOptions = {}) {
const { isAuthenticated, isLoading } = useAuth(); const { isAuthenticated, isLoading } = useAuth();
const router = useRouter(); const router = useRouter();

View file

@ -8,7 +8,7 @@ import { StorageServiceCasual } from 'common-ui';
import { useRouter } from 'expo-router'; import { useRouter } from 'expo-router';
import constants from '@/src/constants'; import constants from '@/src/constants';
interface RedirectState { export interface RedirectState {
targetUrl: string; targetUrl: string;
queryParams: Record<string, any>; queryParams: Record<string, any>;
timestamp: number; timestamp: number;

View file

@ -56,7 +56,7 @@ type StoreWithProductsResponse = StoreWithProductsApiType;
type AvailabilityResponse = AvailabilityApiType; type AvailabilityResponse = AvailabilityApiType;
type BaseProduct = AllProductsApiType['products'][number] type BaseProduct = AllProductsApiType['products'][number]
type AvailabilityEntry = AvailabilityApiType['availability'][number] export type AvailabilityEntry = AvailabilityApiType['availability'][number]
export type MergedProduct = BaseProduct & { export type MergedProduct = BaseProduct & {
price: number price: number

View file

@ -1,11 +1,11 @@
import { create } from 'zustand'; import { create } from 'zustand';
import { useSlots, useAvailability } from '@/src/hooks/prominent-api-hooks'; import { useSlots, useAvailability } from '@/src/hooks/prominent-api-hooks';
import type { AvailabilityEntry } from '@/src/hooks/prominent-api-hooks';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { SlotsApiType, AvailabilityApiType } from "@backend/trpc/router"; import { SlotsApiType } from "@backend/trpc/router";
type Slot = SlotsApiType['slots'][number]; type Slot = SlotsApiType['slots'][number];
type ProductAvailability = SlotsApiType['productAvailability'][number]; type ProductAvailability = SlotsApiType['productAvailability'][number];
type AvailabilityEntry = AvailabilityApiType['availability'][number];
interface ProductSlotInfo { interface ProductSlotInfo {
slots: Slot[]; slots: Slot[];

View file

@ -27,18 +27,12 @@ export interface AuthState {
token: string | null; token: string | null;
} }
export interface LoginCredentials { import type { LoginRequest, RegisterRequest } from '@packages/shared'
identifier: string; // email or mobile
password: string;
}
export interface RegisterData { // Wire-contract shapes live in @packages/shared (inputs.types.ts) —
name: string; // these aliases preserve the local names used across user-ui.
email: string; export type LoginCredentials = LoginRequest
mobile: string; export type RegisterData = RegisterRequest
password: string;
profileImageUrl?: string | null;
}
export interface UpdateProfileData { export interface UpdateProfileData {
name?: string; name?: string;

View file

@ -0,0 +1,31 @@
// Shared order view-model types for user-ui
// (Were identically duplicated in me/my-orders/index.tsx and NextOrderGlimpse.tsx)
export interface OrderItem {
productName: string;
quantity: number;
price: number;
amount: number;
image: string | null;
}
export interface Order {
id: number;
orderId: string;
orderDate: string;
deliveryStatus: string;
deliveryDate?: string;
orderStatus: string;
cancelReason: string | null;
totalAmount: number;
deliveryCharge: number;
paymentMode: string;
paymentStatus: string;
refundStatus: string;
refundAmount: number | null;
userNotes: string | null;
items: OrderItem[];
discountAmount?: number;
isFlashDelivery: boolean;
createdAt: string;
}

View file

@ -5,15 +5,10 @@ import { useAuth } from '../lib/auth-context'
import { trpc } from '../lib/trpc-client' import { trpc } from '../lib/trpc-client'
import { useGetEssentialConsts } from '../hooks/prominent-api-hooks' import { useGetEssentialConsts } from '../hooks/prominent-api-hooks'
import { MyButton, pInput as PInput } from 'web-components' import { MyButton, pInput as PInput } from 'web-components'
import type { LoginFormInputs } from '@packages/shared'
export const Route = createFileRoute('/login')({ component: LoginPage }) export const Route = createFileRoute('/login')({ component: LoginPage })
interface LoginFormInputs {
mobile: string
otp?: string
password?: string
}
function LoginPage() { function LoginPage() {
const { loginWithToken } = useAuth() const { loginWithToken } = useAuth()
const navigate = useNavigate() const navigate = useNavigate()

View file

@ -747,3 +747,110 @@ Context: user approved the db-helper-unification plan (SKU model canonical; post
=== REBUILT types_inventory.md (latest snapshot) === === REBUILT types_inventory.md (latest snapshot) ===
792 types (521 unique), 143 duplicate names, 131 identical-property clusters, 711 `any` usages across 210 files. Organized by file + by name, duplicate clusters w/ consumers, identical-property clusters, per-file `any` table. 792 types (521 unique), 143 duplicate names, 131 identical-property clusters, 711 `any` usages across 210 files. Organized by file + by name, duplicate clusters w/ consumers, identical-property clusters, per-file `any` table.
[2026-09-04 23:36:11] PHASE 1: dedupe packages/shared/types/admin.ts — 10 types re-declared identically in dedicated files are replaced by re-exports (verified byte-identical modulo comments/whitespace).
=== packages/shared/types/admin.ts ===
- removed local declarations: Banner, Complaint, ComplaintWithUser, Constant, ConstantUpdateResult, Coupon, CouponValidationResult, UserMiniInfo, StaffUser, StaffRole
- added re-export block:
export type { Banner } from './banner.types'
export type { Complaint, ComplaintWithUser } from './complaint.types'
export type { Constant, ConstantUpdateResult } from './const.types'
export type { Coupon, CouponValidationResult, UserMiniInfo } from './coupon.types'
export type { StaffUser, StaffRole } from './staff-user.types'
- KEPT in admin.ts: Store (canonical home — store.types.ts note says so), AdminOrderRow and everything below
[2026-09-04 23:40:00] PHASE 1b: packages/shared/types/user.ts — UserBanner is byte-identical to Banner; replaced local declaration with alias.
- removed local interface UserBanner (10 fields) at user.ts ~line 119
- added: import type { Banner } from './banner.types'
export type UserBanner = Banner
(5 live consumers — sqlite/postgres banners.ts, backend dbService re-export — keep working unchanged)
[2026-09-04 23:47:00] PHASE 2: centralize cross-app / in-app exact-duplicate types.
=== apps/user-ui/src/types/auth.ts ===
- replaced local interfaces with shared aliases (shared/inputs.types.ts LoginRequest/RegisterRequest verified byte-identical):
removed: export interface LoginCredentials { identifier: string; password: string; }
export interface RegisterData { name; email; mobile; password; profileImageUrl?: string | null; }
added: import type { LoginRequest, RegisterRequest } from '@packages/shared'
export type LoginCredentials = LoginRequest
export type RegisterData = RegisterRequest
(6 consumer files keep importing the same names from '@/src/types/auth' — zero consumer edits)
=== apps/user-ui/hooks/useAuthenticatedRoute.ts + src/contexts/AuthContext.tsx ===
- RedirectState identical in both. Canonical: AuthContext (line 11 interface → exported).
- hook: deleted local interface, added import type { RedirectState } from '@/src/contexts/AuthContext'
(hook already imports useAuth from AuthContext — no new cycle)
=== login forms (user-ui + web-ui) ===
- both LoginFormInputs identical. Canonical: shared/app-common.types.ts LoginFormInputs (already there).
- apps/user-ui/app/(auth)/login.tsx: deleted local interface, added import type { LoginFormInputs } from '@packages/shared'
- apps/web-ui/src/routes/login.tsx: deleted local interface, added import type { LoginFormInputs } from '@packages/shared'
=== user-ui Order/OrderItem view models ===
- new file apps/user-ui/src/types/orders.ts exporting the identical Order + OrderItem interfaces (from me/my-orders/index.tsx)
- me/my-orders/index.tsx + components/NextOrderGlimpse.tsx: deleted locals (incl. the '// Type definitions' comment), import from '@/src/types/orders'
=== apps/user-ui/src/store/centralSlotStore.ts ===
- deleted local type AvailabilityEntry = AvailabilityApiType['availability'][number] (line 8)
- added import type { AvailabilityEntry } from '@/src/hooks/prominent-api-hooks'
(type-only import — no runtime cycle with the store's existing value import from the same file)
[2026-09-04 23:55:00] PHASE 3: centralize remaining exact-duplicate db types.
(a) FIX broken seed re-export chain (prior session migrated lib/seed.ts to shared imports but left index.ts re-exporting from lib/seed):
- packages/db_helper_sqlite/src/lib/seed.ts + packages/db_helper_postgres/src/lib/seed.ts: added
export type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
(index.ts `export { ..., type UnitSeedData, ... } from './src/lib/seed'` blocks resolve again)
(b) NEW packages/shared/types/order.types.ts: PlacedOrder, CouponUsageWithCoupon, GetAllOrdersInput
(copied verbatim from sqlite; pg verified byte-identical. NOT included: OrderWithCancellationData — extends drifted OrderWithFullData, stays local in both packages.)
- shared/types/index.ts: added export type * from './order.types';
(c) MIGRATIONS to shared:
- sqlite+pg user-apis/order.ts: deleted local PlacedOrder + CouponUsageWithCoupon; extended existing '@packages/shared' import
- sqlite+pg admin-apis/order.ts: deleted local GetAllOrdersInput; extended existing '@packages/shared' import
- sqlite+pg stores/store-helpers.ts: deleted local StoreBasicData interface; added
import type { StoreSummary } from '@packages/shared'
export type StoreBasicData = StoreSummary
(index.ts `type StoreBasicData` export lines + backend consumers keep working via the alias; shared StoreSummary verified identical shape)
NOT touched (verified different, per exact-dupe rule): CreateCouponInput/UpdateCouponInput, CreateProductTagInput/UpdateProductTagInput, SlotSnippetInput, CreateSkuInput/CreateProductInput (sku- vs product-model drift); InferSelectModel *Row aliases (schema-bound per package); user-apis richer CouponValidationResult (different concept, same name — rename candidate only); backend banner-store Banner (subset shape); const-keys files (different key sets).
[2026-09-04 23:58:00] FIX Phase 1 regression: my shape comparison was unreliable (shell-quoting artifact) and wrongly unified 2 drifted pairs. sqlite tsc went 4 -> 12 errors (coupon.ts x5, staff-user.ts x3).
- Coupon: admin.ts original had `skuIds: number[] | null`; canonical coupon.types.ts has `productIds: number[] | null` — RESTORED admin.ts local Coupon.
- StaffUser: admin.ts original had `staffRoleId: number | null`; canonical staff-user.types.ts has `staffRoleId: number` — RESTORED admin.ts local StaffUser.
- Verified truly identical (re-export kept): Banner, Complaint, ComplaintWithUser, Constant, ConstantUpdateResult, UserMiniInfo, StaffRole.
[2026-09-04 23:59:00] PHASE 4: additive shared primitives + aliasing (zero consumer edits).
- NEW packages/shared/types/primitives.types.ts: MessageResponse {success, message}, IdName {id, name} (leaf module, no imports — no cycles)
- shared/types/index.ts: added export type * from './primitives.types';
- shared/types/user.ts: 8 interfaces (UserAddressDeleteResponse, UserCancelOrderResponse, UserDeleteAccountResponse, UserPasswordUpdateResponse, UserPaymentFailResponse, UserPaymentVerifyResponse, UserRaiseComplaintResponse, UserUpdateNotesResponse) become export type X = MessageResponse
- shared/types/admin.ts: AdminOrderMessageResult becomes export type AdminOrderMessageResult = MessageResponse ; AdminVendorSnippetProduct becomes export type AdminVendorSnippetProduct = IdName
- apps/admin-ui/types/vendor-snippets.ts: VendorSnippetProduct becomes alias of shared IdName
- apps/admin-ui/components/ProductListDialog.tsx: local VendorSnippetProduct becomes alias of shared IdName
- apps/admin-ui/src/components/TagForm.tsx: StoreOption becomes alias of shared IdName
- apps/admin-ui/components/context/staff-auth-context.tsx: Staff becomes alias of shared IdName
- apps/backend/src/middleware/auth.middleware.ts: StaffContext becomes alias of shared IdName
DECISION (documented, not done): ui<->web-components prop mirrors left independent (no cross-dep between the RN and web UI packages; wiring one for 3 prop types is disproportionate). migrator TableInfo/ColumnInfo left (ColumnInfo field names differ per direction — unifying TableInfo alone would be wrong). CartData left (each app's CartItem element type differs). Drifted pairs (coupon/tag/slot/product inputs, store-helpers cache types, user-apis order relations) left per exact-dupe rule.
[2026-09-05 00:02:00] FIX two regressions found by tsc verification:
(a) admin.ts used MessageResponse/IdName in aliases without importing them (export-from does not bring names into local scope) — added import type { MessageResponse, IdName } from './primitives.types' (re-export line kept).
(b) Pre-existing broken chain from prior centralization session (NOT mine, but fixed as part of unification): both store-helpers.ts files imported ProductTagData/TagProductMapping/UserNegativityData from shared without re-exporting, while both index.ts files re-export those names from store-helpers (TS2459 x3 in backend build). Added export type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared' to both store-helpers files.
[2026-09-05 00:05:00] FIX two more gaps from prior centralization session (surfaced by my Phase 2 wiring):
(a) shared/types/app-common.types.ts was never added to shared/types/index.ts star exports — added export type * from './app-common.types'; (no name collisions verified). This makes LoginFormInputs/DropdownOption/CartIconProps/AddressFormProps/ComplaintFormProps/CartData importable from '@packages/shared'.
(b) user-ui prominent-api-hooks.ts declared AvailabilityEntry without export — added export keyword so centralSlotStore's import resolves.
[2026-09-05 00:08:50] COMPLETED exact-duplicate type unification (Phases 1-4).
Centralized in @packages/shared and re-used:
- admin.ts: Banner, Complaint, ComplaintWithUser, Constant, ConstantUpdateResult, CouponValidationResult, UserMiniInfo, StaffRole → re-exports (Coupon + StaffUser KEPT local — verified drifted: skuIds vs productIds, staffRoleId nullable vs not)
- user.ts: UserBanner → alias of Banner
- NEW order.types.ts: PlacedOrder, CouponUsageWithCoupon, GetAllOrdersInput; both db packages import them (OrderWithCancellationData left local — extends drifted OrderWithFullData)
- StoreBasicData (both store-helpers) → alias of shared StoreSummary (verified identical shape)
- seed re-export chain repaired in both lib/seed.ts (was dangling after prior session's migration)
- user-ui: LoginCredentials/RegisterData → shared aliases; RedirectState canonical in AuthContext; LoginFormInputs (user-ui + web-ui) → shared app-common; Order/OrderItem → new src/types/orders.ts; AvailabilityEntry canonical in prominent-api-hooks
- primitives.types.ts (MessageResponse, IdName): 8 user.ts + AdminOrderMessageResult + AdminVendorSnippetProduct + 4 cross-file {id,name} types aliased
- 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).

View file

@ -25,6 +25,7 @@ import type {
AdminRefundRecord, AdminRefundRecord,
RefundStatus, RefundStatus,
PaymentStatus, PaymentStatus,
GetAllOrdersInput,
} from '@packages/shared' } from '@packages/shared'
import type { InferSelectModel } from 'drizzle-orm' import type { InferSelectModel } from 'drizzle-orm'
@ -427,16 +428,6 @@ export async function updateAddressCoords(
return { success: result.length > 0 } return { success: result.length > 0 }
} }
type GetAllOrdersInput = {
cursor?: number
limit: number
slotId?: number | null
packagedFilter?: 'all' | 'packaged' | 'not_packaged'
deliveredFilter?: 'all' | 'delivered' | 'not_delivered'
cancellationFilter?: 'all' | 'cancelled' | 'not_cancelled'
flashDeliveryFilter?: 'all' | 'flash' | 'regular'
}
export async function getAllOrders(input: GetAllOrdersInput): Promise<AdminGetAllOrdersResultWithUserId> { export async function getAllOrders(input: GetAllOrdersInput): Promise<AdminGetAllOrdersResultWithUserId> {
const { const {
cursor, cursor,

View file

@ -2,6 +2,10 @@ import { db } from '../db/db_index'
import { eq, and } from 'drizzle-orm' import { eq, and } from 'drizzle-orm'
import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared' import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
// Re-exported so the package index (`export { ... } from './src/lib/seed'`)
// keeps resolving to the single shared source.
export type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
// ============================================================================ // ============================================================================
// Unit Seed Helper // Unit Seed Helper
// ============================================================================ // ============================================================================

View file

@ -14,7 +14,14 @@ import {
userIncidents, userIncidents,
} from '../db/schema' } from '../db/schema'
import { eq, and, gt, sql, inArray, isNotNull, asc, sum } from 'drizzle-orm' import { eq, and, gt, sql, inArray, isNotNull, asc, sum } from 'drizzle-orm'
import type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared' import type { ProductTagData, TagProductMapping, UserNegativityData, StoreSummary } from '@packages/shared'
// Re-exported so the package index (`export { ... } from './src/stores/store-helpers'`)
// keeps resolving to the single shared source.
export type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared'
// StoreBasicData is exactly the shared StoreSummary shape — single source, same export name.
export type StoreBasicData = StoreSummary
// ============================================================================ // ============================================================================
// BANNER STORE HELPERS // BANNER STORE HELPERS
@ -57,12 +64,6 @@ export interface ProductBasicData {
flashPrice: string | null flashPrice: string | null
} }
export interface StoreBasicData {
id: number
name: string
description: string | null
}
export interface DeliverySlotData { export interface DeliverySlotData {
productId: number productId: number
id: number id: number

View file

@ -18,26 +18,10 @@ import { and, eq, inArray, desc, lte } from 'drizzle-orm'
import type { import type {
UserOrderSummary, UserOrderSummary,
UserOrderDetail, UserOrderDetail,
PlacedOrder,
CouponUsageWithCoupon,
} from '@packages/shared' } from '@packages/shared'
export interface PlacedOrder {
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
}
export interface OrderWithRelations { export interface OrderWithRelations {
id: number id: number
userId: number userId: number
@ -144,19 +128,6 @@ export interface CouponValidationResult {
}> }>
} }
export interface CouponUsageWithCoupon {
id: number
couponId: number
orderId: number | null
coupon: {
id: number
couponCode: string
discountPercent: string | null
flatDiscount: string | null
maxValue: string | null
}
}
export async function validateAndGetCoupon( export async function validateAndGetCoupon(
couponId: number | undefined, couponId: number | undefined,
userId: number, userId: number,

View file

@ -25,6 +25,7 @@ import type {
AdminRefundRecord, AdminRefundRecord,
RefundStatus, RefundStatus,
PaymentStatus, PaymentStatus,
GetAllOrdersInput,
} from '@packages/shared' } from '@packages/shared'
import type { InferSelectModel } from 'drizzle-orm' import type { InferSelectModel } from 'drizzle-orm'
import { coerceDate } from '../lib/date' import { coerceDate } from '../lib/date'
@ -441,16 +442,6 @@ export async function updateAddressCoords(
return { success: result.length > 0 } return { success: result.length > 0 }
} }
type GetAllOrdersInput = {
cursor?: number
limit: number
slotId?: number | null
packagedFilter?: 'all' | 'packaged' | 'not_packaged'
deliveredFilter?: 'all' | 'delivered' | 'not_delivered'
cancellationFilter?: 'all' | 'cancelled' | 'not_cancelled'
flashDeliveryFilter?: 'all' | 'flash' | 'regular'
}
export async function getAllOrders(input: GetAllOrdersInput): Promise<AdminGetAllOrdersResultWithUserId> { export async function getAllOrders(input: GetAllOrdersInput): Promise<AdminGetAllOrdersResultWithUserId> {
const { const {
cursor, cursor,

View file

@ -2,6 +2,10 @@ import { db } from '../db/db_index'
import { eq, and } from 'drizzle-orm' import { eq, and } from 'drizzle-orm'
import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared' import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
// Re-exported so the package index (`export { ... } from './src/lib/seed'`)
// keeps resolving to the single shared source.
export type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
// ============================================================================ // ============================================================================
// Unit Seed Helper // Unit Seed Helper
// ============================================================================ // ============================================================================

View file

@ -17,7 +17,14 @@ import {
} from '../db/schema' } from '../db/schema'
import { eq, and, gt, sql, isNotNull, asc } from 'drizzle-orm' import { eq, and, gt, sql, isNotNull, asc } from 'drizzle-orm'
import { composeSkuName, composeUnitNotation } from '../lib/sku-features' import { composeSkuName, composeUnitNotation } from '../lib/sku-features'
import type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared' import type { ProductTagData, TagProductMapping, UserNegativityData, StoreSummary } from '@packages/shared'
// Re-exported so the package index (`export { ... } from './src/stores/store-helpers'`)
// keeps resolving to the single shared source.
export type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared'
// StoreBasicData is exactly the shared StoreSummary shape — single source, same export name.
export type StoreBasicData = StoreSummary
// ============================================================================ // ============================================================================
// BANNER STORE HELPERS // BANNER STORE HELPERS
@ -75,12 +82,6 @@ export interface AvailabilityCacheData {
isSuspended: boolean isSuspended: boolean
} }
export interface StoreBasicData {
id: number
name: string
description: string | null
}
export interface DeliverySlotData { export interface DeliverySlotData {
skuId: number skuId: number
id: number id: number

View file

@ -19,29 +19,13 @@ import { and, eq, inArray, desc, sql } from 'drizzle-orm'
import type { import type {
UserOrderSummary, UserOrderSummary,
UserOrderDetail, UserOrderDetail,
PlacedOrder,
CouponUsageWithCoupon,
} from '@packages/shared' } from '@packages/shared'
import { coerceDate } from '../lib/date' import { coerceDate } from '../lib/date'
import { runBatched } from '../lib/run-batched' import { runBatched } from '../lib/run-batched'
import { composeSkuName, composeUnitNotation } from '../lib/sku-features' import { composeSkuName, composeUnitNotation } from '../lib/sku-features'
export interface PlacedOrder {
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
}
export interface OrderWithRelations { export interface OrderWithRelations {
id: number id: number
userId: number userId: number
@ -154,19 +138,6 @@ export interface CouponValidationResult {
}> }>
} }
export interface CouponUsageWithCoupon {
id: number
couponId: number
orderId: number | null
coupon: {
id: number
couponCode: string
discountPercent: string | null
flatDiscount: string | null
maxValue: string | null
}
}
export async function validateAndGetCoupon( export async function validateAndGetCoupon(
couponId: number | undefined, couponId: number | undefined,
userId: number, userId: number,

View file

@ -1,45 +1,18 @@
// Admin-related types // Admin-related types
// (Entity shapes live in the dedicated per-domain files — re-exported here
// so existing `@packages/shared` consumers keep working from one surface.)
export interface Banner { import type { MessageResponse, IdName } from './primitives.types'
id: number; export type { Banner } from './banner.types'
name: string; export type { Complaint, ComplaintWithUser } from './complaint.types'
imageUrl: string; export type { Constant, ConstantUpdateResult } from './const.types'
description: string | null; export type { CouponValidationResult, UserMiniInfo } from './coupon.types'
skuIds: number[] | null; export type { StaffRole } from './staff-user.types'
redirectUrl: string | null; export type { MessageResponse, IdName } from './primitives.types'
serialNum: number | null;
isActive: boolean;
createdAt: Date;
lastUpdated: Date;
}
export interface Complaint {
id: number;
complaintBody: string;
userId: number;
orderId: number | null;
isResolved: boolean;
response: string | null;
createdAt: Date;
images: string[] | null;
}
export interface ComplaintWithUser extends Complaint {
userName: string | null;
userMobile: string | null;
}
export interface Constant {
key: string;
value: any;
}
export interface ConstantUpdateResult {
success: boolean;
updatedCount: number;
keys: string[];
}
// NOTE: Coupon and StaffUser intentionally keep LOCAL declarations below —
// the dedicated files drifted (productIds vs skuIds; staffRoleId nullable vs
// not) and sqlite consumers depend on these exact shapes.
export interface Coupon { export interface Coupon {
id: number; id: number;
couponCode: string; couponCode: string;
@ -58,17 +31,12 @@ export interface Coupon {
createdBy: number; createdBy: number;
} }
export interface CouponValidationResult { export interface StaffUser {
valid: boolean;
message?: string;
discountAmount?: number;
coupon?: Partial<Coupon>;
}
export interface UserMiniInfo {
id: number; id: number;
name: string; name: string;
mobile: string | null; password: string;
staffRoleId: number | null;
createdAt: Date;
} }
export interface Store { export interface Store {
@ -81,19 +49,6 @@ export interface Store {
// updatedAt: Date; // updatedAt: Date;
} }
export interface StaffUser {
id: number;
name: string;
password: string;
staffRoleId: number | null;
createdAt: Date;
}
export interface StaffRole {
id: number;
roleName: string;
}
export interface AdminOrderRow { export interface AdminOrderRow {
id: number; id: number;
userId: number; userId: number;
@ -232,10 +187,7 @@ export interface AdminOrderItemPackagingResult {
updated: boolean; updated: boolean;
} }
export interface AdminOrderMessageResult { export type AdminOrderMessageResult = MessageResponse
success: boolean;
message: string;
}
export interface AdminOrderBasicResult { export interface AdminOrderBasicResult {
success: boolean; success: boolean;
@ -601,10 +553,7 @@ export interface AdminVendorSnippetWithSlot extends AdminVendorSnippet {
slot: AdminDeliverySlot | null; slot: AdminDeliverySlot | null;
} }
export interface AdminVendorSnippetProduct { export type AdminVendorSnippetProduct = IdName
id: number;
name: string;
}
export interface AdminVendorSnippetWithProducts extends AdminVendorSnippetWithSlot { export interface AdminVendorSnippetWithProducts extends AdminVendorSnippetWithSlot {
accessUrl: string; accessUrl: string;

View file

@ -10,6 +10,8 @@ export type * from './store.types';
// Shared cross-cutting types — import from '@packages/shared' anywhere: // Shared cross-cutting types — import from '@packages/shared' anywhere:
export type * from './upload.types'; // ContextString, UploadInput, UploadBatchInput, UploadResult 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
export type * from './seed.types'; // UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData export type * from './seed.types'; // UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData
export type * from './inputs.types'; // CreateBannerInput, UpdateBannerInput, CreateStoreInput, Login/Register requests export type * from './inputs.types'; // CreateBannerInput, UpdateBannerInput, CreateStoreInput, Login/Register requests
export type * from './cache.types'; // ProductTagData, TagProductMapping, UserNegativityData (truly identical subset) export type * from './cache.types'; // ProductTagData, TagProductMapping, UserNegativityData (truly identical subset)

View file

@ -0,0 +1,49 @@
/**
* Order-domain shared types
* Were identically duplicated in db_helper_sqlite and db_helper_postgres.
* Canonical: import these from @packages/shared instead of redeclaring locally.
* NOTE: OrderWithFullData / OrderWithCancellationData / OrderWithRelations are
* intentionally NOT here they drift between the sku-model (sqlite) and
* product-model (postgres) schemas and keep their local defs.
*/
export interface PlacedOrder {
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
}
export interface CouponUsageWithCoupon {
id: number
couponId: number
orderId: number | null
coupon: {
id: number
couponCode: string
discountPercent: string | null
flatDiscount: string | null
maxValue: string | null
}
}
export type GetAllOrdersInput = {
cursor?: number
limit: number
slotId?: number | null
packagedFilter?: 'all' | 'packaged' | 'not_packaged'
deliveredFilter?: 'all' | 'delivered' | 'not_delivered'
cancellationFilter?: 'all' | 'cancelled' | 'not_cancelled'
flashDeliveryFilter?: 'all' | 'flash' | 'regular'
}

View file

@ -0,0 +1,15 @@
/**
* 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.
*/
export interface MessageResponse {
success: boolean
message: string
}
export interface IdName {
id: number
name: string
}

View file

@ -1,5 +1,12 @@
// User-related types // User-related types
import type { MessageResponse } from './primitives.types'
import type { Banner } from './banner.types'
// UserBanner is exactly the shared Banner shape — single source in banner.types.ts
export type UserBanner = Banner
export interface User { export interface User {
id: number; id: number;
name: string | null; name: string | null;
@ -58,10 +65,7 @@ export interface UserAddressesResponse {
data: UserAddress[]; data: UserAddress[];
} }
export interface UserAddressDeleteResponse { export type UserAddressDeleteResponse = MessageResponse
success: boolean;
message: string;
}
export interface Product { export interface Product {
id: number; id: number;
@ -116,19 +120,6 @@ export interface Payment {
createdAt: Date; createdAt: Date;
} }
export interface UserBanner {
id: number;
name: string;
imageUrl: string;
description: string | null;
skuIds: number[] | null;
redirectUrl: string | null;
serialNum: number | null;
isActive: boolean;
createdAt: Date;
lastUpdated: Date;
}
export interface UserBannersResponse { export interface UserBannersResponse {
banners: UserBanner[]; banners: UserBanner[];
} }
@ -146,10 +137,7 @@ export interface UserComplaintsResponse {
complaints: UserComplaint[]; complaints: UserComplaint[];
} }
export interface UserRaiseComplaintResponse { export type UserRaiseComplaintResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserTagSummary { export interface UserTagSummary {
id: number; id: number;
@ -368,15 +356,9 @@ export interface UserPaymentOrderResponse {
key: string | undefined; key: string | undefined;
} }
export interface UserPaymentVerifyResponse { export type UserPaymentVerifyResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserPaymentFailResponse { export type UserPaymentFailResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserAuthProfile { export interface UserAuthProfile {
id: number; id: number;
@ -414,15 +396,9 @@ export interface UserOtpVerifyResponse {
}; };
} }
export interface UserPasswordUpdateResponse { export type UserPasswordUpdateResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserDeleteAccountResponse { export type UserDeleteAccountResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserCouponUsage { export interface UserCouponUsage {
id: number; id: number;
@ -574,12 +550,6 @@ export interface UserOrderDetail extends UserOrderSummary {
orderAmount: number; orderAmount: number;
} }
export interface UserCancelOrderResponse { export type UserCancelOrderResponse = MessageResponse
success: boolean;
message: string;
}
export interface UserUpdateNotesResponse { export type UserUpdateNotesResponse = MessageResponse
success: boolean;
message: string;
}