cache middleware

This commit is contained in:
2026-01-27 13:45:10 -03:00
parent 9ad9457260
commit 028297443a
2 changed files with 61 additions and 13 deletions

View File

@@ -22,6 +22,7 @@ export type WorkspaceContextProps = {
subscription: Subscription | null
address: Address | null
test_mode: boolean
blocked: boolean
}
type HttpResponse = {
@@ -33,18 +34,23 @@ type HttpResponse = {
preferred_org_id?: string
}
export const workspaceContext = createContext<
WorkspaceContextProps & { blocked: boolean }
>()
export const workspaceContext = createContext<WorkspaceContextProps>()
export const workspaceMiddleware = async (
{ params, request, context }: LoaderFunctionArgs,
next: () => Promise<Response>
): Promise<Response> => {
const url = new URL(request.url)
const orgId = params.orgid
const user = context.get(userContext)!
console.debug('Hit on workspace middelware')
const cacheKey = buildWorkspaceCacheKey(request, user.sub, orgId)
const cached = await getFromCache(cacheKey)
if (cached) {
context.set(workspaceContext, cached)
return next()
}
const r = await req({
url: `/users/${user.sub}/orgs?limit=25`,
request,
@@ -61,9 +67,10 @@ export const workspaceMiddleware = async (
return { id, name, cnpj }
})
const activeWorkspace = workspaces.find(({ id }) => id === params.orgid)
const activeWorkspace = workspaces.find(({ id }) => id === orgId)
if (!activeWorkspace) {
const url = new URL(request.url)
const fallback = preferred_org_id
? (workspaces.find(({ id }) => id === preferred_org_id) ?? workspaces[0])
: workspaces[0]
@@ -81,14 +88,55 @@ export const workspaceMiddleware = async (
context
}).then((r) => r.json())) as any
context.set(workspaceContext, {
const workspace = {
activeWorkspace,
workspaces,
subscription: org?.['subscription'] || null,
address: org?.['address'] || null,
test_mode: 'test_mode' in org,
blocked: 'subscription_frozen' in org
})
}
context.set(workspaceContext, workspace)
saveToCache(cacheKey, workspace)
return await next()
}
function buildWorkspaceCacheKey(
request: Request,
userId: string,
orgId?: string
) {
const url = new URL(request.url)
url.pathname = `/__cache/workspace/${userId}/${orgId ?? 'none'}`
url.search = ''
return new Request(url.toString(), {
method: 'GET'
})
}
async function getFromCache(
key: Request
): Promise<WorkspaceContextProps | null> {
const cache: Cache = await caches.open('saladeaula.digital')
const cached = await cache.match(key)
if (!cached) {
return null
}
return cached.json()
}
async function saveToCache(key: Request, data: WorkspaceContextProps) {
const cache: Cache = await caches.open('saladeaula.digital')
const response = new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': `public, max-age=${60 * 10}`
}
})
await cache.put(key, response)
}

View File

@@ -47,7 +47,7 @@ export async function loader({ context, request }: Route.ActionArgs) {
return {
user,
sidebar_state,
...workspace
workspace
}
}
@@ -59,7 +59,7 @@ export function shouldRevalidate({
}
export default function Route({ loaderData }: Route.ComponentProps) {
const { user, sidebar_state, blocked, ...props } = loaderData
const { user, sidebar_state, workspace } = loaderData
useEffect(() => {
if (typeof window !== 'undefined' && window.rybbit) {
@@ -73,7 +73,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
return (
<>
{blocked ? (
{workspace.blocked ? (
<AlertDialog open={true}>
<AlertDialogContent>
<AlertDialogTitle>Serviço com acesso suspenso</AlertDialogTitle>
@@ -85,10 +85,10 @@ export default function Route({ loaderData }: Route.ComponentProps) {
</AlertDialog>
) : null}
<WorkspaceProvider {...props}>
<WorkspaceProvider {...workspace}>
<SidebarProvider
defaultOpen={sidebar_state === 'true'}
className={cn('flex', blocked && 'pointer-events-none')}
className={cn('flex', workspace.blocked && 'pointer-events-none')}
>
<AppSidebar />