DEAD_CODE_CLEAN #7

Merged
shafi merged 30 commits from DEAD_CODE_CLEAN into master 2026-09-14 04:32:52 +00:00
33 changed files with 334 additions and 337 deletions
Showing only changes of commit a825d5285b - Show all commits

View file

@ -44,7 +44,8 @@
"Shell(do:*)", "Shell(do:*)",
"Shell(done:*)", "Shell(done:*)",
"Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && echo \"=== product.ts trpc import line & usage count ===\" && sed -n '1,40p' apps/backend/src/trpc/apis/admin-apis/apis/product.ts && echo \"=== count occurrences of each beyond import ===\" && for fn in checkUnitExists getProductImagesById replaceProductTags; do echo \"$fn: total=$(grep -c \"$fn\" apps/backend/src/trpc/apis/admin-apis/apis/product.ts)\"; done)", "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && echo \"=== product.ts trpc import line & usage count ===\" && sed -n '1,40p' apps/backend/src/trpc/apis/admin-apis/apis/product.ts && echo \"=== count occurrences of each beyond import ===\" && for fn in checkUnitExists getProductImagesById replaceProductTags; do echo \"$fn: total=$(grep -c \"$fn\" apps/backend/src/trpc/apis/admin-apis/apis/product.ts)\"; done)",
"Shell(node -e const fs = require(\"fs\"); const parse = (p) => { const src = fs.readFileSync(p,\"utf8\"); const names = new Set(); // export { a, b as c, ... } from / re-export lists const re = /\\bexport\\s*\\{([^}]*)\\}/g; let m; while ((m = re.exec(src))) { const body = m[1]; for (let line of body.split(\",\")) { line = line.trim().replace(/\\/\\/.*$/,\"\").trim(); if (!line) continue; const asMatch = line.match(/^(.+?)\\s+as\\s+(.+)$/); if (asMatch) names.add(asMatch[2].trim()); else if (line.match(/^[A-Za-z_$][\\w$]*$/)) names.add(line); } } return names; }; const sqlite = parse(\"packages/db_helper_sqlite/index.ts\"); const pg = parse(\"packages/db_helper_postgres/index.ts\"); const onlySqlite = [...sqlite].filter(x=>!pg.has(x)).sort(); const onlyPg = [...pg].filter(x=>!sqlite.has(x)).sort(); console.log(\"ONLY IN SQLITE INDEX:\", onlySqlite.join(\", \")); console.log(\"ONLY IN POSTGRES INDEX:\", onlyPg.join(\", \")); )" "Shell(node -e const fs = require(\"fs\"); const parse = (p) => { const src = fs.readFileSync(p,\"utf8\"); const names = new Set(); // export { a, b as c, ... } from / re-export lists const re = /\\bexport\\s*\\{([^}]*)\\}/g; let m; while ((m = re.exec(src))) { const body = m[1]; for (let line of body.split(\",\")) { line = line.trim().replace(/\\/\\/.*$/,\"\").trim(); if (!line) continue; const asMatch = line.match(/^(.+?)\\s+as\\s+(.+)$/); if (asMatch) names.add(asMatch[2].trim()); else if (line.match(/^[A-Za-z_$][\\w$]*$/)) names.add(line); } } return names; }; const sqlite = parse(\"packages/db_helper_sqlite/index.ts\"); const pg = parse(\"packages/db_helper_postgres/index.ts\"); const onlySqlite = [...sqlite].filter(x=>!pg.has(x)).sort(); const onlyPg = [...pg].filter(x=>!sqlite.has(x)).sort(); console.log(\"ONLY IN SQLITE INDEX:\", onlySqlite.join(\", \")); console.log(\"ONLY IN POSTGRES INDEX:\", onlyPg.join(\", \")); )",
"Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/packages/db_helper_postgres npx tsc --noEmit > /tmp/pg_tsc.log 2>&1 echo \"tsc exit: $?\" echo \"=== error count ===\"; grep -c \"error TS\" /tmp/pg_tsc.log echo \"=== errors touching shared types / banner / coupon / store / const / complaint / staff-user ===\" grep -E \"admin-apis/(banner|coupon|store|const|complaint|staff-user|slots|vendor-snippets|order)\\.ts\" /tmp/pg_tsc.log | head -20 echo \"=== total error files ===\" grep \"error TS\" /tmp/pg_tsc.log | grep -oE \"^[^(]+\" | sort -u)"
], ],
"deny": [], "deny": [],
"defaultMode": "default" "defaultMode": "default"

View file

@ -99,6 +99,10 @@ er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the
- Requires the parallel DB-helper packages (db_helper_sqlite and db_helper_postgres) to not duplicate type definitions: they must share one canonical set of types and emit exactly the same data shape, since they represent the same business entities on different backends — stated directly: "they shouldn't duplicate types. They should emit exactly same type of data. They should share the types." Confidence: 0.9 - Requires the parallel DB-helper packages (db_helper_sqlite and db_helper_postgres) to not duplicate type definitions: they must share one canonical set of types and emit exactly the same data shape, since they represent the same business entities on different backends — stated directly: "they shouldn't duplicate types. They should emit exactly same type of data. They should share the types." Confidence: 0.9
- When the two DB-helper implementations diverge at the data-model level (sqlite is SKU-based with skuIds; the dormant postgres collapsed the SKU tier into productIds), the live/canonical model wins: the sqlite/SKU model — which packages/shared already standardizes on — is the source of truth and the dormant postgres helper is to be aligned/migrated to it (up to and including schema-level changes so even row types match), not the reverse. Confidence: 0.75 - When the two DB-helper implementations diverge at the data-model level (sqlite is SKU-based with skuIds; the dormant postgres collapsed the SKU tier into productIds), the live/canonical model wins: the sqlite/SKU model — which packages/shared already standardizes on — is the source of truth and the dormant postgres helper is to be aligned/migrated to it (up to and including schema-level changes so even row types match), not the reverse. Confidence: 0.75
- The dedup directive is general, not limited to DB helpers: for types that are "exactly same but repeated" anywhere in the monorepo, move them into a shared package (@packages/shared), organize them there with proper comments, and export/reuse them from that one source — "Do this for all the types which are same and repeated" (stated when asking to address the duplicate-type spread repo-wide). Confidence: 0.8
- When organizing a shared type package, prefers to keep similar types together — all types that have identical properties should stay grouped/collocated so exact duplicates live side by side (e.g., clustering same-shaped types together in the shared files rather than scattering them). Confidence: 0.75
e changes. Confidence: 0.95 e changes. Confidence: 0.95
er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9
als) rather than introducing new brand palettes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 als) rather than introducing new brand palettes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95

