fix: harden widget request caching

This commit is contained in:
ajnart committed 2026-08-26 14:57:53 +02:00
1 parent c81088d876
commit 47724f44eb
26 files changed
+838 -209

No files matched your search

+15 -1
View File
@@ -5,9 +5,10 @@ import type { Session } from "@homarr/auth";
import { createId } from "@homarr/common";
import type { Database, InferSelectModel } from "@homarr/db";
import { asc, eq, inArray, like } from "@homarr/db";
import { apps } from "@homarr/db/schema";
import { apps, integrations } from "@homarr/db/schema";
import { selectAppSchema } from "@homarr/db/validationSchemas";
import { getIconForName } from "@homarr/icons";
import { invalidateIntegrationResponseCacheAsync } from "@homarr/redis";
import { appCreateManySchema, appEditSchema, appManageSchema } from "@homarr/validation/app";
import { byIdSchema, paginatedSchema } from "@homarr/validation/common";
@@ -256,6 +257,14 @@ export const appRouter = createTRPCRouter({
pingUrl: input.pingUrl === "" ? null : input.pingUrl,
})
.where(eq(apps.id, input.id));
if (app.href !== input.href) {
const linkedIntegrations = await ctx.db.query.integrations.findMany({
columns: { id: true },
where: eq(integrations.appId, input.id),
});
await Promise.all(linkedIntegrations.map(({ id }) => invalidateIntegrationResponseCacheAsync(id)));
}
}),
delete: permissionRequiredProcedure
.requiresPermission("app-full-all")
@@ -271,7 +280,12 @@ export const appRouter = createTRPCRouter({
})
.input(byIdSchema)
.mutation(async ({ ctx, input }) => {
const linkedIntegrations = await ctx.db.query.integrations.findMany({
columns: { id: true },
where: eq(integrations.appId, input.id),
});
await ctx.db.delete(apps).where(eq(apps.id, input.id));
await Promise.all(linkedIntegrations.map(({ id }) => invalidateIntegrationResponseCacheAsync(id)));
}),
});
+2 -2
View File
@@ -161,8 +161,8 @@ const validateWidgetConfigurationsAsync = async (
);
if (invalidIntegrationIds.length > 0) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Invalid integration IDs: ${invalidIntegrationIds.join(", ")}`,
code: "NOT_FOUND",
message: "Integration not found",
});
}
@@ -38,7 +38,7 @@ export const indexerManagerRouter = createTRPCRouter({
testAllIndexers: protectedProcedure
.concat(createManyWidgetIntegrationMiddleware("interact", "indexerManager"))
.mutation(async ({ ctx }) => {
await Promise.all(
const results = await Promise.allSettled(
ctx.integrations.map(async (integration) => {
const client = await createIntegrationAsync(integration);
await client.testAllAsync().catch((err) => {
@@ -51,5 +51,8 @@ export const indexerManagerRouter = createTRPCRouter({
}),
);
await indexerManagerRequestHandler.invalidateCacheAsync(ctx.integrations.map(({ id }) => id));
const firstFailure = results.find((result) => result.status === "rejected");
if (firstFailure?.status === "rejected") throw firstFailure.reason;
}),
});