enh
This commit is contained in:
parent
3ebbf989f0
commit
a825d5285b
33 changed files with 334 additions and 337 deletions
|
|
@ -44,7 +44,8 @@
|
|||
"Shell(do:*)",
|
||||
"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(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": [],
|
||||
"defaultMode": "default"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
- 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
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,22 +1,6 @@
|
|||
import { useState } from 'react';
|
||||
import { trpc } from '../src/trpc-client';
|
||||
|
||||
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[];
|
||||
}
|
||||
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared';
|
||||
|
||||
export function useUploadToObjectStorage() {
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "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. */
|
||||
"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. */
|
||||
// "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. */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { CacheCreator } from './src/jobs/cache-creator'
|
|||
import { createApp } from './src/app'
|
||||
import { ensureWorkerInit } from './src/lib/worker-init'
|
||||
import { runFlashDeliveryToggleCron } from './src/lib/flash-delivery-cron'
|
||||
import { mergeDuplicateProducts } from './src/sqliteImporter'
|
||||
import {
|
||||
handleNotifQueue,
|
||||
handleOrderPlacedQueue,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,6 @@
|
|||
import { useState } from 'react'
|
||||
import { trpc } from '@/src/trpc-client'
|
||||
|
||||
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[]
|
||||
}
|
||||
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared'
|
||||
|
||||
export function useUploadToObjectStorage() {
|
||||
const [isUploading, setIsUploading] = useState(false)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,6 @@
|
|||
import { useState } from 'react'
|
||||
import { trpc } from '../lib/trpc-client'
|
||||
|
||||
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[]
|
||||
}
|
||||
import type { ContextString, UploadInput, UploadBatchInput, UploadResult } from '@packages/shared'
|
||||
|
||||
export function useUploadToObjectStorage() {
|
||||
const [isUploading, setIsUploading] = useState(false)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
[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)
|
||||
- shared/coupon.types.ts: ReservedCoupon
|
||||
- shared/user.ts: UserAvailabilityResponse + UserAvailabilityEntry (transitively dead — only consumer was the removed response type)
|
||||
- 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).
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -1,19 +1,7 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { homeBanners } from '../db/schema';
|
||||
import { eq, desc } from 'drizzle-orm';
|
||||
|
||||
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;
|
||||
}
|
||||
import type { Banner, CreateBannerInput, UpdateBannerInput } from '@packages/shared';
|
||||
|
||||
export async function getBanners(): Promise<Banner[]> {
|
||||
const banners = await db.query.homeBanners.findMany({
|
||||
|
|
@ -25,7 +13,7 @@ export async function getBanners(): Promise<Banner[]> {
|
|||
name: banner.name,
|
||||
imageUrl: banner.imageUrl,
|
||||
description: banner.description,
|
||||
productIds: banner.productIds || [],
|
||||
skuIds: banner.productIds || [],
|
||||
redirectUrl: banner.redirectUrl,
|
||||
serialNum: banner.serialNum,
|
||||
isActive: banner.isActive,
|
||||
|
|
@ -46,7 +34,7 @@ export async function getBannerById(id: number): Promise<Banner | null> {
|
|||
name: banner.name,
|
||||
imageUrl: banner.imageUrl,
|
||||
description: banner.description,
|
||||
productIds: banner.productIds || [],
|
||||
skuIds: banner.productIds || [],
|
||||
redirectUrl: banner.redirectUrl,
|
||||
serialNum: banner.serialNum,
|
||||
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> {
|
||||
const [banner] = await db.insert(homeBanners).values({
|
||||
name: input.name,
|
||||
imageUrl: input.imageUrl,
|
||||
description: input.description,
|
||||
productIds: input.productIds || [],
|
||||
productIds: input.skuIds || [],
|
||||
redirectUrl: input.redirectUrl,
|
||||
serialNum: input.serialNum,
|
||||
isActive: input.isActive,
|
||||
|
|
@ -73,7 +59,7 @@ export async function createBanner(input: CreateBannerInput): Promise<Banner> {
|
|||
name: banner.name,
|
||||
imageUrl: banner.imageUrl,
|
||||
description: banner.description,
|
||||
productIds: banner.productIds || [],
|
||||
skuIds: banner.productIds || [],
|
||||
redirectUrl: banner.redirectUrl,
|
||||
serialNum: banner.serialNum,
|
||||
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> {
|
||||
const { skuIds, ...rest } = input as UpdateBannerInput & { skuIds?: number[] | null };
|
||||
const [banner] = await db.update(homeBanners)
|
||||
.set({
|
||||
...input,
|
||||
...rest,
|
||||
...(skuIds !== undefined ? { productIds: skuIds } : {}),
|
||||
lastUpdated: new Date(),
|
||||
})
|
||||
.where(eq(homeBanners.id, id))
|
||||
|
|
@ -98,7 +84,7 @@ export async function updateBanner(id: number, input: UpdateBannerInput): Promis
|
|||
name: banner.name,
|
||||
imageUrl: banner.imageUrl,
|
||||
description: banner.description,
|
||||
productIds: banner.productIds || [],
|
||||
skuIds: banner.productIds || [],
|
||||
redirectUrl: banner.redirectUrl,
|
||||
serialNum: banner.serialNum,
|
||||
isActive: banner.isActive,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,8 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { complaints, users } from '../db/schema';
|
||||
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> {
|
||||
const complaint = await db.query.complaints.findFirst({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { keyValStore } from '../db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
export interface Constant {
|
||||
key: string;
|
||||
value: any;
|
||||
}
|
||||
import type { Constant } from '@packages/shared';
|
||||
|
||||
export async function getAllConstants(): Promise<Constant[]> {
|
||||
const constants = await db.select().from(keyValStore);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,7 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema';
|
||||
import { eq, and, like, or, inArray, lt, desc } from 'drizzle-orm';
|
||||
|
||||
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;
|
||||
}
|
||||
import type { Coupon, CouponValidationResult, UserMiniInfo } from '@packages/shared';
|
||||
|
||||
export async function getAllCoupons(
|
||||
cursor?: number,
|
||||
|
|
@ -208,13 +191,6 @@ export async function invalidateCoupon(id: number): Promise<Coupon> {
|
|||
return result[0] as Coupon;
|
||||
}
|
||||
|
||||
export interface CouponValidationResult {
|
||||
valid: boolean;
|
||||
message?: string;
|
||||
discountAmount?: number;
|
||||
coupon?: Partial<Coupon>;
|
||||
}
|
||||
|
||||
export async function validateCoupon(
|
||||
code: string,
|
||||
userId: number,
|
||||
|
|
@ -455,12 +431,6 @@ export async function createCouponForUser(
|
|||
});
|
||||
}
|
||||
|
||||
export interface UserMiniInfo {
|
||||
id: number;
|
||||
name: string;
|
||||
mobile: string | null;
|
||||
}
|
||||
|
||||
export async function getUsersForCoupon(
|
||||
search?: string,
|
||||
limit: number = 20,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,7 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema';
|
||||
import { eq, or, ilike, and, lt, desc } from 'drizzle-orm';
|
||||
|
||||
export interface StaffUser {
|
||||
id: number;
|
||||
name: string;
|
||||
password: string;
|
||||
staffRoleId: number | null;
|
||||
createdAt: Date;
|
||||
}
|
||||
import type { StaffUser } from '@packages/shared';
|
||||
|
||||
export async function getStaffUserByName(name: string): Promise<StaffUser | null> {
|
||||
const staff = await db.query.staffUsers.findFirst({
|
||||
|
|
|
|||
|
|
@ -1,16 +1,7 @@
|
|||
import { db } from '../db/db_index';
|
||||
import { storeInfo, productInfo } from '../db/schema';
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
|
||||
export interface Store {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string | null;
|
||||
imageUrl: string | null;
|
||||
owner: number;
|
||||
createdAt: Date;
|
||||
// updatedAt: Date;
|
||||
}
|
||||
import type { Store, CreateStoreInput, UpdateStoreInput } from '@packages/shared';
|
||||
|
||||
export async function getAllStores(): Promise<any[]> {
|
||||
const stores = await db.query.storeInfo.findMany({
|
||||
|
|
@ -33,13 +24,6 @@ export async function getStoreById(id: number): Promise<any | null> {
|
|||
return store || null;
|
||||
}
|
||||
|
||||
export interface CreateStoreInput {
|
||||
name: string;
|
||||
description?: string;
|
||||
imageUrl?: string;
|
||||
owner: number;
|
||||
}
|
||||
|
||||
export async function createStore(
|
||||
input: CreateStoreInput,
|
||||
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(
|
||||
id: number,
|
||||
input: UpdateStoreInput,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { eq, and } from 'drizzle-orm'
|
||||
import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
|
||||
|
||||
// ============================================================================
|
||||
// Unit Seed Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface UnitSeedData {
|
||||
shortNotation: string
|
||||
fullName: string
|
||||
}
|
||||
|
||||
export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
|
||||
for (const unit of unitsToSeed) {
|
||||
const { units: unitsTable } = await import('../db/schema')
|
||||
|
|
@ -26,9 +22,6 @@ export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
|
|||
// 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> {
|
||||
for (const roleName of rolesToSeed) {
|
||||
const { staffRoles } = await import('../db/schema')
|
||||
|
|
@ -45,9 +38,6 @@ export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void
|
|||
// 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> {
|
||||
for (const permissionName of permissionsToSeed) {
|
||||
const { staffPermissions } = await import('../db/schema')
|
||||
|
|
@ -64,11 +54,6 @@ export async function seedStaffPermissions(permissionsToSeed: StaffPermissionNam
|
|||
// Role-Permission Assignment Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface RolePermissionAssignment {
|
||||
roleName: StaffRoleName
|
||||
permissionName: StaffPermissionName
|
||||
}
|
||||
|
||||
export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> {
|
||||
await db.transaction(async (tx) => {
|
||||
const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema')
|
||||
|
|
@ -106,11 +91,6 @@ export async function seedRolePermissions(assignments: RolePermissionAssignment[
|
|||
// Key-Value Store Seed Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface KeyValSeedData {
|
||||
key: string
|
||||
value: any
|
||||
}
|
||||
|
||||
export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> {
|
||||
for (const constant of constantsToSeed) {
|
||||
const { keyValStore } = await import('../db/schema')
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
userIncidents,
|
||||
} from '../db/schema'
|
||||
import { eq, and, gt, sql, inArray, isNotNull, asc, sum } from 'drizzle-orm'
|
||||
import type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared'
|
||||
|
||||
// ============================================================================
|
||||
// BANNER STORE HELPERS
|
||||
|
|
@ -77,11 +78,6 @@ export interface SpecialDealData {
|
|||
validTill: Date
|
||||
}
|
||||
|
||||
export interface ProductTagData {
|
||||
productId: number
|
||||
tagName: string
|
||||
}
|
||||
|
||||
export async function getAllProductsForCache(): Promise<ProductBasicData[]> {
|
||||
return db
|
||||
.select({
|
||||
|
|
@ -172,11 +168,6 @@ export interface TagBasicData {
|
|||
relatedStores: unknown
|
||||
}
|
||||
|
||||
export interface TagProductMapping {
|
||||
tagId: number
|
||||
productId: number
|
||||
}
|
||||
|
||||
export async function getAllTagsForCache(): Promise<TagBasicData[]> {
|
||||
return db
|
||||
.select({
|
||||
|
|
@ -293,11 +284,6 @@ export async function getAllSlotsWithProductsForCache(): Promise<SlotWithProduct
|
|||
// USER NEGATIVITY STORE HELPERS
|
||||
// ============================================================================
|
||||
|
||||
export interface UserNegativityData {
|
||||
userId: number
|
||||
totalNegativityScore: number
|
||||
}
|
||||
|
||||
export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> {
|
||||
return db
|
||||
.select({
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
"target": "es2020",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
"@/*": ["./*"],
|
||||
"@packages/shared": ["../shared"],
|
||||
"@packages/shared/*": ["../shared/*"]
|
||||
},
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "./dist",
|
||||
|
|
|
|||
|
|
@ -1,20 +1,7 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { homeBanners, staffUsers } from '../db/schema'
|
||||
import { eq, desc } from 'drizzle-orm'
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
import type { Banner, CreateBannerInput, UpdateBannerInput } from '@packages/shared'
|
||||
|
||||
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> {
|
||||
const [banner] = await db.insert(homeBanners).values({
|
||||
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> {
|
||||
const [banner] = await db.update(homeBanners)
|
||||
.set({
|
||||
|
|
|
|||
|
|
@ -1,22 +1,8 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { complaints, users } from '../db/schema'
|
||||
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> {
|
||||
const complaint = await db.query.complaints.findFirst({
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { keyValStore } from '../db/schema'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import type { Constant } from '@packages/shared'
|
||||
import { CONST_KEYS, castConstValue } from '../lib/const-keys'
|
||||
|
||||
export interface Constant {
|
||||
key: string
|
||||
value: any
|
||||
}
|
||||
|
||||
export async function getAllConstants(): Promise<Constant[]> {
|
||||
const constants = await db.select().from(keyValStore)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,7 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { coupons, reservedCoupons, users, orders, orderStatus, couponApplicableUsers, couponApplicableProducts } from '../db/schema'
|
||||
import { eq, and, like, or, inArray, lt, desc, asc } from 'drizzle-orm'
|
||||
|
||||
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
|
||||
}
|
||||
import type { Coupon, CouponValidationResult, UserMiniInfo } from '@packages/shared'
|
||||
|
||||
export async function getAllCoupons(
|
||||
cursor?: number,
|
||||
|
|
@ -212,13 +195,6 @@ export async function invalidateCoupon(id: number): Promise<Coupon> {
|
|||
return result[0] as Coupon
|
||||
}
|
||||
|
||||
export interface CouponValidationResult {
|
||||
valid: boolean
|
||||
message?: string
|
||||
discountAmount?: number
|
||||
coupon?: Partial<Coupon>
|
||||
}
|
||||
|
||||
export async function validateCoupon(
|
||||
code: string,
|
||||
userId: number,
|
||||
|
|
@ -459,12 +435,6 @@ export async function createCouponForUser(
|
|||
})
|
||||
}
|
||||
|
||||
export interface UserMiniInfo {
|
||||
id: number
|
||||
name: string
|
||||
mobile: string | null
|
||||
}
|
||||
|
||||
export async function getUsersForCoupon(
|
||||
search?: string,
|
||||
limit: number = 20,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,7 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { staffUsers, staffRoles, users, userDetails, orders } from '../db/schema'
|
||||
import { eq, or, like, and, lt, desc } from 'drizzle-orm'
|
||||
|
||||
export interface StaffUser {
|
||||
id: number
|
||||
name: string
|
||||
password: string
|
||||
staffRoleId: number | null
|
||||
createdAt: Date
|
||||
}
|
||||
import type { StaffUser } from '@packages/shared'
|
||||
|
||||
export async function getStaffUserByName(name: string): Promise<StaffUser | null> {
|
||||
const staff = await db.query.staffUsers.findFirst({
|
||||
|
|
|
|||
|
|
@ -2,16 +2,7 @@ import { db } from '../db/db_index'
|
|||
import { storeInfo, productInfo, productSkus } from '../db/schema'
|
||||
import { eq, inArray } from 'drizzle-orm'
|
||||
import { runBatched } from '../lib/run-batched'
|
||||
|
||||
export interface Store {
|
||||
id: number
|
||||
name: string
|
||||
description: string | null
|
||||
imageUrl: string | null
|
||||
owner: number
|
||||
createdAt: Date
|
||||
// updatedAt: Date
|
||||
}
|
||||
import type { Store, CreateStoreInput, UpdateStoreInput } from '@packages/shared'
|
||||
|
||||
export async function getAllStores(): Promise<any[]> {
|
||||
const stores = await db.query.storeInfo.findMany({
|
||||
|
|
@ -34,13 +25,6 @@ export async function getStoreById(id: number): Promise<any | null> {
|
|||
return store || null
|
||||
}
|
||||
|
||||
export interface CreateStoreInput {
|
||||
name: string
|
||||
description?: string
|
||||
imageUrl?: string
|
||||
owner: number
|
||||
}
|
||||
|
||||
export async function createStore(
|
||||
input: CreateStoreInput,
|
||||
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(
|
||||
id: number,
|
||||
input: UpdateStoreInput,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import { db } from '../db/db_index'
|
||||
import { eq, and } from 'drizzle-orm'
|
||||
import type { UnitSeedData, StaffRoleName, StaffPermissionName, RolePermissionAssignment, KeyValSeedData } from '@packages/shared'
|
||||
|
||||
// ============================================================================
|
||||
// Unit Seed Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface UnitSeedData {
|
||||
shortNotation: string
|
||||
fullName: string
|
||||
}
|
||||
|
||||
export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
|
||||
for (const unit of unitsToSeed) {
|
||||
const { units: unitsTable } = await import('../db/schema')
|
||||
|
|
@ -26,9 +22,6 @@ export async function seedUnits(unitsToSeed: UnitSeedData[]): Promise<void> {
|
|||
// 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> {
|
||||
for (const roleName of rolesToSeed) {
|
||||
const { staffRoles } = await import('../db/schema')
|
||||
|
|
@ -45,9 +38,6 @@ export async function seedStaffRoles(rolesToSeed: StaffRoleName[]): Promise<void
|
|||
// 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> {
|
||||
for (const permissionName of permissionsToSeed) {
|
||||
const { staffPermissions } = await import('../db/schema')
|
||||
|
|
@ -64,11 +54,6 @@ export async function seedStaffPermissions(permissionsToSeed: StaffPermissionNam
|
|||
// Role-Permission Assignment Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface RolePermissionAssignment {
|
||||
roleName: StaffRoleName
|
||||
permissionName: StaffPermissionName
|
||||
}
|
||||
|
||||
export async function seedRolePermissions(assignments: RolePermissionAssignment[]): Promise<void> {
|
||||
await db.transaction(async (tx) => {
|
||||
const { staffRoles, staffPermissions, staffRolePermissions } = await import('../db/schema')
|
||||
|
|
@ -106,11 +91,6 @@ export async function seedRolePermissions(assignments: RolePermissionAssignment[
|
|||
// Key-Value Store Seed Helper
|
||||
// ============================================================================
|
||||
|
||||
export interface KeyValSeedData {
|
||||
key: string
|
||||
value: any
|
||||
}
|
||||
|
||||
export async function seedKeyValStore(constantsToSeed: KeyValSeedData[]): Promise<void> {
|
||||
for (const constant of constantsToSeed) {
|
||||
const { keyValStore } = await import('../db/schema')
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from '../db/schema'
|
||||
import { eq, and, gt, sql, isNotNull, asc } from 'drizzle-orm'
|
||||
import { composeSkuName, composeUnitNotation } from '../lib/sku-features'
|
||||
import type { ProductTagData, TagProductMapping, UserNegativityData } from '@packages/shared'
|
||||
|
||||
// ============================================================================
|
||||
// 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[]> {
|
||||
const skus = await db.query.productSkus.findMany({
|
||||
with: {
|
||||
|
|
@ -276,11 +272,6 @@ export interface TagBasicData {
|
|||
sortOrder: number[] | null
|
||||
}
|
||||
|
||||
export interface TagProductMapping {
|
||||
tagId: number
|
||||
productId: number
|
||||
}
|
||||
|
||||
export async function getAllTagsForCache(): Promise<TagBasicData[]> {
|
||||
return db
|
||||
.select({
|
||||
|
|
@ -411,11 +402,6 @@ export async function getAllSlotsWithProductsForCache(): Promise<SlotWithProduct
|
|||
// USER NEGATIVITY STORE HELPERS
|
||||
// ============================================================================
|
||||
|
||||
export interface UserNegativityData {
|
||||
userId: number
|
||||
totalNegativityScore: number
|
||||
}
|
||||
|
||||
export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> {
|
||||
const results = await db
|
||||
.select({
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
"target": "es2020",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
"@/*": ["./*"],
|
||||
"@packages/shared": ["../shared"],
|
||||
"@packages/shared/*": ["../shared/*"]
|
||||
},
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "./dist",
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ export interface StaffUser {
|
|||
id: number;
|
||||
name: string;
|
||||
password: string;
|
||||
staffRoleId: number;
|
||||
staffRoleId: number | null;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
|
|
|
|||
85
packages/shared/types/app-common.types.ts
Normal file
85
packages/shared/types/app-common.types.ts
Normal 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
|
||||
}
|
||||
41
packages/shared/types/cache.types.ts
Normal file
41
packages/shared/types/cache.types.ts
Normal 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
|
||||
}
|
||||
|
|
@ -1,6 +1,15 @@
|
|||
// 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 './user';
|
||||
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)
|
||||
|
|
|
|||
43
packages/shared/types/inputs.types.ts
Normal file
43
packages/shared/types/inputs.types.ts
Normal 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
|
||||
}
|
||||
29
packages/shared/types/seed.types.ts
Normal file
29
packages/shared/types/seed.types.ts
Normal 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
|
||||
}
|
||||
30
packages/shared/types/upload.types.ts
Normal file
30
packages/shared/types/upload.types.ts
Normal 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[]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue