task-managment / src / server / trpc.ts
trpc.ts
Raw
import { initTRPC, TRPCError } from "@trpc/server";
import { ZodError } from "zod";
import { Context, createContext } from "./context";
import { auth, currentUser } from "@clerk/nextjs/server";
import { db } from "@/database/db";
import {
  areas,
  eventsLog,
  eventType,
  floor,
  materials,
  project,
  projectMaterials,
} from "@/database/schema";
import { eq, SQL, sql, sum } from "drizzle-orm";
import { removeLocalOffsetFromDate } from "@/lib/utils";
import { extractPayload, getCookie, VARIABLES_CONFIG } from "@/lib/db/util";

const t = initTRPC.context<typeof createContext>().create({
  errorFormatter(opts) {
    const { shape, error } = opts;
    return {
      ...shape,
      data: {
        ...shape.data,
        zodError:
          error.code === "BAD_REQUEST" && error.cause instanceof ZodError
            ? error.cause.flatten()
            : null,
      },
    };
  },
});

//reusable middleware that verifies user is admin before signin

export const isAdminMiddleware = t.middleware(async (opts) => {
  const { sessionClaims, userId } = auth();
  const { ctx, next } = opts;
 const verificationToken = getCookie(
    VARIABLES_CONFIG.VERIFICATION_TOKEN!
  )?.value;
  const payload = verificationToken ? extractPayload(verificationToken):null
  const authUser = {
    userId: userId as string,
    rol: sessionClaims?.metadata.role || payload?.role
  };

  if (authUser?.rol !== "admin") {
    throw new Error("Solo un administrador puede hacer esta acción");
  }

  return next({
    ctx: {
      user: authUser,
    },
  });
});

//reusable middleware, verifies user is signin
export const isSigninMiddleware = t.middleware(async ({ ctx, next }) => {
  const { sessionClaims, userId } = auth();

  //fix error, context not working on mutations, only on queries, ensure user data is path in both.
  const authUser = {
    userId: userId as string,
    rol: sessionClaims?.metadata.role ,
  };

  if (!authUser?.userId) {
    throw new TRPCError({
      code: "UNAUTHORIZED",
      message: "User must be signed in",
    });
  }

  return next({
    ctx: {
      user: authUser,
    },
  });
});

export const createLogRecord = async (
  tx: typeof db,
  values: any
) => {
  const { eventType, userId, oldValues, newValues, modifiedItem, tableName } =
    values;
  try {
    const values: any = {
      eventType,
      userId,
      modifiedItem,
      tableName,
    };

    if (oldValues) {
      values.oldValues = sql`${oldValues}::jsonb`;
    }

    if (newValues) {
      values.newValues = sql`${newValues}::jsonb`;
    }

    await tx.insert(eventsLog).values(values);
  } catch (err) {
    console.log("err", err);
    throw new Error("Error al crear log record");
  }
};



export const router = t.router;
export const publicProcedure = t.procedure;