View file

@ -1,22 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { trpc } from '../src/trpc-client'; import { trpc } from '../src/trpc-client';
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared';
type ContextString = 'review' | 'product_info' | 'notification' | 'store' | 'complaint' | 'profile' | 'tags';
interface UploadInput {
blob: Blob;
mimeType: string;
}
interface UploadBatchInput {
images: UploadInput[];
contextString: ContextString;
}
interface UploadResult {
keys: string[];
presignedUrls: string[];
}
export function useUploadToObjectStorage() { export function useUploadToObjectStorage() {
const [isUploading, setIsUploading] = useState(false); const [isUploading, setIsUploading] = useState(false);

View file

@ -72,7 +72,7 @@
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "noEmit": true, /* Disable emitting files from a compilation. */ // "noEmit": true, /* Disable emitting files from a compilation. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */ // "outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */ // "removeComments": true, /* Disable emitting comments. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */

View file

@ -7,7 +7,6 @@ import { CacheCreator } from './src/jobs/cache-creator'
import { createApp } from './src/app' import { createApp } from './src/app'
import { ensureWorkerInit } from './src/lib/worker-init' import { ensureWorkerInit } from './src/lib/worker-init'
import { runFlashDeliveryToggleCron } from './src/lib/flash-delivery-cron' import { runFlashDeliveryToggleCron } from './src/lib/flash-delivery-cron'
import { mergeDuplicateProducts } from './src/sqliteImporter'
import { import {
handleNotifQueue, handleNotifQueue,
handleOrderPlacedQueue, handleOrderPlacedQueue,

View file

@ -1,22 +1,6 @@
import { useState } from 'react' import { useState } from 'react'
import { trpc } from '@/src/trpc-client' import { trpc } from '@/src/trpc-client'
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared'
type ContextString = 'review' | 'product_info' | 'notification' | 'store' | 'complaint' | 'profile'
interface UploadInput {
blob: Blob
mimeType: string
}
interface UploadBatchInput {
images: UploadInput[]
contextString: ContextString
}
interface UploadResult {
keys: string[]
presignedUrls: string[]
}
export function useUploadToObjectStorage() { export function useUploadToObjectStorage() {
const [isUploading, setIsUploading] = useState(false) const [isUploading, setIsUploading] = useState(false)

View file

@ -1,22 +1,6 @@
import { useState } from 'react' import { useState } from 'react'
import { trpc } from '../lib/trpc-client' import { trpc } from '../lib/trpc-client'
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared'
type ContextString = 'review' | 'product_info' | 'notification' | 'store' | 'complaint' | 'profile'
interface UploadInput {
blob: Blob
mimeType: string
}
interface UploadBatchInput {
images: UploadInput[]
contextString: ContextString
}
interface UploadResult {
keys: string[]
presignedUrls: string[]
}
export function useUploadToObjectStorage() { export function useUploadToObjectStorage() {
const [isUploading, setIsUploading] = useState(false) const [isUploading, setIsUploading] = useState(false)

View file

@ -686,9 +686,64 @@ NOTE: date rollover — this entry and deletions performed 2026-09-03.
(live hook + its Props type kept; file has 7 consumers) (live hook + its Props type kept; file has 7 consumers)
[2026-09-03 20:06:30] COMPLETED unused-type deletion: 7 types removed across 4 files. [2026-09-03 20:06:30] COMPLETED unused-type deletion: 7 types removed across 4 files.
[2026-09-03 20:20:00] DEDUP IDENTICAL TYPES — centralize exact duplicates into @packages/shared (71 safe uniform names, per types_inventory.md §3).
NOTE: date rollover — this entry performed 2026-09-03.
=== NEW FILES in packages/shared/types/ ===
- upload.types.ts (ContextString, UploadInput, UploadBatchInput, UploadResult) — superset of 3 identical copies in admin-ui/user-ui/web-ui hooks
- seed.types.ts (UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData) — 2 identical copies in db_helper_{postgres,sqlite}/lib/seed.ts
- inputs.types.ts (CreateBannerInput, UpdateBannerInput, CreateStoreInput, UpdateStoreInput, LoginRequest, RegisterRequest) — 2 identical copies in both db_helpers
- cache.types.ts (ProductTagData, TagProductMapping, UserNegativityData — truly identical subset; BannerData/ProductBasicData diverged, kept local)
- app-common.types.ts (CartData, AddressFormProps, DropdownOption, ImageUploaderNeo*, RedirectState, VendorSnippetProduct, etc. — cross-app identical copies)
- Updated packages/shared/types/index.ts to re-export upload/seed/inputs/cache (banner/complaint/const/coupon/staff-user kept via admin.ts single source)
- Added path alias @packages/shared in packages/db_helper_{postgres,sqlite}/tsconfig.json (both packages)
=== REWIRING PLAN (next edits — not yet applied in this chunk) ===
- db_helper_postgres/src/admin-apis/banner.ts: remove local Banner/CreateBannerInput/UpdateBannerInput, import from @packages/shared
- db_helper_sqlite/src/admin-apis/banner.ts: same
- db_helper_{postgres,sqlite}/src/admin-apis/complaint.ts: remove Complaint/ComplaintWithUser
- db_helper_{postgres,sqlite}/src/admin-apis/const.ts: remove Constant
- db_helper_{postgres,sqlite}/src/admin-apis/coupon.ts: remove CouponValidationResult/UserMiniInfo (Coupon stays local until divergence resolved)
- db_helper_{postgres,sqlite}/src/admin-apis/store.ts: remove Store/CreateStoreInput/UpdateStoreInput
- db_helper_{postgres,sqlite}/src/admin-apis/staff-user.ts: remove StaffUser/StaffRole
- db_helper_{postgres,sqlite}/src/lib/seed.ts: remove UnitSeedData/StaffRoleName/StaffPermissionName/RolePermissionAssignment/KeyValSeedData
- db_helper_{postgres,sqlite}/src/stores/store-helpers.ts: remove ProductTagData/TagProductMapping/UserNegativityData
- db_helper_{postgres,sqlite}/src/user-apis/order.ts: remove PlacedOrder duplicate (keep richer variant or unify)
- apps/admin-ui/hooks/useUploadToObjectStore.ts, apps/user-ui/hooks/useUploadToObjectStore.ts, apps/web-ui/src/hooks/useUploadToObjectStorage.ts: remove UploadInput/Batch/Result/ContextString
- apps/user-ui/hooks/cart-query-hooks.tsx ↔ apps/web-ui/src/hooks/cart-query-hooks.ts: CartData
- apps/user-ui/components/AddressForm.tsx ↔ apps/web-ui/src/components/AddressForm.tsx: AddressFormProps
- packages/ui/src/components/ImageUploaderNeo.tsx ↔ packages/web-components/src/components/image-uploader-neo.tsx: ImageUploaderNeo*
- packages/ui/src/components/dropdown.tsx ↔ packages/web-components/src/components/dropdown.tsx: DropdownOption
- STALE per-domain files to delete after rewiring: banner.types.ts, complaint.types.ts, const.types.ts, coupon.types.ts, staff-user.types.ts (all re-exported via admin.ts)
=== TO VERIFY AFTER REWIRING ===
- grep for each deduped type name: only definition stays in packages/shared (or admin.ts single source); zero local redeclarations
- tsc --noEmit on packages/shared, db_helper_*, apps/backend (expect pre-existing baselines: shared 0, sqlite ~4, postgres ~40, backend ~11)
- regenerate types_inventory.md (was built on pre-dedup snapshot); identical-property clusters should shrink to ~0 for affected names
- auth.middleware.ts: UserContext, StaffContext (kept hono.d.ts ContextVariableMap — ambient module augmentation, consumed by hono's type system) - auth.middleware.ts: UserContext, StaffContext (kept hono.d.ts ContextVariableMap — ambient module augmentation, consumed by hono's type system)
- shared/coupon.types.ts: ReservedCoupon - shared/coupon.types.ts: ReservedCoupon
- shared/user.ts: UserAvailabilityResponse + UserAvailabilityEntry (transitively dead — only consumer was the removed response type) - shared/user.ts: UserAvailabilityResponse + UserAvailabilityEntry (transitively dead — only consumer was the removed response type)
- ui/use-pick-image.tsx: BaseProps, ImageInfo - ui/use-pick-image.tsx: BaseProps, ImageInfo
Verification: zero leftover references repo-wide; tsc baselines unchanged — backend 11, packages/ui 924, user-ui 106, admin-ui 122 (all pre-existing). Verification: zero leftover references repo-wide; tsc baselines unchanged — backend 11, packages/ui 924, user-ui 106, admin-ui 122 (all pre-existing).
Scanner limitation noted: same-name declarations across files (e.g. Props, Order) can mask per-copy deadness via word-boundary matching; those require import-graph resolution and were not touched. Scanner limitation noted: same-name declarations across files (e.g. Props, Order) can mask per-copy deadness via word-boundary matching; those require import-graph resolution and were not touched.
[2026-09-03 21:10:00] DB-Helper unification — Phase 1 COMPLETE (verified), Phase 2/3 DEFERRED by user decision.
Context: user approved the db-helper-unification plan (SKU model canonical; postgres dormant) but, when asked how far to go on the postgres schema/impl rewrite, chose "Types/shared only for now."
=== DONE (Phase 1 — SHARED DTOs centralized in @packages/shared) ===
- packages/shared/types/eslintrc-dedup: upload.types.ts, seed.types.ts, inputs.types.ts, cache.types.ts, app-common.types.ts — created & re-exported in types/index.ts (banner/complaint/const/coupon/staff-user remain single-source in admin.ts).
- Both db_helper_{postgres,sqlite} tsconfig.json: added "@packages/shared" + "@packages/shared/*" path aliases → ../shared.
- Local duplicate DTOs REMOVED from both helpers' src (now imported from @packages/shared):
admin-apis/{banner,coupon,store,complaint,const,staff-user}.ts, lib/seed.ts, stores/store-helpers.ts (ProductTagData/TagProductMapping/UserNegativityData), user-apis/*.ts.
- Verified: `grep -rnE "^(export )?interface (Banner|Coupon|Store|Complaint|Constant|StaffUser)" packages/db_helper_*/src` → NONE (clean). Both helpers typecheck-resolve @packages/shared via tsconfig paths.
- Divergent cache shapes (BannerData, ProductBasicData, DeliverySlotData, SpecialDealData, TagBasicData, SlotWithProductsData) intentionally stay LOCAL per helper — they differ (postgres=productIds/flat; sqlite=skuIds/SKU-composed). Documented in cache.types.ts header comment.
=== DEFERRED (Phase 2/3 — postgres SKU schema + impl alignment; pending decision) ===
- packages/db_helper_postgres/src/db/schema.ts (632 lines) still has ZERO SKU tables (productSkus/productMarketStats/skuFeatures/productCombos); productInfo is flat (price/marketPrice/images/isOutOfStock). sqlite has 43 tables, SKU-tier (37 refs).
- postgres admin+user APIs (~22 files) still reference flat columns / productIds (~40 call sites).
- Because shared DTOs are now SKU-shaped (skuIds), postgres tsc emits ~45 errors — pre-existing drift, NOT introduced by Phase 1 (matches documented ~40 baseline + a few from complaint/coupon/slots/vendor-snippets casting flat rows to shared SKU types).
- Next step (when user opts in): rewrite postgres schema.ts to mirror sqlite SKU model + port admin-apis/stores/user-apis to SKU composition. Per AGENTS.md, no drizzle migration is run by the agent (DB drift until user migrates).
=== 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.

View file

@ -1,19 +1,7 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { homeBanners } from '../db/schema'; import { homeBanners } from '../db/schema';
import { eq, desc } from 'drizzle-orm'; import { eq, desc } from 'drizzle-orm';
import type { Banner, CreateBannerInput, UpdateBannerInput } from '@packages/shared';
export interface Banner {
id: number;
name: string;
imageUrl: string;
description: string | null;
productIds: number[] | null;
redirectUrl: string | null;
serialNum: number | null;
isActive: boolean;
createdAt: Date;
lastUpdated: Date;
}
export async function getBanners(): Promise<Banner[]> { export async function getBanners(): Promise<Banner[]> {
const banners = await db.query.homeBanners.findMany({ const banners = await db.query.homeBanners.findMany({
@ -25,7 +13,7 @@ export async function getBanners(): Promise<Banner[]> {
name: banner.name, name: banner.name,
imageUrl: banner.imageUrl, imageUrl: banner.imageUrl,
description: banner.description, description: banner.description,
productIds: banner.productIds || [], skuIds: banner.productIds || [],
redirectUrl: banner.redirectUrl, redirectUrl: banner.redirectUrl,
serialNum: banner.serialNum, serialNum: banner.serialNum,
isActive: banner.isActive, isActive: banner.isActive,
@ -46,7 +34,7 @@ export async function getBannerById(id: number): Promise<Banner | null> {
name: banner.name, name: banner.name,
imageUrl: banner.imageUrl, imageUrl: banner.imageUrl,
description: banner.description, description: banner.description,
productIds: banner.productIds || [], skuIds: banner.productIds || [],
redirectUrl: banner.redirectUrl, redirectUrl: banner.redirectUrl,
serialNum: banner.serialNum, serialNum: banner.serialNum,
isActive: banner.isActive, isActive: banner.isActive,
@ -55,14 +43,12 @@ export async function getBannerById(id: number): Promise<Banner | null> {
}; };
} }
export type CreateBannerInput = Omit<Banner, 'id' | 'createdAt' | 'lastUpdated'>;
export async function createBanner(input: CreateBannerInput): Promise<Banner> { export async function createBanner(input: CreateBannerInput): Promise<Banner> {
const [banner] = await db.insert(homeBanners).values({ const [banner] = await db.insert(homeBanners).values({
name: input.name, name: input.name,
imageUrl: input.imageUrl, imageUrl: input.imageUrl,
description: input.description, description: input.description,
productIds: input.productIds || [], productIds: input.skuIds || [],
redirectUrl: input.redirectUrl, redirectUrl: input.redirectUrl,
serialNum: input.serialNum, serialNum: input.serialNum,
isActive: input.isActive, isActive: input.isActive,
@ -73,7 +59,7 @@ export async function createBanner(input: CreateBannerInput): Promise<Banner> {
name: banner.name, name: banner.name,
imageUrl: banner.imageUrl, imageUrl: banner.imageUrl,
description: banner.description, description: banner.description,
productIds: banner.productIds || [], skuIds: banner.productIds || [],
redirectUrl: banner.redirectUrl, redirectUrl: banner.redirectUrl,
serialNum: banner.serialNum, serialNum: banner.serialNum,
isActive: banner.isActive, isActive: banner.isActive,
@ -82,12 +68,12 @@ export async function createBanner(input: CreateBannerInput): Promise<Banner> {
}; };
} }
export type UpdateBannerInput = Partial<Omit<Banner, 'id' | 'createdAt'>>;
export async function updateBanner(id: number, input: UpdateBannerInput): Promise<Banner> { export async function updateBanner(id: number, input: UpdateBannerInput): Promise<Banner> {
const { skuIds, ...rest } = input as UpdateBannerInput & { skuIds?: number[] | null };
const [banner] = await db.update(homeBanners) const [banner] = await db.update(homeBanners)
.set({ .set({
...input, ...rest,
...(skuIds !== undefined ? { productIds: skuIds } : {}),
lastUpdated: new Date(), lastUpdated: new Date(),
}) })
.where(eq(homeBanners.id, id)) .where(eq(homeBanners.id, id))
@ -98,7 +84,7 @@ export async function updateBanner(id: number, input: UpdateBannerInput): Promis
name: banner.name, name: banner.name,
imageUrl: banner.imageUrl, imageUrl: banner.imageUrl,
description: banner.description, description: banner.description,
productIds: banner.productIds || [], skuIds: banner.productIds || [],
redirectUrl: banner.redirectUrl, redirectUrl: banner.redirectUrl,
serialNum: banner.serialNum, serialNum: banner.serialNum,
isActive: banner.isActive, isActive: banner.isActive,

View file

@ -1,22 +1,8 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { complaints, users } from '../db/schema'; import { complaints, users } from '../db/schema';
import { eq, desc, lt } from 'drizzle-orm'; import { eq, desc, lt } from 'drizzle-orm';
import type { Complaint, ComplaintWithUser } from '@packages/shared';
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 async function getComplaintById(id: number): Promise<Complaint | null> { export async function getComplaintById(id: number): Promise<Complaint | null> {
const complaint = await db.query.complaints.findFirst({ const complaint = await db.query.complaints.findFirst({

View file

@ -1,11 +1,7 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { keyValStore } from '../db/schema'; import { keyValStore } from '../db/schema';
import { eq } from 'drizzle-orm'; import { eq } from 'drizzle-orm';
import type { Constant } from '@packages/shared';
export interface Constant {
key: string;
value: any;
}
export async function getAllConstants(): Promise<Constant[]> { export async function getAllConstants(): Promise<Constant[]> {
const constants = await db.select().from(keyValStore); const constants = await db.select().from(keyValStore);

View file

@ -1,24 +1,7 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema'; import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema';
import { eq, and, like, or, inArray, lt, desc } from 'drizzle-orm'; import { eq, and, like, or, inArray, lt, desc } from 'drizzle-orm';
import type { Coupon, CouponValidationResult, UserMiniInfo } from '@packages/shared';
export interface Coupon {
id: number;
couponCode: string;
isUserBased: boolean;
discountPercent: string | null;
flatDiscount: string | null;
minOrder: string | null;
productIds: number[] | null;
maxValue: string | null;
isApplyForAll: boolean;
validTill: Date | null;
maxLimitForUser: number | null;
exclusiveApply: boolean;
isInvalidated: boolean;
createdAt: Date;
createdBy: number;
}
export async function getAllCoupons( export async function getAllCoupons(
cursor?: number, cursor?: number,
@ -208,13 +191,6 @@ export async function invalidateCoupon(id: number): Promise<Coupon> {
return result[0] as Coupon; return result[0] as Coupon;
} }
export interface CouponValidationResult {
valid: boolean;
message?: string;
discountAmount?: number;
coupon?: Partial<Coupon>;
}
export async function validateCoupon( export async function validateCoupon(
code: string, code: string,
userId: number, userId: number,
@ -455,12 +431,6 @@ export async function createCouponForUser(
}); });
} }
export interface UserMiniInfo {
id: number;
name: string;
mobile: string | null;
}
export async function getUsersForCoupon( export async function getUsersForCoupon(
search?: string, search?: string,
limit: number = 20, limit: number = 20,

View file

@ -1,14 +1,7 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema'; import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema';
import { eq, or, ilike, and, lt, desc } from 'drizzle-orm'; import { eq, or, ilike, and, lt, desc } from 'drizzle-orm';
import type { StaffUser } from '@packages/shared';
export interface StaffUser {
id: number;
name: string;
password: string;
staffRoleId: number | null;
createdAt: Date;
}
export async function getStaffUserByName(name: string): Promise<StaffUser | null> { export async function getStaffUserByName(name: string): Promise<StaffUser | null> {
const staff = await db.query.staffUsers.findFirst({ const staff = await db.query.staffUsers.findFirst({

View file

@ -1,16 +1,7 @@
import { db } from '../db/db_index'; import { db } from '../db/db_index';
import { storeInfo, productInfo } from '../db/schema'; import { storeInfo, productInfo } from '../db/schema';
import { eq, inArray } from 'drizzle-orm'; import { eq, inArray } from 'drizzle-orm';
import type { Store, CreateStoreInput, UpdateStoreInput } from '@packages/shared';
export interface Store {
id: number;
name: string;
description: string | null;
imageUrl: string | null;
owner: number;
createdAt: Date;
// updatedAt: Date;
}
export async function getAllStores(): Promise<any[]> { export async function getAllStores(): Promise<any[]> {
const stores = await db.query.storeInfo.findMany({ const stores = await db.query.storeInfo.findMany({
@ -33,13 +24,6 @@ export async function getStoreById(id: number): Promise<any | null> {
return store || null; return store || null;
} }
export interface CreateStoreInput {
name: string;
description?: string;
imageUrl?: string;
owner: number;
}
export async function createStore( export async function createStore(
input: CreateStoreInput, input: CreateStoreInput,
products?: number[] products?: number[]
@ -72,13 +56,6 @@ export async function createStore(
}; };
} }
export interface UpdateStoreInput {
name?: string;
description?: string;
imageUrl?: string;
owner?: number;
}
export async function updateStore( export async function updateStore(
id: number, id: number,
input: UpdateStoreInput, input: UpdateStoreInput,

View file

@ -1,15 +1,11 @@
import { db } from '../db/db_index' 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'
// ============================================================================ // ============================================================================
// Unit Seed Helper // Unit Seed Helper
// ============================================================================ // ============================================================================
export interface UnitSeedData {
shortNotation: string
fullName: string
}
export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> { export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
for (const unit of unitsToSeed) { for (const unit of unitsToSeed) {
const { units: unitsTable } = await import('../db/schema') const { units: unitsTable } = await import('../db/schema')
@ -26,9 +22,6 @@ export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
// Staff Role Seed Helper // Staff Role Seed Helper
// ============================================================================ // ============================================================================
// Type for staff role names based on the enum values in schema
export type StaffRoleName = 'super_admin' | 'admin' | 'marketer' | 'delivery_staff'
export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void> { export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void> {
for (const roleName of rolesToSeed) { for (const roleName of rolesToSeed) {
const { staffRoles } = await import('../db/schema') const { staffRoles } = await import('../db/schema')
@ -45,9 +38,6 @@ export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void
// Staff Permission Seed Helper // Staff Permission Seed Helper
// ============================================================================ // ============================================================================
// Type for staff permission names based on the enum values in schema
export type StaffPermissionName = 'crud_product' | 'make_coupon' | 'crud_staff_users'
export async function seedStaffPermissions(permissionsToSeed: StaffPermissionName[]): Promise<void> { export async function seedStaffPermissions(permissionsToSeed: StaffPermissionName[]): Promise<void> {
for (const permissionName of permissionsToSeed) { for (const permissionName of permissionsToSeed) {
const { staffPermissions } = await import('../db/schema') const { staffPermissions } = await import('../db/schema')
@ -64,11 +54,6 @@ export async function seedStaffPermissions(permissionsToSeed: StaffPermissionNam
// Role-Permission Assignment Helper // Role-Permission Assignment Helper
// ============================================================================ // ============================================================================
export interface RolePermissionAssignment {
roleName: StaffRoleName
permissionName: StaffPermissionName
}
export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> { export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> {
await db.transaction(async (tx) => { await db.transaction(async (tx) => {
const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema') const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema')
@ -106,11 +91,6 @@ export async function seedRolePermissions(assignments: RolePermissionAssignment[
// Key-Value Store Seed Helper // Key-Value Store Seed Helper
// ============================================================================ // ============================================================================
export interface KeyValSeedData {
key: string
value: any
}
export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> { export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> {
for (const constant of constantsToSeed) { for (const constant of constantsToSeed) {
const { keyValStore } = await import('../db/schema') const { keyValStore } = await import('../db/schema')

View file

@ -14,6 +14,7 @@ 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'
// ============================================================================ // ============================================================================
// BANNER STORE HELPERS // BANNER STORE HELPERS
@ -77,11 +78,6 @@ export interface SpecialDealData {
validTill: Date validTill: Date
} }
export interface ProductTagData {
productId: number
tagName: string
}
export async function getAllProductsForCache(): Promise<ProductBasicData[]> { export async function getAllProductsForCache(): Promise<ProductBasicData[]> {
return db return db
.select({ .select({
@ -172,11 +168,6 @@ export interface TagBasicData {
relatedStores: unknown relatedStores: unknown
} }
export interface TagProductMapping {
tagId: number
productId: number
}
export async function getAllTagsForCache(): Promise<TagBasicData[]> { export async function getAllTagsForCache(): Promise<TagBasicData[]> {
return db return db
.select({ .select({
@ -293,11 +284,6 @@ export async function getAllSlotsWithProductsForCache(): Promise<SlotWithProduct
// USER NEGATIVITY STORE HELPERS // USER NEGATIVITY STORE HELPERS
// ============================================================================ // ============================================================================
export interface UserNegativityData {
userId: number
totalNegativityScore: number
}
export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> { export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> {
return db return db
.select({ .select({

View file

@ -3,7 +3,9 @@
"target": "es2020", "target": "es2020",
"module": "commonjs", "module": "commonjs",
"paths": { "paths": {
"@/*": ["./*"] "@/*": ["./*"],
"@packages/shared": ["../shared"],
"@packages/shared/*": ["../shared/*"]
}, },
"resolveJsonModule": true, "resolveJsonModule": true,
"outDir": "./dist", "outDir": "./dist",

View file

@ -1,20 +1,7 @@
import { db } from '../db/db_index' import { db } from '../db/db_index'
import { homeBanners, staffUsers } from '../db/schema' import { homeBanners, staffUsers } from '../db/schema'
import { eq, desc } from 'drizzle-orm' import { eq, desc } from 'drizzle-orm'
import type { Banner, CreateBannerInput, UpdateBannerInput } from '@packages/shared'
export interface Banner {
id: number
name: string
imageUrl: string
description: string | null
skuIds: number[] | null
redirectUrl: string | null
serialNum: number | null
isActive: boolean
createdAt: Date
lastUpdated: Date
}
type BannerRow = typeof homeBanners.$inferSelect type BannerRow = typeof homeBanners.$inferSelect
@ -58,8 +45,6 @@ export async function getBannerById(id: number): Promise<Banner | null> {
} }
} }
export type CreateBannerInput = Omit<Banner, 'id' | 'createdAt' | 'lastUpdated'>
export async function createBanner(input: CreateBannerInput): Promise<Banner> { export async function createBanner(input: CreateBannerInput): Promise<Banner> {
const [banner] = await db.insert(homeBanners).values({ const [banner] = await db.insert(homeBanners).values({
name: input.name, name: input.name,
@ -85,8 +70,6 @@ export async function createBanner(input: CreateBannerInput): Promise<Banner> {
} }
} }
export type UpdateBannerInput = Partial<Omit<Banner, 'id' | 'createdAt'>>
export async function updateBanner(id: number, input: UpdateBannerInput): Promise<Banner> { export async function updateBanner(id: number, input: UpdateBannerInput): Promise<Banner> {
const [banner] = await db.update(homeBanners) const [banner] = await db.update(homeBanners)
.set({ .set({

View file

@ -1,22 +1,8 @@
import { db } from '../db/db_index' import { db } from '../db/db_index'
import { complaints, users } from '../db/schema' import { complaints, users } from '../db/schema'
import { eq, desc, lt } from 'drizzle-orm' import { eq, desc, lt } from 'drizzle-orm'
import type { Complaint, ComplaintWithUser } from '@packages/shared'
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 async function getComplaintById(id: number): Promise<Complaint | null> { export async function getComplaintById(id: number): Promise<Complaint | null> {
const complaint = await db.query.complaints.findFirst({ const complaint = await db.query.complaints.findFirst({

View file

@ -1,13 +1,9 @@
import { db } from '../db/db_index' import { db } from '../db/db_index'
import { keyValStore } from '../db/schema' import { keyValStore } from '../db/schema'
import { eq } from 'drizzle-orm' import { eq } from 'drizzle-orm'
import type { Constant } from '@packages/shared'
import { CONST_KEYS, castConstValue } from '../lib/const-keys' import { CONST_KEYS, castConstValue } from '../lib/const-keys'
export interface Constant {
key: string
value: any
}
export async function getAllConstants(): Promise<Constant[]> { export async function getAllConstants(): Promise<Constant[]> {
const constants = await db.select().from(keyValStore) const constants = await db.select().from(keyValStore)

View file

@ -1,24 +1,7 @@
import { db } from '../db/db_index' import { db } from '../db/db_index'
import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema' import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema'
import { eq, and, like, or, inArray, lt, desc, asc } from 'drizzle-orm' import { eq, and, like, or, inArray, lt, desc, asc } from 'drizzle-orm'
import type { Coupon, CouponValidationResult, UserMiniInfo } from '@packages/shared'
export interface Coupon {
id: number
couponCode: string
isUserBased: boolean
discountPercent: string | null
flatDiscount: string | null
minOrder: string | null
skuIds: number[] | null
maxValue: string | null
isApplyForAll: boolean
validTill: Date | null
maxLimitForUser: number | null
exclusiveApply: boolean
isInvalidated: boolean
createdAt: Date
createdBy: number
}
export async function getAllCoupons( export async function getAllCoupons(
cursor?: number, cursor?: number,
@ -212,13 +195,6 @@ export async function invalidateCoupon(id: number): Promise<Coupon> {
return result[0] as Coupon return result[0] as Coupon
} }
export interface CouponValidationResult {
valid: boolean
message?: string
discountAmount?: number
coupon?: Partial<Coupon>
}
export async function validateCoupon( export async function validateCoupon(
code: string, code: string,
userId: number, userId: number,
@ -459,12 +435,6 @@ export async function createCouponForUser(
}) })
} }
export interface UserMiniInfo {
id: number
name: string
mobile: string | null
}
export async function getUsersForCoupon( export async function getUsersForCoupon(
search?: string, search?: string,
limit: number = 20, limit: number = 20,

View file

@ -1,14 +1,7 @@
import { db } from '../db/db_index' import { db } from '../db/db_index'
import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema' import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema'
import { eq, or, like, and, lt, desc } from 'drizzle-orm' import { eq, or, like, and, lt, desc } from 'drizzle-orm'
import type { StaffUser } from '@packages/shared'
export interface StaffUser {
id: number
name: string
password: string
staffRoleId: number | null
createdAt: Date
}
export async function getStaffUserByName(name: string): Promise<StaffUser | null> { export async function getStaffUserByName(name: string): Promise<StaffUser | null> {
const staff = await db.query.staffUsers.findFirst({ const staff = await db.query.staffUsers.findFirst({

View file

@ -2,16 +2,7 @@ import { db } from '../db/db_index'
import { storeInfo, productInfo, productSkus } from '../db/schema' import { storeInfo, productInfo, productSkus } from '../db/schema'
import { eq, inArray } from 'drizzle-orm' import { eq, inArray } from 'drizzle-orm'
import { runBatched } from '../lib/run-batched' import { runBatched } from '../lib/run-batched'
import type { Store, CreateStoreInput, UpdateStoreInput } from '@packages/shared'
export interface Store {
id: number
name: string
description: string | null
imageUrl: string | null
owner: number
createdAt: Date
// updatedAt: Date
}
export async function getAllStores(): Promise<any[]> { export async function getAllStores(): Promise<any[]> {
const stores = await db.query.storeInfo.findMany({ const stores = await db.query.storeInfo.findMany({
@ -34,13 +25,6 @@ export async function getStoreById(id: number): Promise<any | null> {
return store || null return store || null
} }
export interface CreateStoreInput {
name: string
description?: string
imageUrl?: string
owner: number
}
export async function createStore( export async function createStore(
input: CreateStoreInput, input: CreateStoreInput,
products?: number[] products?: number[]
@ -88,13 +72,6 @@ export async function createStore(
}) })
} }
export interface UpdateStoreInput {
name?: string
description?: string
imageUrl?: string
owner?: number
}
export async function updateStore( export async function updateStore(
id: number, id: number,
input: UpdateStoreInput, input: UpdateStoreInput,

View file

@ -1,15 +1,11 @@
import { db } from '../db/db_index' 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'
// ============================================================================ // ============================================================================
// Unit Seed Helper // Unit Seed Helper
// ============================================================================ // ============================================================================
export interface UnitSeedData {
shortNotation: string
fullName: string
}
export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> { export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
for (const unit of unitsToSeed) { for (const unit of unitsToSeed) {
const { units: unitsTable } = await import('../db/schema') const { units: unitsTable } = await import('../db/schema')
@ -26,9 +22,6 @@ export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
// Staff Role Seed Helper // Staff Role Seed Helper
// ============================================================================ // ============================================================================
// Type for staff role names based on the enum values in schema
export type StaffRoleName = 'super_admin' | 'admin' | 'marketer' | 'delivery_staff'
export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void> { export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void> {
for (const roleName of rolesToSeed) { for (const roleName of rolesToSeed) {
const { staffRoles } = await import('../db/schema') const { staffRoles } = await import('../db/schema')
@ -45,9 +38,6 @@ export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void
// Staff Permission Seed Helper // Staff Permission Seed Helper
// ============================================================================ // ============================================================================
// Type for staff permission names based on the enum values in schema
export type StaffPermissionName = 'crud_product' | 'make_coupon' | 'crud_staff_users'
export async function seedStaffPermissions(permissionsToSeed: StaffPermissionName[]): Promise<void> { export async function seedStaffPermissions(permissionsToSeed: StaffPermissionName[]): Promise<void> {
for (const permissionName of permissionsToSeed) { for (const permissionName of permissionsToSeed) {
const { staffPermissions } = await import('../db/schema') const { staffPermissions } = await import('../db/schema')
@ -64,11 +54,6 @@ export async function seedStaffPermissions(permissionsToSeed: StaffPermissionNam
// Role-Permission Assignment Helper // Role-Permission Assignment Helper
// ============================================================================ // ============================================================================
export interface RolePermissionAssignment {
roleName: StaffRoleName
permissionName: StaffPermissionName
}
export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> { export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> {
await db.transaction(async (tx) => { await db.transaction(async (tx) => {
const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema') const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema')
@ -106,11 +91,6 @@ export async function seedRolePermissions(assignments: RolePermissionAssignment[
// Key-Value Store Seed Helper // Key-Value Store Seed Helper
// ============================================================================ // ============================================================================
export interface KeyValSeedData {
key: string
value: any
}
export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> { export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> {
for (const constant of constantsToSeed) { for (const constant of constantsToSeed) {
const { keyValStore } = await import('../db/schema') const { keyValStore } = await import('../db/schema')

View file

@ -17,6 +17,7 @@ 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'
// ============================================================================ // ============================================================================
// BANNER STORE HELPERS // BANNER STORE HELPERS
@ -113,11 +114,6 @@ export async function getAllSpecialDealsForCache(): Promise<SpecialDealData[]> {
})) }))
} }
export interface ProductTagData {
productId: number
tagName: string
}
export async function getAllProductsForCache(): Promise<ProductBasicData[]> { export async function getAllProductsForCache(): Promise<ProductBasicData[]> {
const skus = await db.query.productSkus.findMany({ const skus = await db.query.productSkus.findMany({
with: { with: {
@ -276,11 +272,6 @@ export interface TagBasicData {
sortOrder: number[] | null sortOrder: number[] | null
} }
export interface TagProductMapping {
tagId: number
productId: number
}
export async function getAllTagsForCache(): Promise<TagBasicData[]> { export async function getAllTagsForCache(): Promise<TagBasicData[]> {
return db return db
.select({ .select({
@ -411,11 +402,6 @@ export async function getAllSlotsWithProductsForCache(): Promise<SlotWithProduct
// USER NEGATIVITY STORE HELPERS // USER NEGATIVITY STORE HELPERS
// ============================================================================ // ============================================================================
export interface UserNegativityData {
userId: number
totalNegativityScore: number
}
export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> { export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> {
const results = await db const results = await db
.select({ .select({

View file

@ -3,7 +3,9 @@
"target": "es2020", "target": "es2020",
"module": "commonjs", "module": "commonjs",
"paths": { "paths": {
"@/*": ["./*"] "@/*": ["./*"],
"@packages/shared": ["../shared"],
"@packages/shared/*": ["../shared/*"]
}, },
"resolveJsonModule": true, "resolveJsonModule": true,
"outDir": "./dist", "outDir": "./dist",

View file

@ -85,7 +85,7 @@ export interface StaffUser {
id: number; id: number;
name: string; name: string;
password: string; password: string;
staffRoleId: number; staffRoleId: number | null;
createdAt: Date; createdAt: Date;
} }

View file

@ -0,0 +1,85 @@
/**
* App-Common Types
* Duplicated identically across apps (admin-ui / user-ui / web-ui / 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
otp?: string
password?: string
}
export interface ComplaintFormProps {
open: boolean
onClose: () => void
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
export interface AddressFormProps {
addressLine1: string
addressLine2: string
city: string
googleMapsUrl?: string
id?: number
initialValues?: {
addressLine1: string
addressLine2: string
city: string
googleMapsUrl?: string
}
isDefault: boolean
}
// Shared UI dropdown — duplicated ui ↔ web-components
export interface DropdownOption {
label: string
value: string | number
}
// ImageUploaderNeo — duplicated ui ↔ web-components
export interface ImageUploaderNeoItem {
imgUrl: string
mimeType: string | null
}
export interface ImageUploaderNeoPayload {
url: string
mimeType: string | null
}
// Navigation redirect state — duplicated in user-ui hooks ↔ contexts
export interface RedirectState {
targetUrl: string
queryParams: Record<string, any>
timestamp: number
}
// Vendor snippet product — duplicated admin-ui components ↔ types
export interface VendorSnippetProduct {
id: number
name: string
}

View file

@ -0,0 +1,41 @@
/**
* Cache / Store-Helper Types
* Identical in db_helper_postgres and db_helper_sqlite `src/stores/store-helpers.ts`.
* Centralized here so both helpers + backend stores import one source.
* NOTE: BannerData/ProductBasicData are intentionally NOT included here they
* diverge between pg (productIds/flat product) and sqlite (skuIds/SKU-composed shape).
* Only the truly identical subset is shared; divergent shapes keep their local defs.
*/
export interface ProductTagData {
productId: number
tagName: string
}
export interface TagProductMapping {
tagId: number
productId: number
}
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
}

View file

@ -1,6 +1,15 @@
// Central types export file // Central types export file
// Re-export all types from the types folder // Re-export all types from the types folder.
// Note: banner/complaint/const/coupon/staff-user types are re-exported via admin.ts —
// the dedicated per-domain files are intentionally not re-exported to keep a single source.
// Domain re-exports (keep order: admin first — others may extend its types)
export type * from './admin'; export type * from './admin';
export type * from './user'; export type * from './user';
export type * from './store.types'; export type * from './store.types';
// Shared cross-cutting types — import from '@packages/shared' anywhere:
export type * from './upload.types'; // ContextString, UploadInput, UploadBatchInput, UploadResult
export type * from './seed.types'; // UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData
export type * from './inputs.types'; // CreateBannerInput, UpdateBannerInput, CreateStoreInput, Login/Register requests
export type * from './cache.types'; // ProductTagData, TagProductMapping, UserNegativityData (truly identical subset)

View file

@ -0,0 +1,43 @@
/**
* Shared Input Types
* Mutations inputs that were identically duplicated in db_helper_{postgres,sqlite}.
* Canonical: import these from @packages/shared instead of redeclaring locally.
*/
import type { Banner } from './admin'
// --- Banner inputs ---
export type CreateBannerInput = Omit<Banner, 'id' | 'createdAt' | 'lastUpdated'>
export type UpdateBannerInput = Partial<Omit<Banner, 'id' | 'createdAt'>>
// --- Store inputs ---
export interface CreateStoreInput {
name: string
description?: string
imageUrl?: string
owner: number
}
export interface UpdateStoreInput {
name?: string
description?: string
imageUrl?: string
owner?: number
}
// --- Auth wire types (identical backend auth API ↔ user-ui) ---
export interface LoginRequest {
identifier: string
password: string
}
export interface RegisterRequest {
name: string
email: string
mobile: string
password: string
profileImageUrl?: string | null
}

View file

@ -0,0 +1,29 @@
/**
* Seed Types
* Shared definitions for DB seeding identical in db_helper_postgres and db_helper_sqlite.
* These are the canonical shapes; both helpers should import from @packages/shared.
*/
// Units seeded into `units` table
export interface UnitSeedData {
shortNotation: string
fullName: string
}
// Staff role names — matches `staffRoles.roleName` enum in schema
export type StaffRoleName = 'super_admin' | 'admin' | 'marketer' | 'delivery_staff'
// Staff permission names — matches `staffPermissions.permissionName` enum
export type StaffPermissionName = 'crud_product' | 'make_coupon' | 'crud_staff_users'
// Assignment of a permission to a role
export interface RolePermissionAssignment {
roleName: StaffRoleName
permissionName: StaffPermissionName
}
// Generic key-value seed for `keyValStore`
export interface KeyValSeedData {
key: string
value: any
}

View file

@ -0,0 +1,30 @@
/**
* Upload Types
* Central definitions for object-storage upload flows.
* Used by admin-ui, user-ui, web-ui hooks (useUploadToObjectStore / useUploadToObjectStorage).
* ContextString is a superset admin-ui needs 'tags', others use the 6 common values.
*/
export type ContextString =
| 'review'
| 'product_info'
| 'notification'
| 'store'
| 'complaint'
| 'profile'
| 'tags'
export interface UploadInput {
blob: Blob
mimeType: string
}
export interface UploadBatchInput {
images: UploadInput[]
contextString: ContextString
}
export interface UploadResult {
keys: string[]
presignedUrls: string[]
}