feat(index): Add http/module api to interact with the index engine (#13869)

* feat(index): Add support to trigger sync manually

* feat(index): Add API route to interact with

* feat(index): Add API route to interact with

* feat(index): Add API route to interact with

* test(): Add http integration tests

* Create weak-elephants-reply.md
This commit is contained in:
Adrien de Peretti
2025-10-28 20:31:39 +01:00
committed by GitHub
parent 540ae996ff
commit 85b1f3d43a
19 changed files with 1061 additions and 7 deletions

View File

@@ -0,0 +1,19 @@
import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework"
import { HttpTypes } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
/**
* Get the index information for all entities that are indexed and their sync state
* @param req
* @param res
*/
export const GET = async (
req: AuthenticatedMedusaRequest<void>,
res: MedusaResponse<HttpTypes.AdminIndexDetailsResponse>
) => {
const indexModuleService = req.scope.resolve(Modules.INDEX)
const indexInfo = await indexModuleService.getInfo()
res.json({
metadata: indexInfo,
})
}

View File

@@ -0,0 +1,62 @@
import { validateAndTransformBody } from "@medusajs/framework"
import {
AuthenticatedMedusaRequest,
MedusaNextFunction,
MedusaResponse,
MiddlewareRoute,
} from "@medusajs/framework/http"
import { Logger } from "@medusajs/framework/types"
import {
ContainerRegistrationKeys,
FeatureFlag,
Modules,
} from "@medusajs/framework/utils"
import IndexEngineFeatureFlag from "../../../feature-flags/index-engine"
import { authenticate } from "../../../utils/middlewares/authenticate-middleware"
import { AdminIndexSyncPayload } from "./validator"
const isIndexEnabledMiddleware = (
req: AuthenticatedMedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
const indexService = req.scope.resolve(Modules.INDEX, {
allowUnregistered: true,
})
const logger =
req.scope.resolve(ContainerRegistrationKeys.LOGGER, {
allowUnregistered: true,
}) ?? (console as unknown as Logger)
if (
!indexService ||
!FeatureFlag.isFeatureEnabled(IndexEngineFeatureFlag.key)
) {
logger.warn(
"Trying to access '/admin/index/*' route but the index module is not configured"
)
return res.status(404)
}
return next()
}
export const adminIndexRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["GET"],
matcher: "/admin/index/details",
middlewares: [
authenticate("user", ["session", "bearer", "api-key"]),
isIndexEnabledMiddleware,
],
},
{
method: ["POST"],
matcher: "/admin/index/sync",
middlewares: [
authenticate("user", ["session", "bearer", "api-key"]),
isIndexEnabledMiddleware,
validateAndTransformBody(AdminIndexSyncPayload),
],
},
]

View File

@@ -0,0 +1,15 @@
import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/framework"
import { HttpTypes } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
export const POST = async (
req: AuthenticatedMedusaRequest<HttpTypes.AdminIndexSyncPayload>,
res: MedusaResponse
) => {
const indexService = req.scope.resolve(Modules.INDEX)
const strategy = req.validatedBody.strategy
await indexService.sync({ strategy })
res.send(200)
}

View File

@@ -0,0 +1,5 @@
import z from "zod"
export const AdminIndexSyncPayload = z.object({
strategy: z.enum(["full", "reset"]).optional(),
})