feat: EMEX catalog integration — schema, data migration, backend & frontend
Some checks failed
CI / Lint, Typecheck, Test & Build (push) Has been cancelled
Some checks failed
CI / Lint, Typecheck, Test & Build (push) Has been cancelled
Redesign emex_* tables from vehicle-centric to catalog-centric structure with junction tables (emex_vehicle_group_links, emex_vehicle_part_links). Migrate 92M+ rows from emex DB via postgres_fdw. Add EmexCatalogService for browse and VIN pre-scraped matching, with Redis caching. Frontend catalog page now has PL24/Emex tabs with full drill-down routes (brand → vehicle → group → parts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,9 +41,12 @@ import { Route as DashboardAdminCopyLogsRouteImport } from "./routes/dashboard/a
|
||||
import { Route as DashboardAdminAnalyticsRouteImport } from "./routes/dashboard/admin/analytics"
|
||||
import { Route as DashboardVehiclesIdIndexRouteImport } from "./routes/dashboard/vehicles_/$id/index"
|
||||
import { Route as DashboardCatalogBrandNameIndexRouteImport } from "./routes/dashboard/catalog_/$brandName/index"
|
||||
import { Route as DashboardCatalogEmexCatalogCodeIndexRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode/index"
|
||||
import { Route as DashboardCatalogBrandNameModelIdIndexRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/index"
|
||||
import { Route as DashboardVehiclesIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/vehicles_/$id/categories_/$categoryId"
|
||||
import { Route as DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId/index"
|
||||
import { Route as DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||
import { Route as DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport } from "./routes/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId"
|
||||
|
||||
const TermsRoute = TermsRouteImport.update({
|
||||
id: "/terms",
|
||||
@@ -208,6 +211,12 @@ const DashboardCatalogBrandNameIndexRoute =
|
||||
path: "/catalog/$brandName/",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
const DashboardCatalogEmexCatalogCodeIndexRoute =
|
||||
DashboardCatalogEmexCatalogCodeIndexRouteImport.update({
|
||||
id: "/catalog_/emex/$catalogCode/",
|
||||
path: "/catalog/emex/$catalogCode/",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
const DashboardCatalogBrandNameModelIdIndexRoute =
|
||||
DashboardCatalogBrandNameModelIdIndexRouteImport.update({
|
||||
id: "/catalog_/$brandName_/$modelId/",
|
||||
@@ -220,12 +229,24 @@ const DashboardVehiclesIdCategoriesCategoryIdRoute =
|
||||
path: "/vehicles/$id/categories/$categoryId",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
const DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute =
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport.update({
|
||||
id: "/catalog_/emex/$catalogCode_/$vehicleId/",
|
||||
path: "/catalog/emex/$catalogCode/$vehicleId/",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
const DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute =
|
||||
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport.update({
|
||||
id: "/catalog_/$brandName_/$modelId/categories_/$categoryId",
|
||||
path: "/catalog/$brandName/$modelId/categories/$categoryId",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
const DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute =
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport.update({
|
||||
id: "/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId",
|
||||
path: "/catalog/emex/$catalogCode/$vehicleId/groups/$groupId",
|
||||
getParentRoute: () => DashboardRoute,
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
"/": typeof IndexRoute
|
||||
@@ -261,7 +282,10 @@ export interface FileRoutesByFullPath {
|
||||
"/dashboard/vehicles/$id/": typeof DashboardVehiclesIdIndexRoute
|
||||
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog/$brandName/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||
"/dashboard/catalog/emex/$catalogCode/": typeof DashboardCatalogEmexCatalogCodeIndexRoute
|
||||
"/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog/emex/$catalogCode/$vehicleId/": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute
|
||||
"/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
"/": typeof IndexRoute
|
||||
@@ -296,7 +320,10 @@ export interface FileRoutesByTo {
|
||||
"/dashboard/vehicles/$id": typeof DashboardVehiclesIdIndexRoute
|
||||
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog/$brandName/$modelId": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||
"/dashboard/catalog/emex/$catalogCode": typeof DashboardCatalogEmexCatalogCodeIndexRoute
|
||||
"/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog/emex/$catalogCode/$vehicleId": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute
|
||||
"/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
@@ -334,7 +361,10 @@ export interface FileRoutesById {
|
||||
"/dashboard/vehicles_/$id/": typeof DashboardVehiclesIdIndexRoute
|
||||
"/dashboard/vehicles_/$id/categories_/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog_/$brandName_/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||
"/dashboard/catalog_/emex/$catalogCode/": typeof DashboardCatalogEmexCatalogCodeIndexRoute
|
||||
"/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||
"/dashboard/catalog_/emex/$catalogCode_/$vehicleId/": typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute
|
||||
"/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId": typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
@@ -372,7 +402,10 @@ export interface FileRouteTypes {
|
||||
| "/dashboard/vehicles/$id/"
|
||||
| "/dashboard/vehicles/$id/categories/$categoryId"
|
||||
| "/dashboard/catalog/$brandName/$modelId/"
|
||||
| "/dashboard/catalog/emex/$catalogCode/"
|
||||
| "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||
| "/dashboard/catalog/emex/$catalogCode/$vehicleId/"
|
||||
| "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId"
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to:
|
||||
| "/"
|
||||
@@ -407,7 +440,10 @@ export interface FileRouteTypes {
|
||||
| "/dashboard/vehicles/$id"
|
||||
| "/dashboard/vehicles/$id/categories/$categoryId"
|
||||
| "/dashboard/catalog/$brandName/$modelId"
|
||||
| "/dashboard/catalog/emex/$catalogCode"
|
||||
| "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||
| "/dashboard/catalog/emex/$catalogCode/$vehicleId"
|
||||
| "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId"
|
||||
id:
|
||||
| "__root__"
|
||||
| "/"
|
||||
@@ -444,7 +480,10 @@ export interface FileRouteTypes {
|
||||
| "/dashboard/vehicles_/$id/"
|
||||
| "/dashboard/vehicles_/$id/categories_/$categoryId"
|
||||
| "/dashboard/catalog_/$brandName_/$modelId/"
|
||||
| "/dashboard/catalog_/emex/$catalogCode/"
|
||||
| "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||
| "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/"
|
||||
| "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId"
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
@@ -688,6 +727,13 @@ declare module "@tanstack/react-router" {
|
||||
preLoaderRoute: typeof DashboardCatalogBrandNameIndexRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
"/dashboard/catalog_/emex/$catalogCode/": {
|
||||
id: "/dashboard/catalog_/emex/$catalogCode/"
|
||||
path: "/catalog/emex/$catalogCode"
|
||||
fullPath: "/dashboard/catalog/emex/$catalogCode/"
|
||||
preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeIndexRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
"/dashboard/catalog_/$brandName_/$modelId/": {
|
||||
id: "/dashboard/catalog_/$brandName_/$modelId/"
|
||||
path: "/catalog/$brandName/$modelId"
|
||||
@@ -702,6 +748,13 @@ declare module "@tanstack/react-router" {
|
||||
preLoaderRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
"/dashboard/catalog_/emex/$catalogCode_/$vehicleId/": {
|
||||
id: "/dashboard/catalog_/emex/$catalogCode_/$vehicleId/"
|
||||
path: "/catalog/emex/$catalogCode/$vehicleId"
|
||||
fullPath: "/dashboard/catalog/emex/$catalogCode/$vehicleId/"
|
||||
preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
"/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": {
|
||||
id: "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||
path: "/catalog/$brandName/$modelId/categories/$categoryId"
|
||||
@@ -709,6 +762,13 @@ declare module "@tanstack/react-router" {
|
||||
preLoaderRoute: typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
"/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId": {
|
||||
id: "/dashboard/catalog_/emex/$catalogCode_/$vehicleId_/groups/$groupId"
|
||||
path: "/catalog/emex/$catalogCode/$vehicleId/groups/$groupId"
|
||||
fullPath: "/dashboard/catalog/emex/$catalogCode/$vehicleId/groups/$groupId"
|
||||
preLoaderRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRouteImport
|
||||
parentRoute: typeof DashboardRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +807,10 @@ interface DashboardRouteChildren {
|
||||
DashboardVehiclesIdIndexRoute: typeof DashboardVehiclesIdIndexRoute
|
||||
DashboardVehiclesIdCategoriesCategoryIdRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||
DashboardCatalogBrandNameModelIdIndexRoute: typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||
DashboardCatalogEmexCatalogCodeIndexRoute: typeof DashboardCatalogEmexCatalogCodeIndexRoute
|
||||
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute: typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute: typeof DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute
|
||||
}
|
||||
|
||||
const DashboardRouteChildren: DashboardRouteChildren = {
|
||||
@@ -771,8 +834,14 @@ const DashboardRouteChildren: DashboardRouteChildren = {
|
||||
DashboardVehiclesIdCategoriesCategoryIdRoute,
|
||||
DashboardCatalogBrandNameModelIdIndexRoute:
|
||||
DashboardCatalogBrandNameModelIdIndexRoute,
|
||||
DashboardCatalogEmexCatalogCodeIndexRoute:
|
||||
DashboardCatalogEmexCatalogCodeIndexRoute,
|
||||
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute:
|
||||
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute,
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute:
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdIndexRoute,
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute:
|
||||
DashboardCatalogEmexCatalogCodeVehicleIdGroupsGroupIdRoute,
|
||||
}
|
||||
|
||||
const DashboardRouteWithChildren = DashboardRoute._addFileChildren(
|
||||
|
||||
Reference in New Issue
Block a user