{"id":70912,"date":"2024-07-26T19:08:45","date_gmt":"2024-07-26T15:38:45","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/"},"modified":"2024-07-26T19:08:45","modified_gmt":"2024-07-26T15:38:45","slug":"9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/","title":{"rendered":"9 \u0646\u06a9\u062a\u0647 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0628 \u0627\u0645\u0646 \u0628\u0627 tRPC\u060c Next.js\u060c Prisma\u060c Turbo \u0648 NextAuth"},"content":{"rendered":"<p>Summarize this content to 400 words in Persian Lang<br \/>\n            \u0645\u0646 \u0627\u062e\u06cc\u0631\u0627 Minute: \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f\u06cc \u06a9\u0647 \u0627\u0632 T3 Stack \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u067e\u0631\u0648\u0698\u0647 \u0622\u062e\u0631 \u0647\u0641\u062a\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f \u0633\u0627\u062e\u062a\u0647 \u0627\u0645.  \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647\u060c \u0646\u06a9\u0627\u062a \u0627\u0645\u0646\u06cc\u062a\u06cc \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u062d\u06cc\u0646 \u0633\u0627\u062e\u062a Minute \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u0645\u060c \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0645. <\/p>\n<p>  \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc<\/p>\n<p>\u0627\u06cc\u0646 \u0628\u062e\u0634 \u0628\u0647 \u0637\u0648\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0628\u0647 \u0627\u0645\u0646\u06cc\u062a \u0645\u0631\u0628\u0648\u0637 \u0646\u0645\u06cc \u0634\u0648\u062f\u060c \u0627\u0645\u0627 \u0627\u0628\u062a\u062f\u0627 \u062a\u0648\u0636\u06cc\u062d \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a \u062a\u0627 \u062f\u0631\u06a9 \u0628\u062e\u0634 \u0647\u0627\u06cc \u0632\u06cc\u0631 \u0622\u0633\u0627\u0646 \u062a\u0631 \u0634\u0648\u062f.<\/p>\n<p>\u0645\u0646 Turborepo \u0631\u0627 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u062f \u0645\u0646\u0628\u0639 \u062e\u0648\u062f \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 monorepo \u067e\u0630\u06cc\u0631\u0641\u062a\u0645.  \u0628\u0627 \u062a\u0648\u062c\u0647 \u0628\u0647 \u0633\u0627\u062e\u062a \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0645\u0648\u0646\u0648\u0631\u067e\u0648\u060c \u0641\u06a9\u0631 \u0645\u06cc \u06a9\u0646\u0645 \u0633\u062e\u062a \u062a\u0631\u06cc\u0646 \u0642\u0633\u0645\u062a \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0686\u06af\u0648\u0646\u0647 \u06a9\u062f \u0645\u0646\u0628\u0639 \u0631\u0627 \u062c\u062f\u0627 \u06a9\u0646\u06cc\u0645 \u0648 \u0627\u0632 \u0686\u0647 \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n<p>\u062f\u0631 \u0627\u0628\u062a\u062f\u0627 \u0628\u0647 \u0641\u06a9\u0631 \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0628\u0631 \u0627\u0633\u0627\u0633 Clean Architecture \u0628\u0648\u062f\u0645\u060c \u0627\u0645\u0627 \u067e\u0633 \u0627\u0632 \u0634\u0631\u0648\u0639\u060c \u0646\u0638\u0631\u0645 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f.  \u0627\u06cc\u0646 \u0628\u0647 \u0627\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631\u0686\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc \u067e\u0627\u06a9 \u06cc\u06a9 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0634\u0646\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0648 \u0633\u0646\u062c\u06cc\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc Minute \u06a9\u0645\u06cc \u0628\u06cc\u0634 \u0627\u0632 \u062d\u062f \u0645\u0647\u0646\u062f\u0633\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0645\u0646 \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0631\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0633\u0627\u062f\u0647 \u06a9\u0631\u062f\u0645:<\/p>\n<p>\u0645\u0646 \u0628\u0631\u062e\u06cc \u0627\u0632 \u0628\u0633\u062a\u0647 \u0647\u0627 \u0631\u0627 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc \u062f\u0647\u0645\u060c \u0628\u0647 \u062c\u0632 \u0622\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0648\u0627\u0636\u062d \u0647\u0633\u062a\u0646\u062f.<\/p>\n<p>  prisma\/<\/p>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0633\u062a\u0647 \u0634\u0627\u0645\u0644 \u0641\u0627\u06cc\u0644 \u0637\u0631\u062d\u0648\u0627\u0631\u0647 Prisma\u060c \u0641\u0627\u06cc\u0644 \u0647\u0627\u06cc \u0645\u0647\u0627\u062c\u0631\u062a \u0648 Prisma Client \u0645\u06cc \u0628\u0627\u0634\u062f.  \u0642\u0627\u0628\u0644 \u0630\u06a9\u0631 \u0627\u0633\u062a \u06a9\u0647 Prisma Client \u0627\u0632 \u0686\u0646\u062f\u06cc\u0646 \u0628\u0633\u062a\u0647 \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f: trpc\u060c \u0633\u0631\u0648\u06cc\u0633\u060c \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\/\u0648\u0628.  \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u06cc\u06a9 \u0628\u0633\u062a\u0647 prisma\/ \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u062f \u0632\u06cc\u0631\u0627 \u062f\u0631\u06a9 \u0641\u0627\u06cc\u0644 \u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0628\u0627 Prisma \u0631\u0627 \u0622\u0633\u0627\u0646 \u062a\u0631 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>  schema\/<\/p>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u0637\u0631\u062d\u0648\u0627\u0631\u0647\u200c\u0647\u0627\u06cc Zod \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062f\u0644 Prisma \u0648 \u0628\u0631\u062e\u06cc \u062b\u0627\u0628\u062a\u200c\u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0628\u0627 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0627\u0633\u062a\u060c \u0645\u0627\u0646\u0646\u062f MAX_NAME_LENGTH\u060c REGEXP\u060c \u0648 \u063a\u06cc\u0631\u0647. \u0627\u06cc\u0646\u0647\u0627 \u0628\u0631\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f.<\/p>\n<p>  services\/<\/p>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u062a\u0648\u0627\u0628\u0639\u06cc \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u0631\u0648\u06cc\u0647 \u0648\u0627\u062d\u062f \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f\u060c \u0645\u0627\u0646\u0646\u062f \u062f\u0631\u062c \u06cc\u0627 \u0628\u0647 \u0631\u0648\u0632 \u0631\u0633\u0627\u0646\u06cc \u06cc\u06a9 \u0645\u062f\u0644 \u067e\u0633 \u0627\u0632 \u062a\u0623\u06cc\u06cc\u062f \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627. <\/p>\n<p>  trpc\/<\/p>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 tRPC\u060c \u0631\u0648\u062a\u0631\u0647\u0627 \u0648 \u0631\u0648\u06cc\u0647 \u0647\u0627 \u0645\u06cc \u0634\u0648\u062f. \u0647\u0645\u0647 \u0631\u0648\u06cc\u0647\u200c\u0647\u0627 \u0641\u0627\u0642\u062f \u0645\u0646\u0637\u0642 \u0647\u0633\u062a\u0646\u062f \u0648 \u067e\u0631\u062f\u0627\u0632\u0634 \u0631\u0627 \u0628\u0647 \u0633\u0631\u0648\u06cc\u0633 \u0645\u0646\u0627\u0633\u0628 \u0648\u0627\u06af\u0630\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f. \u0628\u0627 \u0627\u0646\u062c\u0627\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u062f\u0631 \u0622\u06cc\u0646\u062f\u0647 \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0646\u0637\u0642 \u0628\u0647 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u062f\u06cc\u06af\u0631\u06cc (\u0645\u062b\u0644\u0627\u064b serverAction) \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u0633\u0648\u0626\u06cc\u0686 \u06a9\u0646\u0645.<\/p>\n<p>  \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627 \u062f\u0631 \u0647\u0631 \u0628\u0633\u062a\u0647<\/p>\n<p>\u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u0645\u0647\u0645\u062a\u0631\u06cc\u0646 \u0628\u062e\u0634 \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0628 \u0627\u0633\u062a.  \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646\u060c \u0645\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u0633\u062a\u0645 \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627\u06cc \u0648\u0631\u0648\u062f\u06cc \u0627\u0631\u0633\u0627\u0644 \u0634\u062f\u0647 \u062a\u0648\u0633\u0637 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648 \u062e\u0631\u0648\u062c\u06cc\u200c\u0647\u0627 \u0631\u0627 \u062f\u0631 \u0628\u0633\u062a\u0647\u200c\u0647\u0627\u06cc trpc \u0648 \u0633\u0631\u0648\u06cc\u0633 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u06a9\u0646\u0645.  \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0645\u0634\u0627\u0628\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u06cc \u0627\u0633\u062a.<\/p>\n<p>\u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u060c \u0647\u0631 \u0646\u0642\u0637\u0647 \u0648\u0631\u0648\u062f\u06cc (\u0628\u0633\u062a\u0647) \u0628\u0627\u06cc\u062f \u0645\u0642\u0627\u062f\u06cc\u0631 \u0648\u0631\u0648\u062f\u06cc\/\u062e\u0631\u0648\u062c\u06cc \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u062f\u060c \u0648 \u0627\u06af\u0631 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0627\u0634\u062f\u060c \u062a\u0627\u0628\u0639 \u062e\u0637\u0627 \u0645\u06cc \u062f\u0647\u062f \u0648 \u0641\u0631\u0622\u06cc\u0646\u062f \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0631\u0627 \u0628\u0647 \u062f\u0644\u0627\u06cc\u0644 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0627\u062c\u0631\u0627 \u0646\u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u062e\u0648\u0634\u0628\u062e\u062a\u0627\u0646\u0647\u060c tRPC \u0627\u0632 \u0642\u0628\u0644 \u0627\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a \u0631\u0627 \u062f\u0627\u0631\u062f \u06a9\u0647 \u0648\u0631\u0648\u062f\u06cc \u0647\u0627 \u0648 \u062e\u0631\u0648\u062c\u06cc \u0647\u0627 \u0631\u0627 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u06a9\u0646\u062f\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Zod \u0646\u06cc\u0632 \u062f\u0627\u0631\u0627\u06cc \u0648\u06cc\u0698\u06af\u06cc \u0645\u0634\u0627\u0628\u0647\u06cc \u0628\u0647 \u0646\u0627\u0645 z.function() \u0627\u0633\u062a.<\/p>\n<p>\u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0645\u0646 \u06cc\u06a9 \u062a\u0627\u0628\u0639 \u06a9\u0645\u06a9\u06cc \u0628\u0647 \u0646\u0627\u0645 \u0633\u0627\u062e\u062a\u0645 contract\u060c \u06a9\u0647 \u06cc\u06a9 wrapper \u06a9\u0648\u0686\u06a9 \u0627\u0632 z.function().<\/p>\n<p>import type { ZodTypeAny } from &#8220;zod&#8221;;<br \/>\nimport { z } from &#8220;zod&#8221;;<\/p>\n<p>export const contract =<br \/>\n  I extends ZodTypeAny,<br \/>\n  O extends ZodTypeAny,<br \/>\n  F extends (input: z.inferI&gt;) =&gt; z.inferO&gt;,<br \/>\n&gt;(<br \/>\n  { input, output }: { input: I; output: O },<br \/>\n  implement: F,<br \/>\n) =&gt; {<br \/>\n  return z.function().args(input).returns(output).implement(implement);<br \/>\n};<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0648 \u0627\u0632 \u0622\u0646 \u062f\u0631 \u0647\u0631 \u0628\u0633\u062a\u0647 \u062e\u062f\u0645\u0627\u062a\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>export const getUser = (db: PrismaClient) =&gt;<br \/>\n  contract(<br \/>\n    {<br \/>\n      \/\/ the userId should be UUID otherwise it throws an error.<br \/>\n      input: z.strictObject({<br \/>\n        userId: z.string().uuid(),<br \/>\n      }),<br \/>\n      \/\/ the result object should be the user object.<br \/>\n      output: z.promise(userSchema),<br \/>\n    },<br \/>\n    async (input) =&gt; {<br \/>\n      const user = await db.user.findFirst({<br \/>\n        select: {<br \/>\n          id: true,<br \/>\n          name: true,<br \/>\n          image: true,<br \/>\n          createdAt: true,<br \/>\n          updatedAt: true,<br \/>\n        },<br \/>\n        where: {<br \/>\n          id: input.userId,<br \/>\n        },<br \/>\n      });<br \/>\n      if (user === null) {<br \/>\n        throw Error(&#8220;The user does not exist.&#8221;);<br \/>\n      }<br \/>\n      return user;<br \/>\n    },<br \/>\n  );<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0628\u0633\u062a\u0647 trpc \u0647\u0645\u0686\u0646\u06cc\u0646 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0648\u0631\u0648\u062f\u06cc\/\u062e\u0631\u0648\u062c\u06cc \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>export const tasksRouter = router({<br \/>\n  getTasksInFolder: protectedProcedure<br \/>\n    .input(<br \/>\n      z.strictObject({<br \/>\n        folderId: z.string().uuid(),<br \/>\n      }),<br \/>\n    )<br \/>\n    .output(z.array(taskSchema))<br \/>\n    .query(async ({ input, ctx }) =&gt; {<br \/>\n      return getTasksInFolder(ctx.db)({<br \/>\n        userId: ctx.currentUserId,<br \/>\n        folderId: input.folderId,<br \/>\n      });<br \/>\n    }),<br \/>\n&#8230;<br \/>\n})<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0645\u0646 \u0639\u0627\u0634\u0642 \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0647\u0633\u062a\u0645.  \u0628\u0647 \u0648\u06cc\u0698\u0647\u060c \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u062e\u0631\u0648\u062c\u06cc \u0628\u0647 \u0627\u0646\u062f\u0627\u0632\u0647 \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u0648\u0631\u0648\u062f\u06cc \u0645\u0647\u0645 \u0627\u0633\u062a.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062a\u0635\u0648\u0631 \u06a9\u0646\u06cc\u062f \u0628\u0647 \u0637\u0648\u0631 \u062a\u0635\u0627\u062f\u0641\u06cc \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u062d\u0633\u0627\u0633 (\u0645\u0627\u0646\u0646\u062f sessionToken) \u0631\u0627 \u0628\u0647 \u06cc\u06a9 \u0634\u06cc\u0621 \u0646\u062a\u06cc\u062c\u0647 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0647 \u0627\u06cc\u0645.  \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u062e\u0631\u0648\u062c\u06cc \u0628\u0647 \u062c\u0627\u06cc \u0627\u0631\u0633\u0627\u0644 \u0646\u062a\u06cc\u062c\u0647 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u060c \u06cc\u06a9 \u062e\u0637\u0627 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>  \u062a\u0646\u0638\u06cc\u0645 \u0642\u0627\u0644\u0628 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc tRPC<\/p>\n<p>\u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 tRPC \u0641\u0631\u0645\u062a\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u067e\u06cc\u0634\u200c\u0641\u0631\u0636 \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0628\u062f\u0648\u0646 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0631\u0627\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u06cc \u0641\u0631\u0645\u062a\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u0627\u0632 tRPC \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06cc\u06a9 \u0642\u0627\u0644\u0628\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u062e\u0637\u0627\u06cc\u06cc \u0631\u062e \u062f\u0647\u062f\u060c tRPC an \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f \u067e\u06cc\u063a\u0627\u0645 \u062e\u0637\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u067e\u0627\u0633\u062e \u0628\u0647 \u0637\u0648\u0631 \u067e\u06cc\u0634 \u0641\u0631\u0636  \u0627\u06cc\u0646 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0634\u06a9\u0644\u06cc \u0646\u06cc\u0633\u062a\u060c \u0627\u0645\u0627 \u0628\u0631\u062e\u06cc \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u062f\u0631 \u0635\u0648\u0631\u062a \u0628\u0631\u0648\u0632 \u062e\u0637\u0627\u060c \u067e\u06cc\u0627\u0645 \u0647\u0627\u06cc \u067e\u0631\u0645\u062e\u0627\u0637\u0628 \u0631\u0627 \u0628\u0647 error.message \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Zod \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u0645\u0641\u06cc\u062f \u0628\u0647 error.message \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u0627\u06cc\u0646 \u067e\u06cc\u0627\u0645 \u0647\u0646\u06af\u0627\u0645 \u0627\u0634\u06a9\u0627\u0644 \u0632\u062f\u0627\u06cc\u06cc \u0645\u0641\u06cc\u062f \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0627\u06cc\u0646 \u062e\u0637\u0631 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f \u06a9\u0647 \u06cc\u06a9 \u0645\u0647\u0627\u062c\u0645 \u0628\u062a\u0648\u0627\u0646\u062f \u062d\u062f\u0633 \u0628\u0632\u0646\u062f \u0686\u0647 \u062e\u0637\u0627\u0647\u0627\u06cc\u06cc \u062f\u0631 \u062f\u0627\u062e\u0644 \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a.  \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06cc\u06a9 \u0642\u0627\u0644\u0628\u200c\u06a9\u0646\u0646\u062f\u0647 \u0633\u0641\u0627\u0631\u0634\u06cc \u0645\u0627\u0646\u0646\u062f \u0632\u06cc\u0631 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f:<\/p>\n<p>initTRPC.contexttypeof createInnerContext&gt;().create({<br \/>\n  transformer: superjson,<br \/>\n  errorFormatter({ shape }) {<br \/>\n    \/\/ Hide a message to avoid exposing server errors.<br \/>\n    return { &#8230;shape, message: &#8220;&#8221; };<br \/>\n  },<br \/>\n});<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0628\u0627 \u0627\u0646\u062c\u0627\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631\u060c tRPC \u0647\u0645\u06cc\u0634\u0647 \u062f\u0631 \u0635\u0648\u0631\u062a \u0628\u0631\u0648\u0632 \u062e\u0637\u0627\u060c \u06cc\u06a9 \u0631\u0634\u062a\u0647 \u062e\u0627\u0644\u06cc \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f.<\/p>\n<p>  ENV \u0647\u0627 \u0631\u0627 \u0628\u0627 T3 Env \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u062f<\/p>\n<p>T3 Env \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u0648\u0639 \u0627\u06cc\u0645\u0646 \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0645\u062d\u06cc\u0637 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.  \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0647 \u0646\u062f\u0631\u062a \u067e\u06cc\u0634 \u0645\u06cc\u200c\u0622\u06cc\u062f \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u0647\u06cc\u0686 \u0645\u062a\u063a\u06cc\u0631 \u0645\u062d\u06cc\u0637\u06cc \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0631\u0627 \u0628\u0647 \u0647\u0645\u0647 \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0627\u0632 Next.js \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645.<\/p>\n<p>\u0627\u06af\u0631 \u0642\u0635\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u0631\u0627 \u062f\u0627\u0631\u06cc\u062f\u060c \u0645\u0646 \u0646\u06cc\u0632 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0637\u0628\u0642 \u0627\u06cc\u0646 \u0647\u0634\u062f\u0627\u0631 \u062f\u0631 \u0627\u0633\u0646\u0627\u062f \u0631\u0633\u0645\u06cc\u060c \u0637\u0631\u062d\u0648\u0627\u0631\u0647 \u0647\u0627 \u0631\u0627 \u0628\u0647 \u062f\u0648 \u0641\u0627\u06cc\u0644 \u062a\u0642\u0633\u06cc\u0645 \u06a9\u0646\u06cc\u062f: \u06cc\u06a9\u06cc \u0628\u0631\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc (\u0645\u0634\u062a\u0631\u06cc) \u0648 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0631\u0627\u06cc \u0645\u062e\u0641\u06cc (\u0633\u0631\u0648\u0631).<\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0647 \u0627\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631 \u0637\u0631\u062d\u0648\u0627\u0631\u0647 \u0631\u0627 \u062c\u062f\u0627 \u0646\u06a9\u0646\u06cc\u062f\u060c \u0637\u0631\u062d\u200c\u0647\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc (\u06a9\u0644\u06cc\u062f\u0647\u0627) \u0628\u0631\u0627\u06cc \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0633\u0631\u0648\u0631 \u0628\u0647 \u0645\u0634\u062a\u0631\u06cc \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f.  \u0627\u0644\u0628\u062a\u0647\u060c \u0645\u0642\u0627\u062f\u06cc\u0631 ENV \u062f\u0631 \u0645\u0639\u0631\u0636 \u0646\u0645\u0627\u06cc\u0634 \u0646\u06cc\u0633\u062a\u0646\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0627\u062c\u0628\u0627\u0631\u06cc \u0646\u06cc\u0633\u062a.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0637\u0631\u062d\u200c\u0648\u0627\u0631\u0647\u200c\u0647\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0631 \u0645\u0648\u0631\u062f \u0646\u0648\u0639 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0635\u0648\u0631\u062a \u062f\u0627\u062e\u0644\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f (\u0645\u062b\u0644\u0627\u064b NEXTAUTH_***).<\/p>\n<p>  \u0627\u06af\u0631 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc \u06a9\u0646\u06cc\u062f\u060c fetchCache \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u0647\u0646\u06af\u0627\u0645 \u0627\u06cc\u062c\u0627\u062f Minute\u060c \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632\u060c \u062a\u0635\u0645\u06cc\u0645 \u06af\u0631\u0641\u062a\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc API \u0631\u0627 \u062f\u0631 \u0633\u0645\u062a \u06a9\u0644\u0627\u06cc\u0646\u062a \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u0645 \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u06cc \u062f\u0631 SSR (RSC) \u0627\u0646\u062c\u0627\u0645 \u0646\u062f\u0647\u0645\u060c \u0632\u06cc\u0631\u0627 \u0647\u0645\u0647 \u0635\u0641\u062d\u0627\u062a \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062e\u0635\u0648\u0635\u06cc \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u0648 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u062f\u0627\u0631\u0646\u062f\u060c \u0648 \u0645\u06cc\u200c\u062e\u0648\u0627\u0633\u062a\u0645 \u0627\u0632 \u0646\u06af\u0631\u0627\u0646\u06cc \u062f\u0631 \u0645\u0648\u0631\u062f \u0645\u0633\u0627\u0626\u0644 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0646\u0645. .<\/p>\n<p>\u0627\u06af\u0631 \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u062f \u0630\u062e\u06cc\u0631\u0647 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u0634\u062f\u0647 \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f\u060c \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f only-no-store \u06cc\u0627 force-no-store \u0628\u0631\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u06a9\u0634 \u062f\u0631 \u0635\u0641\u062d\u0647.<\/p>\n<p>export const fetchCache = &#8220;only-no-store&#8221;;<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0686\u0647 \u0632\u0645\u0627\u0646\u06cc force-no-store \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c Next.js \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u0634\u062f\u0647 \u0631\u0627 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 a \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u06a9\u0646\u06cc\u062f force-cache \u06af\u0632\u06cc\u0646\u0647 \u062f\u0631 \u0627\u062c\u0632\u0627\u06cc \u0641\u0631\u0632\u0646\u062f.  \u0645\u062a\u0642\u0627\u0628\u0644\u0627\u060c only-no-store \u0647\u0645\u0686\u0646\u06cc\u0646 cache \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0631\u0627\u0626\u0647 \u06cc\u06a9 \u062e\u0637\u0627\u060c \u062e\u0637\u0627 \u0645\u06cc \u062f\u0647\u062f force-cache \u06af\u0632\u06cc\u0646\u0647.<\/p>\n<p>\u0645\u0646 \u0634\u062e\u0635\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u0631\u0627 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 only-no-store \u0632\u06cc\u0631\u0627 \u0627\u06af\u0631 \u0634\u0645\u0627 \u06cc\u0627 \u0634\u062e\u0635 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0647 \u0637\u0648\u0631 \u0646\u0627\u062e\u0648\u0627\u0633\u062a\u0647 \u0630\u062e\u06cc\u0631\u0647 \u067e\u0646\u0647\u0627\u0646 \u0631\u0627 \u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f\u060c \u0628\u0647 \u0634\u0645\u0627 \u0647\u0634\u062f\u0627\u0631 \u0645\u06cc \u062f\u0647\u062f \u0648 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u0645\u062a\u0648\u062c\u0647 \u0627\u0634\u062a\u0628\u0627\u0647 \u0634\u0648\u06cc\u062f.<\/p>\n<p>Error: cache: &#8216;force-cache&#8217; used on fetch for https:\/\/&#8230; with &#8216;export const fetchCache=&#8221;only-no-store&#8221;<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>  \u0647\u062f\u0631 CSP \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u0647\u062f\u0631 CSP \u0628\u0631\u0627\u06cc \u06a9\u0627\u0647\u0634 \u062e\u0637\u0631 \u062d\u0645\u0644\u0627\u062a XSS \u0636\u0631\u0648\u0631\u06cc \u0627\u0633\u062a.  \u062e\u0648\u0634\u0628\u062e\u062a\u0627\u0646\u0647\u060c \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u062f\u0633\u062a\u0648\u0631\u0627\u0644\u0639\u0645\u0644 \u0646\u062d\u0648\u0647 \u062a\u0646\u0638\u06cc\u0645 \u0647\u062f\u0631 CSP \u062f\u0631 \u0627\u0633\u0646\u0627\u062f Next.js \u0622\u0645\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0628\u0647 \u063a\u06cc\u0631 \u0627\u0632 \u0647\u062f\u0631 CSP\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0647\u062f\u0631\u0647\u0627\u06cc \u0627\u0645\u0646\u06cc\u062a\u06cc \u062f\u06cc\u06af\u0631\u06cc \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f. \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627\u06cc\u06cc \u0628\u0647 \u0637\u0648\u0631 \u062e\u0627\u0635 \u0628\u0631\u0627\u06cc \u0627\u0641\u0632\u0648\u062f\u0646 \u0627\u06cc\u0646 \u0633\u0631\u0635\u0641\u062d\u0647 \u0647\u0627 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f (\u0645\u062b\u0644\u0627\u064b next-safe). <\/p>\n<p>  \u067e\u06cc\u0634\u06af\u06cc\u0631\u06cc CSRF \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 Next.js \u0634\u0645\u0627 \u062f\u0627\u0631\u0627\u06cc \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API \u0627\u0633\u062a\u060c \u0627\u0641\u0632\u0648\u062f\u0646 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0633\u0631\u0635\u0641\u062d\u0647 Origin \u062f\u0631 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u062d\u0645\u0644\u0627\u062a CSRF \u0627\u0631\u0632\u0634\u0645\u0646\u062f \u0627\u0633\u062a.  \u0645\u0631\u0648\u0631\u06af\u0631\u0647\u0627\u06cc \u0645\u062f\u0631\u0646 \u0645\u0646\u0634\u0627\u06cc\u06cc \u0631\u0627 \u06a9\u0647 \u0628\u0627\u0639\u062b \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u0633\u0631\u0622\u06cc\u0646\u062f Origin \u0642\u0628\u0644 \u0627\u0632 \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a API \u0634\u062f\u0647 \u0627\u0633\u062a \u0631\u0627 \u0634\u0627\u0645\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0647 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0627\u0632 \u0622\u0646 \u0628\u0631\u0627\u06cc \u062a\u0639\u06cc\u06cc\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0632 \u0647\u0645\u0627\u0646 \u0645\u0628\u062f\u0627 \u0627\u0633\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f.<\/p>\n<p>const hasValidOrigin = (req: NextRequest) =&gt; {<br \/>\n  const origin = req.headers.get(&#8220;Origin&#8221;);<br \/>\n  return origin === null || origin === &#8216;https:\/\/YOUR-ORIGIN&#8217;;<br \/>\n};<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>FYI: \u0627\u06cc\u0646 \u062a\u06a9\u0646\u06cc\u06a9 \u062f\u0631 ServerAction \u0646\u06cc\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0627\u0632 tRPC \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u0634\u0648\u062f \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0646\u062f \u062a\u0627 \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u062d\u0627\u0635\u0644 \u0634\u0648\u062f \u06a9\u0647 \u0646\u0648\u0639 \u0645\u062d\u062a\u0648\u0627 JSON \u0627\u0633\u062a.  \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u062f\u0631 tRPC v11 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u062e\u0648\u0627\u0647\u062f \u0634\u062f\u060c \u0627\u0645\u0627 \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0646\u0633\u062e\u0647 11 \u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u062f\u0631 \u0646\u0633\u062e\u0647 \u0628\u062a\u0627 \u0627\u0633\u062a\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u06cc\u0646 \u0627\u0639\u062a\u0628\u0627\u0631 \u0631\u0627 \u0628\u0627 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u062e\u0648\u062f\u062a\u0627\u0646 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>const hasJsonContentType = (req: NextRequest) =&gt; {<br \/>\n  const contentType = req.headers.get(&#8220;Content-Type&#8221;);<br \/>\n  return (<br \/>\n    typeof contentType === &#8220;string&#8221; &amp;&amp;<br \/>\n    contentType.startsWith(&#8220;application\/json&#8221;)<br \/>\n  );<br \/>\n};<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u0627\u06cc\u0646\u060c \u0627\u06af\u0631 \u0627\u0632 \u06a9\u0648\u06a9\u06cc\u200c\u0647\u0627 \u0628\u0631\u0627\u06cc \u0630\u062e\u06cc\u0631\u0647 \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627\u06cc \u062c\u0644\u0633\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u062f\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u0648\u06cc\u0698\u06af\u06cc\u200c\u0647\u0627\u06cc HttpOnly\u060c Secure \u0648 SameSite \u06a9\u0648\u06a9\u06cc \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f. (\u0645\u0646 \u0645\u0639\u062a\u0642\u062f\u0645 \u06a9\u0647 NextAuth \u0627\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc \u0647\u0627 \u0631\u0627 \u0628\u0647 \u0637\u0648\u0631 \u067e\u06cc\u0634 \u0641\u0631\u0636 \u0628\u0647 \u062f\u0631\u0633\u062a\u06cc \u062a\u0646\u0638\u06cc\u0645 \u0645\u06cc \u06a9\u0646\u062f.)<\/p>\n<p>  \u0647\u062f\u0631 Cache-Control \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u0647\u062f\u0631 Cache-Control \u0628\u0631\u0627\u06cc \u06a9\u0646\u062a\u0631\u0644 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u067e\u0627\u0633\u062e \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646 \u06a9\u0634 \u06a9\u0631\u062f \u06cc\u0627 \u0646\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.  \u062f\u0631 \u0645\u0648\u0631\u062f Minute\u060c \u062a\u0645\u0627\u0645 \u067e\u0627\u0633\u062e\u200c\u0647\u0627\u06cc tRPC \u062e\u0635\u0648\u0635\u06cc \u0647\u0633\u062a\u0646\u062f \u0648 \u0645\u0646 \u0646\u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u0645 \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u0646\u06af\u0647 \u062f\u0627\u0631\u0645.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0647\u062f\u0631 Cache-Control\u060c \u0628\u0647 \u0633\u0627\u062f\u06af\u06cc \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0631\u0627 \u0628\u0647 next.config.js \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\/** @type {import(&#8216;next&#8217;).NextConfig} *\/<br \/>\nconst nextConfig = {<br \/>\n  reactStrictMode: true,<br \/>\n  headers() {<br \/>\n    return [<br \/>\n      {<br \/>\n        source: &#8220;\/api\/:path*&#8221;,<br \/>\n        headers: [<br \/>\n          {<br \/>\n            key: &#8220;Cache-Control&#8221;,<br \/>\n            value: &#8220;private, no-store, no-cache, must-revalidate&#8221;,<br \/>\n          },<br \/>\n          { key: &#8220;Pragma&#8221;, value: &#8220;no-cache&#8221; },<br \/>\n        ],<br \/>\n      },<br \/>\n    ];<br \/>\n  }<br \/>\n}<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u062a\u0648\u062c\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u062f \u06a9\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0647\u062f\u0631\u0647\u0627\u06cc Cache-Control \u0631\u0627 \u062f\u0631 next.config.js \u0628\u0631\u0627\u06cc \u0635\u0641\u062d\u0627\u062a \u06cc\u0627 \u062f\u0627\u0631\u0627\u06cc\u06cc\u200c\u0647\u0627 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f.  Next.js \u0628\u0647 \u0637\u0648\u0631 \u062e\u0648\u062f\u06a9\u0627\u0631 \u0647\u062f\u0631\u0647\u0627\u06cc Cache-Control \u0645\u0646\u0627\u0633\u0628 \u0631\u0627 \u0628\u0647 \u0647\u0631 \u0635\u0641\u062d\u0647 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u062f (\u0634\u0627\u06cc\u062f\u060c \u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645).<\/p>\n<p>  \u0641\u0642\u0637 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 Next.js \u0634\u0645\u0627\u060c \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0646\u062f \u06a9\u0647 \u0642\u0631\u0627\u0631 \u0627\u0633\u062a \u0641\u0642\u0637 \u062f\u0631 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u0648\u0646\u062f \u0648 \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0646\u062e\u0648\u0627\u0647\u06cc\u062f \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631 \u0645\u0639\u0631\u0636 \u0645\u0631\u0648\u0631\u06af\u0631 \u0645\u0634\u062a\u0631\u06cc \u0642\u0631\u0627\u0631 \u062f\u0647\u06cc\u062f.  \u062f\u0631 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u0628\u0633\u062a\u0647 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u0641\u0627\u06cc\u0644\u06cc \u0648\u0627\u0631\u062f \u0634\u0648\u062f server-only \u0628\u0633\u062a\u0647 \u0647\u0627 \u0648 \u0627\u0632 \u06a9\u0644\u0627\u06cc\u0646\u062a \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f\u060c \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0646\u0634\u062a \u06a9\u062f \u0633\u0645\u062a \u0633\u0631\u0648\u0631\u060c \u062e\u0637\u0627 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f.  \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u06cc\u06a9 \u0648\u0627\u0631\u062f\u0627\u062a \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f server-only \u0628\u0647 \u0647\u0631 \u0641\u0627\u06cc\u0644\u06cc \u06a9\u0647 \u0628\u062f\u06cc\u0647\u06cc \u0627\u0633\u062a \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062a\u0648\u0633\u0637 \u0645\u0634\u062a\u0631\u06cc \u0646\u06cc\u0633\u062a.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062f\u0631 [&#8230;nextauth]\/route.ts):<\/p>\n<p>\/\/ Prevent importing from client-side code.<br \/>\nimport &#8220;server-only&#8221;;<\/p>\n<p>import NextAuth from &#8220;next-auth&#8221;<\/p>\n<p>const handler = NextAuth({<br \/>\n  &#8230;<br \/>\n})<\/p>\n<p>export { handler as GET, handler as POST }<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>  \u06a9\u062f Backend \u0631\u0627 \u062a\u0633\u062a \u06a9\u0646\u06cc\u062f<\/p>\n<p>\u062a\u0633\u062a \u0647\u0627\u06cc Backend \u0628\u0631\u0627\u06cc \u0633\u0627\u0644\u0645 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0634\u0645\u0627 \u0636\u0631\u0648\u0631\u06cc \u0647\u0633\u062a\u0646\u062f.  \u062f\u0631 \u0645\u0648\u0631\u062f Minute\u060c \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0645\u0646 \u0627\u0632 Prisma \u062f\u0631 \u0628\u0627\u0637\u0646 (trpc \u0648 \u0628\u0633\u062a\u0647 \u0633\u0631\u0648\u06cc\u0633) \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u0645\u060c \u0645\u062c\u0628\u0648\u0631 \u0634\u062f\u0645 Prisma Client \u0631\u0627 \u0645\u0633\u062e\u0631\u0647 \u06a9\u0646\u0645 \u06cc\u0627 \u0627\u0632 \u06cc\u06a9 \u06a9\u0627\u0646\u062a\u06cc\u0646\u0631 Docker \u0628\u0631\u0627\u06cc \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0628\u0631\u0627\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0628\u0631\u0627\u06cc \u0646\u0648\u0634\u062a\u0646 \u062a\u0633\u062a \u0647\u0627\u06cc Backend \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0645.  \u0627\u0633\u0646\u0627\u062f Prisma \u0647\u0631 \u062f\u0648 \u06af\u0632\u06cc\u0646\u0647 \u0631\u0627 \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0646\u062f: \u062a\u0633\u062a \u0648\u0627\u062d\u062f \u0648 \u062a\u0633\u062a \u0627\u062f\u063a\u0627\u0645.  \u0645\u0646 \u062a\u0633\u062a \u0627\u062f\u063a\u0627\u0645 \u0631\u0627 \u067e\u0630\u06cc\u0631\u0641\u062a\u0645 \u0632\u06cc\u0631\u0627 \u062f\u0642\u06cc\u0642 \u062a\u0631 \u0627\u0632 \u062a\u0633\u062a \u0648\u0627\u062d\u062f \u0627\u0633\u062a \u0632\u06cc\u0631\u0627 \u0627\u0632 \u06cc\u06a9 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0648\u0627\u0642\u0639\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u0642\u0635\u062f \u062f\u0627\u0631\u06cc\u062f \u062a\u0633\u062a \u0647\u0627\u06cc \u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc \u0628\u0646\u0648\u06cc\u0633\u06cc\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u062e\u0648\u0627\u0647\u06cc\u062f \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634 \u0627\u062c\u0631\u0627 \u0645\u06cc \u0634\u0648\u062f \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0631\u0627 \u0628\u0627\u0632\u0646\u0634\u0627\u0646\u06cc \u06a9\u0646\u06cc\u062f.  \u062f\u0631 \u0622\u0646 \u0635\u0648\u0631\u062a\u060c \u06af\u0632\u06cc\u0646\u0647 &#8211;force-reset \u0645\u0641\u06cc\u062f \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n<p>\/\/ package.json<br \/>\n{<br \/>\n  &#8230;<br \/>\n  &#8220;scripts&#8221;: {<br \/>\n    &#8220;db:reset&#8221;: &#8220;prisma db push &#8211;force-reset&#8221;<br \/>\n  }<br \/>\n}<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>\u0647\u0645\u0686\u0646\u06cc\u0646\u060c \u0627\u06af\u0631 \u062f\u0631 \u062a\u0644\u0627\u0634 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0633\u0627\u062e\u062a\u06af\u06cc \u0628\u0631\u0627\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0647\u0633\u062a\u06cc\u062f\u060c \u0645\u0646 FactoryJS \u0631\u0627 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0627\u0634\u06cc\u0627 \u06cc\u0627 \u0631\u06a9\u0648\u0631\u062f\u0647\u0627\u06cc Prisma \u0633\u0627\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0648\u0642\u062a\u06cc \u062a\u0633\u062a \u0645\u06cc \u0646\u0648\u06cc\u0633\u06cc\u062f\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0647\u0645 \u0645\u0648\u0627\u0631\u062f \u0631\u0627\u06cc\u062c \u0648 \u0647\u0645 \u0645\u0648\u0627\u0631\u062f \u0644\u0628\u0647 \u0631\u0627 \u067e\u0648\u0634\u0634 \u062f\u0647\u06cc\u062f.  \u0645\u062b\u0644\u0627 \u0627\u06af\u0631 \u0634\u0646\u0627\u0633\u0647 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0628\u0627\u0634\u062f \u0686\u0647\u061f<\/p>\n<p>describe(&#8220;deleteChart&#8221;, () =&gt; {<br \/>\n  describe(&#8220;when a user has the chart&#8221;, () =&gt; {<br \/>\n    it(&#8220;deletes the chart and its items&#8221;, async () =&gt; {<br \/>\n      const user = await userFactory.create();<br \/>\n      const chart = await chartFactory.vars({ user: () =&gt; user }).create();<br \/>\n      await expect(<br \/>\n        deleteChart(db)({<br \/>\n          id: chart.id,<br \/>\n          userId: user.id,<br \/>\n        }),<br \/>\n      ).resolves.toBeUndefined();<br \/>\n      await expect(<br \/>\n        db.chart.findFirst({<br \/>\n          where: {<br \/>\n            id: chart.id,<br \/>\n          },<br \/>\n        }),<br \/>\n      ).resolves.toBeNull();<br \/>\n    });<br \/>\n  });<\/p>\n<p>  describe(&#8220;when the id is invalid&#8221;, () =&gt; {<br \/>\n    it(&#8220;throws an error&#8221;, async () =&gt; {<br \/>\n      const user = await userFactory.create();<br \/>\n      await expect(<br \/>\n        deleteChart(db)({<br \/>\n          id: &#8216;INVALID&#8217;,<br \/>\n          userId: user.id,<br \/>\n        }),<br \/>\n      ).rejects.toThrow(&#8220;The chart does not exist.&#8221;);<br \/>\n    });<br \/>\n  });<br \/>\n});<\/p>\n<p>    \u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/p>\n<p>    \u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/p>\n<p>  \u0646\u062a\u06cc\u062c\u0647<\/p>\n<p>\u0645\u0646 \u0646\u06a9\u0627\u062a\u06cc \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u0637\u0648\u0644 \u062a\u0648\u0633\u0639\u0647 Minute \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0645\u060c \u0645\u0639\u0631\u0641\u06cc \u06a9\u0631\u062f\u0645.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0645\u0637\u0645\u0626\u0646 \u0646\u06cc\u0633\u062a\u0645 \u06a9\u0647 \u0647\u0645\u0647 \u0646\u06a9\u0627\u062a \u0645\u0647\u0645 \u0631\u0627 \u0641\u0647\u0631\u0633\u062a \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0645 (\u0627\u062d\u062a\u0645\u0627\u0644\u0627 \u0646\u0647\u060c \u0632\u06cc\u0631\u0627 \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0647\u0633\u062a\u0646\u062f \u0648 \u0631\u0648\u0632 \u0628\u0647 \u0631\u0648\u0632 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc \u06a9\u0646\u0646\u062f).  \u0627\u0645\u0627 \u062d\u062f\u0627\u0642\u0644 \u0645\u0639\u062a\u0642\u062f\u0645 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0642\u0635\u062f \u062f\u0627\u0631\u0646\u062f \u0628\u0627 Next.js\u060c Prisma \u0648 \u063a\u06cc\u0631\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u0627\u0632\u0646\u062f \u0645\u0641\u06cc\u062f \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n<p>\u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0628\u0631\u0627\u06cc \u0634\u0645\u0627 \u0645\u0641\u06cc\u062f \u0648 \u062c\u0627\u0644\u0628 \u0628\u0627\u0634\u062f!<\/p>\n<p>\u0627\u06af\u0631 \u0639\u0644\u0627\u0642\u0647 \u0645\u0646\u062f \u0628\u0647 Minute \u0647\u0633\u062a\u06cc\u062f\u060c \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u0644\u06cc\u0646\u06a9 \u0632\u06cc\u0631 \u0628\u0647 \u0645\u062e\u0632\u0646 \u062f\u0633\u062a\u0631\u0633\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u062f.  \u0645\u0627 \u0647\u0645\u0686\u0646\u06cc\u0646 \u0627\u0632 \u0645\u0634\u0627\u0631\u06a9\u062a \u0647\u0627 \u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0645\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n<p>      \u23f0 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f.<\/p>\n<p>\u23f0\u062f\u0642\u06cc\u0642\u0647<\/p>\n<p>\u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f. <\/p>\n<p>\u062f\u0631 \u0628\u0627\u0631\u0647<\/p>\n<p>\u062f\u0642\u06cc\u0642\u0647 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0627\u0633\u062a.\u0628\u0631\u062e\u0644\u0627\u0641 \u0633\u0627\u06cc\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646\u060c Minute \u0639\u0645\u062f\u062a\u0627\u064b \u0628\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0641\u0631\u062f\u06cc \u0645\u062a\u0645\u0631\u06a9\u0632 \u0627\u0633\u062a \u0648 \u0628\u0631\u0627\u06cc \u06a9\u0645\u06a9 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062f\u0631 \u0628\u0631\u0631\u0633\u06cc \u0646\u062d\u0648\u0647 \u06af\u0630\u0631\u0627\u0646\u062f\u0646 \u0632\u0645\u0627\u0646 \u0648 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0639\u0646\u0627\u062f\u0627\u0631\u062a\u0631 \u0627\u0632 \u0622\u0646 \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0627\u0633\u06a9\u0631\u06cc\u0646 \u0634\u0627\u062a \u0647\u0627<\/p>\n<p>\u0627\u0645\u06a9\u0627\u0646\u0627\u062a<\/p>\n<p>\u067e\u0648\u0634\u0647 \u0647\u0627<\/p>\n<p>\u0648\u0631\u0648\u062f\u06cc\u200c\u0647\u0627\u06cc \u0632\u0645\u0627\u0646 \u0631\u062f\u06cc\u0627\u0628\u06cc\u200c\u0634\u062f\u0647 \u062e\u0648\u062f \u0631\u0627 \u0628\u0627 \u067e\u0648\u0634\u0647\u200c\u0647\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u062f \u0648 \u0632\u0645\u0627\u0646 \u0645\u0635\u0631\u0641 \u0627\u062e\u06cc\u0631 \u062e\u0648\u062f \u0631\u0627 \u062f\u0631 \u0647\u0631 \u067e\u0648\u0634\u0647 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u062a\u062c\u0632\u06cc\u0647 \u0648 \u062a\u062d\u0644\u06cc\u0644 \u06a9\u0646\u06cc\u062f.  \u0647\u0645\u0686\u0646\u06cc\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u0648\u0634\u0647 \u0647\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0648 \u0648\u0631\u0648\u062f\u06cc \u0647\u0627\u06cc \u0632\u0645\u0627\u0646 \u0631\u0627 \u062f\u0631 \u0647\u0631 \u0632\u0645\u0627\u0646 \u0627\u0632 \u0646\u0648\u0627\u0631 \u06a9\u0646\u0627\u0631\u06cc \u0645\u0634\u0627\u0647\u062f\u0647 \u0648 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627<\/p>\n<p>\u0686\u0646\u062f\u06cc\u0646 \u067e\u0648\u0634\u0647 \u0631\u0627 \u062f\u0631 \u06cc\u06a9 \u062f\u0633\u062a\u0647 \u06af\u0631\u0648\u0647 \u0628\u0646\u062f\u06cc \u06a9\u0646\u06cc\u062f \u0648 \u0627\u0632 \u0622\u0646\u0647\u0627 \u0628\u0631\u0627\u06cc \u062a\u062c\u0632\u06cc\u0647 \u0648 \u062a\u062d\u0644\u06cc\u0644 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627\u06cc\u06cc \u0631\u0627 \u0628\u0631\u0627\u06cc \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u06a9\u0627\u0647\u0634 \u062f\u0647\u06cc\u062f \u0648 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u062f \u0648 \u0627\u0632 \u0622\u0646\u0647\u0627 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0646\u0645\u0648\u062f\u0627\u0631\u0647\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc<\/p>\n<p>\u0627\u0632 \u067e\u0648\u0634\u0647 \u0647\u0627 \u0648 \u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0648 \u06a9\u0627\u0647\u0634 \u0632\u0645\u0627\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0631 \u0646\u0645\u0648\u062f\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0645\u0648\u0627\u0631\u062f \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u062f\u0631 \u0646\u0645\u0648\u062f\u0627\u0631\u2026<\/p>\n<div data-article-id=\"1933328\" id=\"article-body\">\n<p>\u0645\u0646 \u0627\u062e\u06cc\u0631\u0627 Minute: \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f\u06cc \u06a9\u0647 \u0627\u0632 T3 Stack \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u067e\u0631\u0648\u0698\u0647 \u0622\u062e\u0631 \u0647\u0641\u062a\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f \u0633\u0627\u062e\u062a\u0647 \u0627\u0645.  \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647\u060c \u0646\u06a9\u0627\u062a \u0627\u0645\u0646\u06cc\u062a\u06cc \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u062d\u06cc\u0646 \u0633\u0627\u062e\u062a Minute \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u0645\u060c \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0645. <\/p>\n<hr\/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter-rtl ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u0641\u0647\u0631\u0633\u062a \u0645\u0637\u0627\u0644\u0628<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"\u062a\u063a\u06cc\u06cc\u0631 \u0648\u0636\u0639\u06cc\u062a \u0641\u0647\u0631\u0633\u062a \u0645\u0637\u0627\u0644\u0628\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1_%D8%AF%D8%A7%DB%8C%D8%B1%DA%A9%D8%AA%D9%88%D8%B1%DB%8C\" >\u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#prisma\" >prisma\/<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#schema\" >schema\/<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#services\" >services\/<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#trpc\" >trpc\/<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C_%D9%BE%D8%A7%D8%B1%D8%A7%D9%85%D8%AA%D8%B1%D9%87%D8%A7_%D8%AF%D8%B1_%D9%87%D8%B1_%D8%A8%D8%B3%D8%AA%D9%87\" >\u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627 \u062f\u0631 \u0647\u0631 \u0628\u0633\u062a\u0647<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%AA%D9%86%D8%B8%DB%8C%D9%85_%D9%82%D8%A7%D9%84%D8%A8_%D8%AE%D8%B7%D8%A7%DB%8C_%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C_tRPC\" >\u062a\u0646\u0638\u06cc\u0645 \u0642\u0627\u0644\u0628 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc tRPC<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#ENV_%D9%87%D8%A7_%D8%B1%D8%A7_%D8%A8%D8%A7_T3_Env_%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA_%DA%A9%D9%86%DB%8C%D8%AF\" >ENV \u0647\u0627 \u0631\u0627 \u0628\u0627 T3 Env \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%A7%DA%AF%D8%B1_%D8%A7%D8%B2_%D8%A2%D9%86_%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87_%D9%86%D9%85%DB%8C_%DA%A9%D9%86%DB%8C%D8%AF%D8%8C_fetchCache_%D8%B1%D8%A7_%D8%BA%DB%8C%D8%B1%D9%81%D8%B9%D8%A7%D9%84_%DA%A9%D9%86%DB%8C%D8%AF\" >\u0627\u06af\u0631 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc \u06a9\u0646\u06cc\u062f\u060c fetchCache \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%87%D8%AF%D8%B1_CSP_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\" >\u0647\u062f\u0631 CSP \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%BE%DB%8C%D8%B4%DA%AF%DB%8C%D8%B1%DB%8C_CSRF_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\" >\u067e\u06cc\u0634\u06af\u06cc\u0631\u06cc CSRF \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%87%D8%AF%D8%B1_Cache-Control_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\" >\u0647\u062f\u0631 Cache-Control \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%81%D9%82%D8%B7_%D8%A7%D8%B2_%D8%B3%D8%B1%D9%88%D8%B1_%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\" >\u0641\u0642\u0637 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%DA%A9%D8%AF_Backend_%D8%B1%D8%A7_%D8%AA%D8%B3%D8%AA_%DA%A9%D9%86%DB%8C%D8%AF\" >\u06a9\u062f Backend \u0631\u0627 \u062a\u0633\u062a \u06a9\u0646\u06cc\u062f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%86%D8%AA%DB%8C%D8%AC%D9%87\" >\u0646\u062a\u06cc\u062c\u0647<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%E2%8F%B0_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87_%D8%B1%D8%AF%DB%8C%D8%A7%D8%A8%DB%8C_%D8%B2%D9%85%D8%A7%D9%86_%D9%85%D9%86%D8%A8%D8%B9_%D8%A8%D8%A7%D8%B2_%D8%A8%D8%B1%D8%A7%DB%8C_%D8%A7%D9%81%D8%B1%D8%A7%D8%AF\" >\u23f0 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f.<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%E2%8F%B0_%D8%AF%D9%82%DB%8C%D9%82%D9%87\" >\u23f0 \u062f\u0642\u06cc\u0642\u0647<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%AF%D8%B1_%D8%A8%D8%A7%D8%B1%D9%87\" >\u062f\u0631 \u0628\u0627\u0631\u0647<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%86_%D8%B4%D8%A7%D8%AA_%D9%87%D8%A7\" >\u0627\u0633\u06a9\u0631\u06cc\u0646 \u0634\u0627\u062a \u0647\u0627<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%A7%D9%85%DA%A9%D8%A7%D9%86%D8%A7%D8%AA\" >\u0627\u0645\u06a9\u0627\u0646\u0627\u062a<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%BE%D9%88%D8%B4%D9%87_%D9%87%D8%A7\" >\u067e\u0648\u0634\u0647 \u0647\u0627<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D8%AF%D8%B3%D8%AA%D9%87_%D8%A8%D9%86%D8%AF%DB%8C_%D9%87%D8%A7\" >\u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/nabfollower.com\/blog\/9-tips-for-building-a-secure-web-application-with-trpc-nextjs-prisma-turbo-and-nextauth-55l2\/#%D9%86%D9%85%D9%88%D8%AF%D8%A7%D8%B1%D9%87%D8%A7%DB%8C_%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C\" >\u0646\u0645\u0648\u062f\u0627\u0631\u0647\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1_%D8%AF%D8%A7%DB%8C%D8%B1%DA%A9%D8%AA%D9%88%D8%B1%DB%8C\"><\/span>\n<p>  \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u06cc\u0646 \u0628\u062e\u0634 \u0628\u0647 \u0637\u0648\u0631 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0628\u0647 \u0627\u0645\u0646\u06cc\u062a \u0645\u0631\u0628\u0648\u0637 \u0646\u0645\u06cc \u0634\u0648\u062f\u060c \u0627\u0645\u0627 \u0627\u0628\u062a\u062f\u0627 \u062a\u0648\u0636\u06cc\u062d \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a \u062a\u0627 \u062f\u0631\u06a9 \u0628\u062e\u0634 \u0647\u0627\u06cc \u0632\u06cc\u0631 \u0622\u0633\u0627\u0646 \u062a\u0631 \u0634\u0648\u062f.<\/p>\n<p>\u0645\u0646 Turborepo \u0631\u0627 \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u062f \u0645\u0646\u0628\u0639 \u062e\u0648\u062f \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 monorepo \u067e\u0630\u06cc\u0631\u0641\u062a\u0645.  \u0628\u0627 \u062a\u0648\u062c\u0647 \u0628\u0647 \u0633\u0627\u062e\u062a \u06cc\u06a9 \u067e\u0631\u0648\u0698\u0647 \u0645\u0648\u0646\u0648\u0631\u067e\u0648\u060c \u0641\u06a9\u0631 \u0645\u06cc \u06a9\u0646\u0645 \u0633\u062e\u062a \u062a\u0631\u06cc\u0646 \u0642\u0633\u0645\u062a \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0686\u06af\u0648\u0646\u0647 \u06a9\u062f \u0645\u0646\u0628\u0639 \u0631\u0627 \u062c\u062f\u0627 \u06a9\u0646\u06cc\u0645 \u0648 \u0627\u0632 \u0686\u0647 \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u0645.<\/p>\n<p>\u062f\u0631 \u0627\u0628\u062a\u062f\u0627 \u0628\u0647 \u0641\u06a9\u0631 \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0628\u0631 \u0627\u0633\u0627\u0633 Clean Architecture \u0628\u0648\u062f\u0645\u060c \u0627\u0645\u0627 \u067e\u0633 \u0627\u0632 \u0634\u0631\u0648\u0639\u060c \u0646\u0638\u0631\u0645 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0631\u062f.  \u0627\u06cc\u0646 \u0628\u0647 \u0627\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631\u0686\u0647 \u0645\u0639\u0645\u0627\u0631\u06cc \u067e\u0627\u06a9 \u06cc\u06a9 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0634\u0646\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0648 \u0633\u0646\u062c\u06cc\u062f\u0647 \u0627\u0633\u062a\u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc Minute \u06a9\u0645\u06cc \u0628\u06cc\u0634 \u0627\u0632 \u062d\u062f \u0645\u0647\u0646\u062f\u0633\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0645\u0646 \u062f\u0631 \u0646\u0647\u0627\u06cc\u062a \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0631\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0633\u0627\u062f\u0647 \u06a9\u0631\u062f\u0645:<\/p>\n<p><\/p>\n<p>\u0645\u0646 \u0628\u0631\u062e\u06cc \u0627\u0632 \u0628\u0633\u062a\u0647 \u0647\u0627 \u0631\u0627 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc \u062f\u0647\u0645\u060c \u0628\u0647 \u062c\u0632 \u0622\u0646\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0648\u0627\u0636\u062d \u0647\u0633\u062a\u0646\u062f.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"prisma\"><\/span>\n<p>  <code>prisma\/<\/code><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0633\u062a\u0647 \u0634\u0627\u0645\u0644 \u0641\u0627\u06cc\u0644 \u0637\u0631\u062d\u0648\u0627\u0631\u0647 Prisma\u060c \u0641\u0627\u06cc\u0644 \u0647\u0627\u06cc \u0645\u0647\u0627\u062c\u0631\u062a \u0648 Prisma Client \u0645\u06cc \u0628\u0627\u0634\u062f.  \u0642\u0627\u0628\u0644 \u0630\u06a9\u0631 \u0627\u0633\u062a \u06a9\u0647 Prisma Client \u0627\u0632 \u0686\u0646\u062f\u06cc\u0646 \u0628\u0633\u062a\u0647 \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f: trpc\u060c \u0633\u0631\u0648\u06cc\u0633\u060c \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\/\u0648\u0628.  \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u06cc\u06a9 \u0628\u0633\u062a\u0647 prisma\/ \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u062f \u0632\u06cc\u0631\u0627 \u062f\u0631\u06a9 \u0641\u0627\u06cc\u0644 \u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0628\u0627 Prisma \u0631\u0627 \u0622\u0633\u0627\u0646 \u062a\u0631 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"schema\"><\/span>\n<p>  <code>schema\/<\/code><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u0637\u0631\u062d\u0648\u0627\u0631\u0647\u200c\u0647\u0627\u06cc Zod \u0628\u0631\u0627\u06cc \u0647\u0631 \u0645\u062f\u0644 Prisma \u0648 \u0628\u0631\u062e\u06cc \u062b\u0627\u0628\u062a\u200c\u0647\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u0628\u0627 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0627\u0633\u062a\u060c \u0645\u0627\u0646\u0646\u062f MAX_NAME_LENGTH\u060c REGEXP\u060c \u0648 \u063a\u06cc\u0631\u0647. \u0627\u06cc\u0646\u0647\u0627 \u0628\u0631\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u0646\u062f.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"services\"><\/span>\n<p>  <code>services\/<\/code><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u062a\u0648\u0627\u0628\u0639\u06cc \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u0631\u0648\u06cc\u0647 \u0648\u0627\u062d\u062f \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f\u060c \u0645\u0627\u0646\u0646\u062f \u062f\u0631\u062c \u06cc\u0627 \u0628\u0647 \u0631\u0648\u0632 \u0631\u0633\u0627\u0646\u06cc \u06cc\u06a9 \u0645\u062f\u0644 \u067e\u0633 \u0627\u0632 \u062a\u0623\u06cc\u06cc\u062f \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627. <\/p>\n<h3><span class=\"ez-toc-section\" id=\"trpc\"><\/span>\n<p>  <code>trpc\/<\/code><br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u0644\u06cc\u0646\u06a9 GitHub<\/p>\n<p>\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 tRPC\u060c \u0631\u0648\u062a\u0631\u0647\u0627 \u0648 \u0631\u0648\u06cc\u0647 \u0647\u0627 \u0645\u06cc \u0634\u0648\u062f. <strong>\u0647\u0645\u0647 \u0631\u0648\u06cc\u0647\u200c\u0647\u0627 \u0641\u0627\u0642\u062f \u0645\u0646\u0637\u0642 \u0647\u0633\u062a\u0646\u062f \u0648 \u067e\u0631\u062f\u0627\u0632\u0634 \u0631\u0627 \u0628\u0647 \u0633\u0631\u0648\u06cc\u0633 \u0645\u0646\u0627\u0633\u0628 \u0648\u0627\u06af\u0630\u0627\u0631 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f.<\/strong> \u0628\u0627 \u0627\u0646\u062c\u0627\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u062f\u0631 \u0622\u06cc\u0646\u062f\u0647 \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u0646\u0637\u0642 \u0628\u0647 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u062f\u06cc\u06af\u0631\u06cc (\u0645\u062b\u0644\u0627\u064b serverAction) \u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u0633\u0648\u0626\u06cc\u0686 \u06a9\u0646\u0645.<\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C_%D9%BE%D8%A7%D8%B1%D8%A7%D9%85%D8%AA%D8%B1%D9%87%D8%A7_%D8%AF%D8%B1_%D9%87%D8%B1_%D8%A8%D8%B3%D8%AA%D9%87\"><\/span>\n<p>  \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627 \u062f\u0631 \u0647\u0631 \u0628\u0633\u062a\u0647<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u0645\u0647\u0645\u062a\u0631\u06cc\u0646 \u0628\u062e\u0634 \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0648\u0628 \u0627\u0633\u062a.  \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646\u060c \u0645\u0646 \u0645\u06cc\u200c\u062e\u0648\u0627\u0633\u062a\u0645 \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627\u06cc \u0648\u0631\u0648\u062f\u06cc \u0627\u0631\u0633\u0627\u0644 \u0634\u062f\u0647 \u062a\u0648\u0633\u0637 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0648 \u062e\u0631\u0648\u062c\u06cc\u200c\u0647\u0627 \u0631\u0627 \u062f\u0631 \u0628\u0633\u062a\u0647\u200c\u0647\u0627\u06cc trpc \u0648 \u0633\u0631\u0648\u06cc\u0633 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u06a9\u0646\u0645.  \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0645\u0634\u0627\u0628\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u06cc \u0627\u0633\u062a.<\/p>\n<p>\u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0648\u06cc\u0633\u06cc \u0642\u0631\u0627\u0631\u062f\u0627\u062f\u060c \u0647\u0631 \u0646\u0642\u0637\u0647 \u0648\u0631\u0648\u062f\u06cc (\u0628\u0633\u062a\u0647) \u0628\u0627\u06cc\u062f \u0645\u0642\u0627\u062f\u06cc\u0631 \u0648\u0631\u0648\u062f\u06cc\/\u062e\u0631\u0648\u062c\u06cc \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u062f\u060c \u0648 \u0627\u06af\u0631 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0627\u0634\u062f\u060c \u062a\u0627\u0628\u0639 \u062e\u0637\u0627 \u0645\u06cc \u062f\u0647\u062f \u0648 \u0641\u0631\u0622\u06cc\u0646\u062f \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0631\u0627 \u0628\u0647 \u062f\u0644\u0627\u06cc\u0644 \u0627\u0645\u0646\u06cc\u062a\u06cc \u0627\u062c\u0631\u0627 \u0646\u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u062e\u0648\u0634\u0628\u062e\u062a\u0627\u0646\u0647\u060c tRPC \u0627\u0632 \u0642\u0628\u0644 \u0627\u06cc\u0646 \u0642\u0627\u0628\u0644\u06cc\u062a \u0631\u0627 \u062f\u0627\u0631\u062f \u06a9\u0647 \u0648\u0631\u0648\u062f\u06cc \u0647\u0627 \u0648 \u062e\u0631\u0648\u062c\u06cc \u0647\u0627 \u0631\u0627 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u06a9\u0646\u062f\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Zod \u0646\u06cc\u0632 \u062f\u0627\u0631\u0627\u06cc \u0648\u06cc\u0698\u06af\u06cc \u0645\u0634\u0627\u0628\u0647\u06cc \u0628\u0647 \u0646\u0627\u0645 z.function() \u0627\u0633\u062a.<\/p>\n<p>\u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0645\u0646 \u06cc\u06a9 \u062a\u0627\u0628\u0639 \u06a9\u0645\u06a9\u06cc \u0628\u0647 \u0646\u0627\u0645 \u0633\u0627\u062e\u062a\u0645 <code>contract<\/code>\u060c \u06a9\u0647 \u06cc\u06a9 wrapper \u06a9\u0648\u0686\u06a9 \u0627\u0632 z.function().<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">import<\/span> <span class=\"kd\">type<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">ZodTypeAny<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">zod<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">z<\/span> <span class=\"p\">}<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">zod<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">contract<\/span> <span class=\"o\">=<\/span> <span class=\"o\">\n  <span class=\"nx\">I<\/span> <span class=\"kd\">extends<\/span> <span class=\"nx\">ZodTypeAny<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">O<\/span> <span class=\"kd\">extends<\/span> <span class=\"nx\">ZodTypeAny<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">F<\/span> <span class=\"nf\">extends <\/span><span class=\"p\">(<\/span><span class=\"nx\">input<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nx\">infer<\/span><span class=\"o\"><span class=\"nx\">I<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nx\">infer<\/span><span class=\"o\"><span class=\"nx\">O<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">,<\/span>\n<span class=\"o\">&gt;<\/span><span class=\"p\">(<\/span>\n  <span class=\"p\">{<\/span> <span class=\"nx\">input<\/span><span class=\"p\">,<\/span> <span class=\"nx\">output<\/span> <span class=\"p\">}:<\/span> <span class=\"p\">{<\/span> <span class=\"nl\">input<\/span><span class=\"p\">:<\/span> <span class=\"nx\">I<\/span><span class=\"p\">;<\/span> <span class=\"nl\">output<\/span><span class=\"p\">:<\/span> <span class=\"nx\">O<\/span> <span class=\"p\">},<\/span>\n  <span class=\"nx\">implement<\/span><span class=\"p\">:<\/span> <span class=\"nx\">F<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"kd\">function<\/span><span class=\"p\">().<\/span><span class=\"nf\">args<\/span><span class=\"p\">(<\/span><span class=\"nx\">input<\/span><span class=\"p\">).<\/span><span class=\"nf\">returns<\/span><span class=\"p\">(<\/span><span class=\"nx\">output<\/span><span class=\"p\">).<\/span><span class=\"nf\">implement<\/span><span class=\"p\">(<\/span><span class=\"nx\">implement<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/span><\/span><\/span><\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0648 \u0627\u0632 \u0622\u0646 \u062f\u0631 \u0647\u0631 \u0628\u0633\u062a\u0647 \u062e\u062f\u0645\u0627\u062a\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">getUser<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">db<\/span><span class=\"p\">:<\/span> <span class=\"nx\">PrismaClient<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>\n  <span class=\"nf\">contract<\/span><span class=\"p\">(<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ the userId should be UUID otherwise it throws an error.<\/span>\n      <span class=\"na\">input<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">strictObject<\/span><span class=\"p\">({<\/span>\n        <span class=\"na\">userId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">string<\/span><span class=\"p\">().<\/span><span class=\"nf\">uuid<\/span><span class=\"p\">(),<\/span>\n      <span class=\"p\">}),<\/span>\n      <span class=\"c1\">\/\/ the result object should be the user object.<\/span>\n      <span class=\"na\">output<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">promise<\/span><span class=\"p\">(<\/span><span class=\"nx\">userSchema<\/span><span class=\"p\">),<\/span>\n    <span class=\"p\">},<\/span>\n    <span class=\"k\">async <\/span><span class=\"p\">(<\/span><span class=\"nx\">input<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">user<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">db<\/span><span class=\"p\">.<\/span><span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nf\">findFirst<\/span><span class=\"p\">({<\/span>\n        <span class=\"na\">select<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">name<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">image<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">createdAt<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">updatedAt<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">},<\/span>\n        <span class=\"na\">where<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"nx\">input<\/span><span class=\"p\">.<\/span><span class=\"nx\">userId<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">},<\/span>\n      <span class=\"p\">});<\/span>\n      <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">user<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">null<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">throw<\/span> <span class=\"nc\">Error<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">The user does not exist.<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n      <span class=\"p\">}<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">user<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">},<\/span>\n  <span class=\"p\">);<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0628\u0633\u062a\u0647 trpc \u0647\u0645\u0686\u0646\u06cc\u0646 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0648\u0631\u0648\u062f\u06cc\/\u062e\u0631\u0648\u062c\u06cc \u0631\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">tasksRouter<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">router<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">getTasksInFolder<\/span><span class=\"p\">:<\/span> <span class=\"nx\">protectedProcedure<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">input<\/span><span class=\"p\">(<\/span>\n      <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">strictObject<\/span><span class=\"p\">({<\/span>\n        <span class=\"na\">folderId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">string<\/span><span class=\"p\">().<\/span><span class=\"nf\">uuid<\/span><span class=\"p\">(),<\/span>\n      <span class=\"p\">}),<\/span>\n    <span class=\"p\">)<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">output<\/span><span class=\"p\">(<\/span><span class=\"nx\">z<\/span><span class=\"p\">.<\/span><span class=\"nf\">array<\/span><span class=\"p\">(<\/span><span class=\"nx\">taskSchema<\/span><span class=\"p\">))<\/span>\n    <span class=\"p\">.<\/span><span class=\"nf\">query<\/span><span class=\"p\">(<\/span><span class=\"k\">async <\/span><span class=\"p\">({<\/span> <span class=\"nx\">input<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ctx<\/span> <span class=\"p\">})<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nf\">getTasksInFolder<\/span><span class=\"p\">(<\/span><span class=\"nx\">ctx<\/span><span class=\"p\">.<\/span><span class=\"nx\">db<\/span><span class=\"p\">)({<\/span>\n        <span class=\"na\">userId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">ctx<\/span><span class=\"p\">.<\/span><span class=\"nx\">currentUserId<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">folderId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">input<\/span><span class=\"p\">.<\/span><span class=\"nx\">folderId<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">});<\/span>\n    <span class=\"p\">}),<\/span>\n<span class=\"p\">...<\/span>\n<span class=\"p\">})<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0645\u0646 \u0639\u0627\u0634\u0642 \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0647\u0633\u062a\u0645.  \u0628\u0647 \u0648\u06cc\u0698\u0647\u060c <strong>\u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u062e\u0631\u0648\u062c\u06cc \u0628\u0647 \u0627\u0646\u062f\u0627\u0632\u0647 \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u0648\u0631\u0648\u062f\u06cc \u0645\u0647\u0645 \u0627\u0633\u062a<\/strong>.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062a\u0635\u0648\u0631 \u06a9\u0646\u06cc\u062f \u0628\u0647 \u0637\u0648\u0631 \u062a\u0635\u0627\u062f\u0641\u06cc \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u062d\u0633\u0627\u0633 (\u0645\u0627\u0646\u0646\u062f sessionToken) \u0631\u0627 \u0628\u0647 \u06cc\u06a9 \u0634\u06cc\u0621 \u0646\u062a\u06cc\u062c\u0647 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0647 \u0627\u06cc\u0645.  \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u062e\u0631\u0648\u062c\u06cc \u0628\u0647 \u062c\u0627\u06cc \u0627\u0631\u0633\u0627\u0644 \u0646\u062a\u06cc\u062c\u0647 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u060c \u06cc\u06a9 \u062e\u0637\u0627 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D8%AA%D9%86%D8%B8%DB%8C%D9%85_%D9%82%D8%A7%D9%84%D8%A8_%D8%AE%D8%B7%D8%A7%DB%8C_%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C_tRPC\"><\/span>\n<p>  \u062a\u0646\u0638\u06cc\u0645 \u0642\u0627\u0644\u0628 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc tRPC<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 tRPC \u0641\u0631\u0645\u062a\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u067e\u06cc\u0634\u200c\u0641\u0631\u0636 \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0628\u062f\u0648\u0646 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0631\u0627\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u06cc \u0641\u0631\u0645\u062a\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u0627\u0632 tRPC \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06cc\u06a9 \u0642\u0627\u0644\u0628\u200c\u06a9\u0646\u0646\u062f\u0647 \u062e\u0637\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u062e\u0637\u0627\u06cc\u06cc \u0631\u062e \u062f\u0647\u062f\u060c tRPC an \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f <strong>\u067e\u06cc\u063a\u0627\u0645 \u062e\u0637\u0627<\/strong> \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u067e\u0627\u0633\u062e \u0628\u0647 \u0637\u0648\u0631 \u067e\u06cc\u0634 \u0641\u0631\u0636  \u0627\u06cc\u0646 \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0645\u0634\u06a9\u0644\u06cc \u0646\u06cc\u0633\u062a\u060c \u0627\u0645\u0627 \u0628\u0631\u062e\u06cc \u0627\u0632 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u062f\u0631 \u0635\u0648\u0631\u062a \u0628\u0631\u0648\u0632 \u062e\u0637\u0627\u060c \u067e\u06cc\u0627\u0645 \u0647\u0627\u06cc \u067e\u0631\u0645\u062e\u0627\u0637\u0628 \u0631\u0627 \u0628\u0647 error.message \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Zod \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u0645\u0641\u06cc\u062f \u0628\u0647 error.message \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/media.dev.to\/cdn-cgi\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9yerfqz7j9ltxbyrw7k.png\" alt=\"\u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 Zod \u06cc\u06a9 \u067e\u06cc\u0627\u0645 \u0645\u0641\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u062f\" loading=\"lazy\" width=\"800\" height=\"683\" title=\"\"><\/p>\n<p>\u0627\u06cc\u0646 \u067e\u06cc\u0627\u0645 \u0647\u0646\u06af\u0627\u0645 \u0627\u0634\u06a9\u0627\u0644 \u0632\u062f\u0627\u06cc\u06cc \u0645\u0641\u06cc\u062f \u0627\u0633\u062a\u060c \u0627\u0645\u0627 <strong>\u0627\u06cc\u0646 \u062e\u0637\u0631 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f \u06a9\u0647 \u06cc\u06a9 \u0645\u0647\u0627\u062c\u0645 \u0628\u062a\u0648\u0627\u0646\u062f \u062d\u062f\u0633 \u0628\u0632\u0646\u062f \u0686\u0647 \u062e\u0637\u0627\u0647\u0627\u06cc\u06cc \u062f\u0631 \u062f\u0627\u062e\u0644 \u0631\u062e \u062f\u0627\u062f\u0647 \u0627\u0633\u062a<\/strong>.  \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06cc\u06a9 \u0642\u0627\u0644\u0628\u200c\u06a9\u0646\u0646\u062f\u0647 \u0633\u0641\u0627\u0631\u0634\u06cc \u0645\u0627\u0646\u0646\u062f \u0632\u06cc\u0631 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f:<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nx\">initTRPC<\/span><span class=\"p\">.<\/span><span class=\"nx\">context<\/span><span class=\"o\"><span class=\"k\">typeof<\/span> <span class=\"nx\">createInnerContext<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">().<\/span><span class=\"nf\">create<\/span><span class=\"p\">({<\/span>\n  <span class=\"na\">transformer<\/span><span class=\"p\">:<\/span> <span class=\"nx\">superjson<\/span><span class=\"p\">,<\/span>\n  <span class=\"nf\">errorFormatter<\/span><span class=\"p\">({<\/span> <span class=\"nx\">shape<\/span> <span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Hide a message to avoid exposing server errors.<\/span>\n    <span class=\"k\">return<\/span> <span class=\"p\">{<\/span> <span class=\"p\">...<\/span><span class=\"nx\">shape<\/span><span class=\"p\">,<\/span> <span class=\"na\">message<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"\"<\/span> <span class=\"p\">};<\/span>\n  <span class=\"p\">},<\/span>\n<span class=\"p\">});<\/span>\n<\/span><\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0628\u0627 \u0627\u0646\u062c\u0627\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631\u060c tRPC \u0647\u0645\u06cc\u0634\u0647 \u062f\u0631 \u0635\u0648\u0631\u062a \u0628\u0631\u0648\u0632 \u062e\u0637\u0627\u060c \u06cc\u06a9 \u0631\u0634\u062a\u0647 \u062e\u0627\u0644\u06cc \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/media.dev.to\/cdn-cgi\/image\/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsf4v0ovc986ist9kry4.png\" alt=\"tRPC \u06cc\u06a9 \u0631\u0634\u062a\u0647 \u062e\u0627\u0644\u06cc \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f\" loading=\"lazy\" width=\"800\" height=\"297\" title=\"\"><\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"ENV_%D9%87%D8%A7_%D8%B1%D8%A7_%D8%A8%D8%A7_T3_Env_%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  ENV \u0647\u0627 \u0631\u0627 \u0628\u0627 T3 Env \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>T3 Env \u0628\u0631\u0627\u06cc \u0645\u062f\u06cc\u0631\u06cc\u062a \u0646\u0648\u0639 \u0627\u06cc\u0645\u0646 \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0645\u062d\u06cc\u0637 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.  \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0647 \u0646\u062f\u0631\u062a \u067e\u06cc\u0634 \u0645\u06cc\u200c\u0622\u06cc\u062f \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u0647\u06cc\u0686 \u0645\u062a\u063a\u06cc\u0631 \u0645\u062d\u06cc\u0637\u06cc \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f\u060c \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0631\u0627 \u0628\u0647 \u0647\u0645\u0647 \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0627\u0632 Next.js \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645.<\/p>\n<p>\u0627\u06af\u0631 \u0642\u0635\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u0631\u0627 \u062f\u0627\u0631\u06cc\u062f\u060c \u0645\u0646 \u0646\u06cc\u0632 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 <strong>\u0637\u0628\u0642 \u0627\u06cc\u0646 \u0647\u0634\u062f\u0627\u0631 \u062f\u0631 \u0627\u0633\u0646\u0627\u062f \u0631\u0633\u0645\u06cc\u060c \u0637\u0631\u062d\u0648\u0627\u0631\u0647 \u0647\u0627 \u0631\u0627 \u0628\u0647 \u062f\u0648 \u0641\u0627\u06cc\u0644 \u062a\u0642\u0633\u06cc\u0645 \u06a9\u0646\u06cc\u062f: \u06cc\u06a9\u06cc \u0628\u0631\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc (\u0645\u0634\u062a\u0631\u06cc) \u0648 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0631\u0627\u06cc \u0645\u062e\u0641\u06cc (\u0633\u0631\u0648\u0631).<\/strong><\/p>\n<p>\u0627\u06cc\u0646 \u0628\u0647 \u0627\u06cc\u0646 \u062f\u0644\u06cc\u0644 \u0627\u0633\u062a \u06a9\u0647 \u0627\u06af\u0631 \u0637\u0631\u062d\u0648\u0627\u0631\u0647 \u0631\u0627 \u062c\u062f\u0627 \u0646\u06a9\u0646\u06cc\u062f\u060c \u0637\u0631\u062d\u200c\u0647\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc (\u06a9\u0644\u06cc\u062f\u0647\u0627) \u0628\u0631\u0627\u06cc \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0633\u0631\u0648\u0631 \u0628\u0647 \u0645\u0634\u062a\u0631\u06cc \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f.  \u0627\u0644\u0628\u062a\u0647\u060c \u0645\u0642\u0627\u062f\u06cc\u0631 ENV \u062f\u0631 \u0645\u0639\u0631\u0636 \u0646\u0645\u0627\u06cc\u0634 \u0646\u06cc\u0633\u062a\u0646\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0627\u062c\u0628\u0627\u0631\u06cc \u0646\u06cc\u0633\u062a.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0637\u0631\u062d\u200c\u0648\u0627\u0631\u0647\u200c\u0647\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0646\u062f \u062f\u0631 \u0645\u0648\u0631\u062f \u0646\u0648\u0639 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0635\u0648\u0631\u062a \u062f\u0627\u062e\u0644\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u062f (\u0645\u062b\u0644\u0627\u064b <code>NEXTAUTH_***<\/code>).<\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D8%A7%DA%AF%D8%B1_%D8%A7%D8%B2_%D8%A2%D9%86_%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87_%D9%86%D9%85%DB%8C_%DA%A9%D9%86%DB%8C%D8%AF%D8%8C_fetchCache_%D8%B1%D8%A7_%D8%BA%DB%8C%D8%B1%D9%81%D8%B9%D8%A7%D9%84_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u0627\u06af\u0631 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u06cc \u06a9\u0646\u06cc\u062f\u060c fetchCache \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0647\u0646\u06af\u0627\u0645 \u0627\u06cc\u062c\u0627\u062f Minute\u060c \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632\u060c \u062a\u0635\u0645\u06cc\u0645 \u06af\u0631\u0641\u062a\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc API \u0631\u0627 \u062f\u0631 \u0633\u0645\u062a \u06a9\u0644\u0627\u06cc\u0646\u062a \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u0645 \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u06cc \u062f\u0631 SSR (RSC) \u0627\u0646\u062c\u0627\u0645 \u0646\u062f\u0647\u0645\u060c \u0632\u06cc\u0631\u0627 \u0647\u0645\u0647 \u0635\u0641\u062d\u0627\u062a \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u062e\u0635\u0648\u0635\u06cc \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f \u0648 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u062f\u0627\u0631\u0646\u062f\u060c \u0648 \u0645\u06cc\u200c\u062e\u0648\u0627\u0633\u062a\u0645 \u0627\u0632 \u0646\u06af\u0631\u0627\u0646\u06cc \u062f\u0631 \u0645\u0648\u0631\u062f \u0645\u0633\u0627\u0626\u0644 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u06a9\u0646\u0645. .<\/p>\n<p>\u0627\u06af\u0631 \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u062f \u0630\u062e\u06cc\u0631\u0647 \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u0634\u062f\u0647 \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f\u060c \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f <code>only-no-store<\/code> \u06cc\u0627 <code>force-no-store<\/code> \u0628\u0631\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u06a9\u0634 \u062f\u0631 \u0635\u0641\u062d\u0647.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"k\">export<\/span> <span class=\"kd\">const<\/span> <span class=\"nx\">fetchCache<\/span> <span class=\"o\">=<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">only-no-store<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0686\u0647 \u0632\u0645\u0627\u0646\u06cc <code>force-no-store<\/code> \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c Next.js \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0648\u0627\u06a9\u0634\u06cc \u0634\u062f\u0647 \u0631\u0627 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u0646\u0645\u06cc\u200c\u06a9\u0646\u062f\u060c \u062d\u062a\u06cc \u0627\u06af\u0631 a \u0631\u0627 \u0627\u0631\u0627\u0626\u0647 \u06a9\u0646\u06cc\u062f <code>force-cache<\/code> \u06af\u0632\u06cc\u0646\u0647 \u062f\u0631 \u0627\u062c\u0632\u0627\u06cc \u0641\u0631\u0632\u0646\u062f.  \u0645\u062a\u0642\u0627\u0628\u0644\u0627\u060c <code>only-no-store<\/code> \u0647\u0645\u0686\u0646\u06cc\u0646 cache \u0631\u0627 \u063a\u06cc\u0631\u0641\u0639\u0627\u0644 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0631\u0627\u0626\u0647 \u06cc\u06a9 \u062e\u0637\u0627\u060c \u062e\u0637\u0627 \u0645\u06cc \u062f\u0647\u062f <code>force-cache<\/code> \u06af\u0632\u06cc\u0646\u0647.<\/p>\n<p>\u0645\u0646 \u0634\u062e\u0635\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u0631\u0627 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 <code>only-no-store<\/code> \u0632\u06cc\u0631\u0627 \u0627\u06af\u0631 \u0634\u0645\u0627 \u06cc\u0627 \u0634\u062e\u0635 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0647 \u0637\u0648\u0631 \u0646\u0627\u062e\u0648\u0627\u0633\u062a\u0647 \u0630\u062e\u06cc\u0631\u0647 \u067e\u0646\u0647\u0627\u0646 \u0631\u0627 \u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f\u060c \u0628\u0647 \u0634\u0645\u0627 \u0647\u0634\u062f\u0627\u0631 \u0645\u06cc \u062f\u0647\u062f \u0648 \u0628\u0647 \u0634\u0645\u0627 \u0627\u0645\u06a9\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u0645\u062a\u0648\u062c\u0647 \u0627\u0634\u062a\u0628\u0627\u0647 \u0634\u0648\u06cc\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>Error: cache: 'force-cache' used on fetch for https:\/\/... with 'export const fetchCache=\"only-no-store\"\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D9%87%D8%AF%D8%B1_CSP_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u0647\u062f\u0631 CSP \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0647\u062f\u0631 CSP \u0628\u0631\u0627\u06cc \u06a9\u0627\u0647\u0634 \u062e\u0637\u0631 \u062d\u0645\u0644\u0627\u062a XSS \u0636\u0631\u0648\u0631\u06cc \u0627\u0633\u062a.  \u062e\u0648\u0634\u0628\u062e\u062a\u0627\u0646\u0647\u060c \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u062f\u0633\u062a\u0648\u0631\u0627\u0644\u0639\u0645\u0644 \u0646\u062d\u0648\u0647 \u062a\u0646\u0638\u06cc\u0645 \u0647\u062f\u0631 CSP \u062f\u0631 \u0627\u0633\u0646\u0627\u062f Next.js \u0622\u0645\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0628\u0647 \u063a\u06cc\u0631 \u0627\u0632 \u0647\u062f\u0631 CSP\u060c <strong>\u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0647\u062f\u0631\u0647\u0627\u06cc \u0627\u0645\u0646\u06cc\u062a\u06cc \u062f\u06cc\u06af\u0631\u06cc \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f.<\/strong> \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627\u06cc\u06cc \u0628\u0647 \u0637\u0648\u0631 \u062e\u0627\u0635 \u0628\u0631\u0627\u06cc \u0627\u0641\u0632\u0648\u062f\u0646 \u0627\u06cc\u0646 \u0633\u0631\u0635\u0641\u062d\u0647 \u0647\u0627 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f (\u0645\u062b\u0644\u0627\u064b next-safe). <\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D9%BE%DB%8C%D8%B4%DA%AF%DB%8C%D8%B1%DB%8C_CSRF_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u067e\u06cc\u0634\u06af\u06cc\u0631\u06cc CSRF \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0627\u06af\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 Next.js \u0634\u0645\u0627 \u062f\u0627\u0631\u0627\u06cc \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API \u0627\u0633\u062a\u060c \u0627\u0641\u0632\u0648\u062f\u0646 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0633\u0631\u0635\u0641\u062d\u0647 Origin \u062f\u0631 \u0645\u06cc\u0627\u0646 \u0627\u0641\u0632\u0627\u0631 \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u062d\u0645\u0644\u0627\u062a CSRF \u0627\u0631\u0632\u0634\u0645\u0646\u062f \u0627\u0633\u062a.  \u0645\u0631\u0648\u0631\u06af\u0631\u0647\u0627\u06cc \u0645\u062f\u0631\u0646 \u0645\u0646\u0634\u0627\u06cc\u06cc \u0631\u0627 \u06a9\u0647 \u0628\u0627\u0639\u062b \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u062f\u0631 \u0633\u0631\u0622\u06cc\u0646\u062f Origin \u0642\u0628\u0644 \u0627\u0632 \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a API \u0634\u062f\u0647 \u0627\u0633\u062a \u0631\u0627 \u0634\u0627\u0645\u0644 \u0645\u06cc\u200c\u0634\u0648\u062f \u06a9\u0647 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646 \u0627\u0632 \u0622\u0646 \u0628\u0631\u0627\u06cc \u062a\u0639\u06cc\u06cc\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u0632 \u0647\u0645\u0627\u0646 \u0645\u0628\u062f\u0627 \u0627\u0633\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">hasValidOrigin<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">:<\/span> <span class=\"nx\">NextRequest<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">origin<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Origin<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">origin<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">null<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">origin<\/span> <span class=\"o\">===<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">https:\/\/YOUR-ORIGIN<\/span><span class=\"dl\">'<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>FYI: \u0627\u06cc\u0646 \u062a\u06a9\u0646\u06cc\u06a9 \u062f\u0631 ServerAction \u0646\u06cc\u0632 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0627\u0632 tRPC \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u0634\u0648\u062f \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0646\u062f \u062a\u0627 \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u062d\u0627\u0635\u0644 \u0634\u0648\u062f \u06a9\u0647 \u0646\u0648\u0639 \u0645\u062d\u062a\u0648\u0627 JSON \u0627\u0633\u062a.  \u0627\u06cc\u0646 \u0631\u0648\u06cc\u06a9\u0631\u062f \u062f\u0631 tRPC v11 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u062e\u0648\u0627\u0647\u062f \u0634\u062f\u060c \u0627\u0645\u0627 \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0646\u0633\u062e\u0647 11 \u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u062f\u0631 \u0646\u0633\u062e\u0647 \u0628\u062a\u0627 \u0627\u0633\u062a\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u06cc\u0646 \u0627\u0639\u062a\u0628\u0627\u0631 \u0631\u0627 \u0628\u0627 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u062e\u0648\u062f\u062a\u0627\u0646 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">hasJsonContentType<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">req<\/span><span class=\"p\">:<\/span> <span class=\"nx\">NextRequest<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">const<\/span> <span class=\"nx\">contentType<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">Content-Type<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return <\/span><span class=\"p\">(<\/span>\n    <span class=\"k\">typeof<\/span> <span class=\"nx\">contentType<\/span> <span class=\"o\">===<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">string<\/span><span class=\"dl\">\"<\/span> <span class=\"o\">&amp;&amp;<\/span>\n    <span class=\"nx\">contentType<\/span><span class=\"p\">.<\/span><span class=\"nf\">startsWith<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">application\/json<\/span><span class=\"dl\">\"<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0639\u0644\u0627\u0648\u0647 \u0628\u0631 \u0627\u06cc\u0646\u060c \u0627\u06af\u0631 \u0627\u0632 \u06a9\u0648\u06a9\u06cc\u200c\u0647\u0627 \u0628\u0631\u0627\u06cc \u0630\u062e\u06cc\u0631\u0647 \u0634\u0646\u0627\u0633\u0647\u200c\u0647\u0627\u06cc \u062c\u0644\u0633\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u062f\u060c <strong>\u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u0648\u06cc\u0698\u06af\u06cc\u200c\u0647\u0627\u06cc HttpOnly\u060c Secure \u0648 SameSite \u06a9\u0648\u06a9\u06cc \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f.<\/strong> (\u0645\u0646 \u0645\u0639\u062a\u0642\u062f\u0645 \u06a9\u0647 NextAuth \u0627\u06cc\u0646 \u0648\u06cc\u0698\u06af\u06cc \u0647\u0627 \u0631\u0627 \u0628\u0647 \u0637\u0648\u0631 \u067e\u06cc\u0634 \u0641\u0631\u0636 \u0628\u0647 \u062f\u0631\u0633\u062a\u06cc \u062a\u0646\u0638\u06cc\u0645 \u0645\u06cc \u06a9\u0646\u062f.)<\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D9%87%D8%AF%D8%B1_Cache-Control_%D8%B1%D8%A7_%D8%A7%D8%B6%D8%A7%D9%81%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u0647\u062f\u0631 Cache-Control \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0647\u062f\u0631 Cache-Control \u0628\u0631\u0627\u06cc \u06a9\u0646\u062a\u0631\u0644 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u067e\u0627\u0633\u062e \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646 \u06a9\u0634 \u06a9\u0631\u062f \u06cc\u0627 \u0646\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.  \u062f\u0631 \u0645\u0648\u0631\u062f Minute\u060c \u062a\u0645\u0627\u0645 \u067e\u0627\u0633\u062e\u200c\u0647\u0627\u06cc tRPC \u062e\u0635\u0648\u0635\u06cc \u0647\u0633\u062a\u0646\u062f \u0648 \u0645\u0646 \u0646\u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u0645 \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631 \u062d\u0627\u0641\u0638\u0647 \u067e\u0646\u0647\u0627\u0646 \u0646\u06af\u0647 \u062f\u0627\u0631\u0645.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0647\u062f\u0631 Cache-Control\u060c \u0628\u0647 \u0633\u0627\u062f\u06af\u06cc \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0631\u0627 \u0628\u0647 next.config.js \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"cm\">\/** @type {import('next').NextConfig} *\/<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">nextConfig<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"na\">reactStrictMode<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n  <span class=\"nf\">headers<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"p\">[<\/span>\n      <span class=\"p\">{<\/span>\n        <span class=\"na\">source<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">\/api\/:path*<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">headers<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\n          <span class=\"p\">{<\/span>\n            <span class=\"na\">key<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Cache-Control<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n            <span class=\"na\">value<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">private, no-store, no-cache, must-revalidate<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\n          <span class=\"p\">},<\/span>\n          <span class=\"p\">{<\/span> <span class=\"na\">key<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Pragma<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"na\">value<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">no-cache<\/span><span class=\"dl\">\"<\/span> <span class=\"p\">},<\/span>\n        <span class=\"p\">],<\/span>\n      <span class=\"p\">},<\/span>\n    <span class=\"p\">];<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u062a\u0648\u062c\u0647 \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u062f \u06a9\u0647 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0647\u062f\u0631\u0647\u0627\u06cc Cache-Control \u0631\u0627 \u062f\u0631 next.config.js \u0628\u0631\u0627\u06cc \u0635\u0641\u062d\u0627\u062a \u06cc\u0627 \u062f\u0627\u0631\u0627\u06cc\u06cc\u200c\u0647\u0627 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f.  Next.js \u0628\u0647 \u0637\u0648\u0631 \u062e\u0648\u062f\u06a9\u0627\u0631 \u0647\u062f\u0631\u0647\u0627\u06cc Cache-Control \u0645\u0646\u0627\u0633\u0628 \u0631\u0627 \u0628\u0647 \u0647\u0631 \u0635\u0641\u062d\u0647 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u062f (\u0634\u0627\u06cc\u062f\u060c \u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645).<\/p>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D9%81%D9%82%D8%B7_%D8%A7%D8%B2_%D8%B3%D8%B1%D9%88%D8%B1_%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u0641\u0642\u0637 \u0627\u0632 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u062f\u0631 \u067e\u0631\u0648\u0698\u0647 Next.js \u0634\u0645\u0627\u060c \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc\u06cc \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u0646\u062f \u06a9\u0647 \u0642\u0631\u0627\u0631 \u0627\u0633\u062a \u0641\u0642\u0637 \u062f\u0631 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u0648\u0646\u062f \u0648 \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0646\u062e\u0648\u0627\u0647\u06cc\u062f \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631 \u0645\u0639\u0631\u0636 \u0645\u0631\u0648\u0631\u06af\u0631 \u0645\u0634\u062a\u0631\u06cc \u0642\u0631\u0627\u0631 \u062f\u0647\u06cc\u062f.  \u062f\u0631 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u0628\u0633\u062a\u0647 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u0641\u0627\u06cc\u0644\u06cc \u0648\u0627\u0631\u062f \u0634\u0648\u062f <code>server-only<\/code> \u0628\u0633\u062a\u0647 \u0647\u0627 \u0648 \u0627\u0632 \u06a9\u0644\u0627\u06cc\u0646\u062a \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f\u060c \u0628\u0631\u0627\u06cc \u062c\u0644\u0648\u06af\u06cc\u0631\u06cc \u0627\u0632 \u0646\u0634\u062a \u06a9\u062f \u0633\u0645\u062a \u0633\u0631\u0648\u0631\u060c \u062e\u0637\u0627 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f.  \u0645\u0646 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u06cc\u06a9 \u0648\u0627\u0631\u062f\u0627\u062a \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f <code>server-only<\/code> \u0628\u0647 \u0647\u0631 \u0641\u0627\u06cc\u0644\u06cc \u06a9\u0647 \u0628\u062f\u06cc\u0647\u06cc \u0627\u0633\u062a \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062a\u0648\u0633\u0637 \u0645\u0634\u062a\u0631\u06cc \u0646\u06cc\u0633\u062a.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062f\u0631 [&#8230;nextauth]\/route.ts):<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"c1\">\/\/ Prevent importing from client-side code.<\/span>\n<span class=\"k\">import<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">server-only<\/span><span class=\"dl\">\"<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">import<\/span> <span class=\"nx\">NextAuth<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">next-auth<\/span><span class=\"dl\">\"<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">handler<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">NextAuth<\/span><span class=\"p\">({<\/span>\n  <span class=\"p\">...<\/span>\n<span class=\"p\">})<\/span>\n\n<span class=\"k\">export<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">handler<\/span> <span class=\"k\">as<\/span> <span class=\"nx\">GET<\/span><span class=\"p\">,<\/span> <span class=\"nx\">handler<\/span> <span class=\"k\">as<\/span> <span class=\"nx\">POST<\/span> <span class=\"p\">}<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%DA%A9%D8%AF_Backend_%D8%B1%D8%A7_%D8%AA%D8%B3%D8%AA_%DA%A9%D9%86%DB%8C%D8%AF\"><\/span>\n<p>  \u06a9\u062f Backend \u0631\u0627 \u062a\u0633\u062a \u06a9\u0646\u06cc\u062f<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u062a\u0633\u062a \u0647\u0627\u06cc Backend \u0628\u0631\u0627\u06cc \u0633\u0627\u0644\u0645 \u0646\u06af\u0647 \u062f\u0627\u0634\u062a\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 \u0634\u0645\u0627 \u0636\u0631\u0648\u0631\u06cc \u0647\u0633\u062a\u0646\u062f.  \u062f\u0631 \u0645\u0648\u0631\u062f Minute\u060c \u0627\u0632 \u0622\u0646\u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0645\u0646 \u0627\u0632 Prisma \u062f\u0631 \u0628\u0627\u0637\u0646 (trpc \u0648 \u0628\u0633\u062a\u0647 \u0633\u0631\u0648\u06cc\u0633) \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0631\u062f\u0645\u060c \u0645\u062c\u0628\u0648\u0631 \u0634\u062f\u0645 Prisma Client \u0631\u0627 \u0645\u0633\u062e\u0631\u0647 \u06a9\u0646\u0645 \u06cc\u0627 \u0627\u0632 \u06cc\u06a9 \u06a9\u0627\u0646\u062a\u06cc\u0646\u0631 Docker \u0628\u0631\u0627\u06cc \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0628\u0631\u0627\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0628\u0631\u0627\u06cc \u0646\u0648\u0634\u062a\u0646 \u062a\u0633\u062a \u0647\u0627\u06cc Backend \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0645.  \u0627\u0633\u0646\u0627\u062f Prisma \u0647\u0631 \u062f\u0648 \u06af\u0632\u06cc\u0646\u0647 \u0631\u0627 \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0646\u062f: \u062a\u0633\u062a \u0648\u0627\u062d\u062f \u0648 \u062a\u0633\u062a \u0627\u062f\u063a\u0627\u0645.  \u0645\u0646 \u062a\u0633\u062a \u0627\u062f\u063a\u0627\u0645 \u0631\u0627 \u067e\u0630\u06cc\u0631\u0641\u062a\u0645 \u0632\u06cc\u0631\u0627 \u062f\u0642\u06cc\u0642 \u062a\u0631 \u0627\u0632 \u062a\u0633\u062a \u0648\u0627\u062d\u062f \u0627\u0633\u062a \u0632\u06cc\u0631\u0627 \u0627\u0632 \u06cc\u06a9 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0648\u0627\u0642\u0639\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<p>\u0627\u06af\u0631 \u0642\u0635\u062f \u062f\u0627\u0631\u06cc\u062f \u062a\u0633\u062a \u0647\u0627\u06cc \u06cc\u06a9\u067e\u0627\u0631\u0686\u0647 \u0633\u0627\u0632\u06cc \u0628\u0646\u0648\u06cc\u0633\u06cc\u062f\u060c \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0628\u062e\u0648\u0627\u0647\u06cc\u062f \u0647\u0631 \u0628\u0627\u0631 \u06a9\u0647 \u0622\u0632\u0645\u0627\u06cc\u0634 \u0627\u062c\u0631\u0627 \u0645\u06cc \u0634\u0648\u062f \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0631\u0627 \u0628\u0627\u0632\u0646\u0634\u0627\u0646\u06cc \u06a9\u0646\u06cc\u062f.  \u062f\u0631 \u0622\u0646 \u0635\u0648\u0631\u062a\u060c \u06af\u0632\u06cc\u0646\u0647 &#8211;force-reset \u0645\u0641\u06cc\u062f \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight json\"><code><span class=\"err\">\/\/<\/span><span class=\"w\"> <\/span><span class=\"err\">package.json<\/span><span class=\"w\">\n<\/span><span class=\"p\">{<\/span><span class=\"w\">\n  <\/span><span class=\"err\">...<\/span><span class=\"w\">\n  <\/span><span class=\"nl\">\"scripts\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n    <\/span><span class=\"nl\">\"db:reset\"<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s2\">\"prisma db push --force-reset\"<\/span><span class=\"w\">\n  <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0647\u0645\u0686\u0646\u06cc\u0646\u060c \u0627\u06af\u0631 \u062f\u0631 \u062a\u0644\u0627\u0634 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u062f\u0627\u062f\u0647\u200c\u0647\u0627\u06cc \u0633\u0627\u062e\u062a\u06af\u06cc \u0628\u0631\u0627\u06cc \u0622\u0632\u0645\u0627\u06cc\u0634 \u0647\u0633\u062a\u06cc\u062f\u060c \u0645\u0646 FactoryJS \u0631\u0627 \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc\u200c\u06a9\u0646\u0645 \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0627\u0634\u06cc\u0627 \u06cc\u0627 \u0631\u06a9\u0648\u0631\u062f\u0647\u0627\u06cc Prisma \u0633\u0627\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p>\u0648\u0642\u062a\u06cc \u062a\u0633\u062a \u0645\u06cc \u0646\u0648\u06cc\u0633\u06cc\u062f\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0647\u0645 \u0645\u0648\u0627\u0631\u062f \u0631\u0627\u06cc\u062c \u0648 \u0647\u0645 \u0645\u0648\u0627\u0631\u062f \u0644\u0628\u0647 \u0631\u0627 \u067e\u0648\u0634\u0634 \u062f\u0647\u06cc\u062f.  \u0645\u062b\u0644\u0627 \u0627\u06af\u0631 \u0634\u0646\u0627\u0633\u0647 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0628\u0627\u0634\u062f \u0686\u0647\u061f<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight typescript\"><code><span class=\"nf\">describe<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">deleteChart<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nf\">describe<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">when a user has the chart<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">it<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">deletes the chart and its items<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"k\">async <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">user<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">userFactory<\/span><span class=\"p\">.<\/span><span class=\"nf\">create<\/span><span class=\"p\">();<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">chart<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">chartFactory<\/span><span class=\"p\">.<\/span><span class=\"nf\">vars<\/span><span class=\"p\">({<\/span> <span class=\"na\">user<\/span><span class=\"p\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nx\">user<\/span> <span class=\"p\">}).<\/span><span class=\"nf\">create<\/span><span class=\"p\">();<\/span>\n      <span class=\"k\">await<\/span> <span class=\"nf\">expect<\/span><span class=\"p\">(<\/span>\n        <span class=\"nf\">deleteChart<\/span><span class=\"p\">(<\/span><span class=\"nx\">db<\/span><span class=\"p\">)({<\/span>\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"nx\">chart<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">userId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">}),<\/span>\n      <span class=\"p\">).<\/span><span class=\"nx\">resolves<\/span><span class=\"p\">.<\/span><span class=\"nf\">toBeUndefined<\/span><span class=\"p\">();<\/span>\n      <span class=\"k\">await<\/span> <span class=\"nf\">expect<\/span><span class=\"p\">(<\/span>\n        <span class=\"nx\">db<\/span><span class=\"p\">.<\/span><span class=\"nx\">chart<\/span><span class=\"p\">.<\/span><span class=\"nf\">findFirst<\/span><span class=\"p\">({<\/span>\n          <span class=\"na\">where<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n            <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"nx\">chart<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span>\n          <span class=\"p\">},<\/span>\n        <span class=\"p\">}),<\/span>\n      <span class=\"p\">).<\/span><span class=\"nx\">resolves<\/span><span class=\"p\">.<\/span><span class=\"nf\">toBeNull<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">});<\/span>\n  <span class=\"p\">});<\/span>\n\n  <span class=\"nf\">describe<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">when the id is invalid<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nf\">it<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">throws an error<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"k\">async <\/span><span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">user<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">userFactory<\/span><span class=\"p\">.<\/span><span class=\"nf\">create<\/span><span class=\"p\">();<\/span>\n      <span class=\"k\">await<\/span> <span class=\"nf\">expect<\/span><span class=\"p\">(<\/span>\n        <span class=\"nf\">deleteChart<\/span><span class=\"p\">(<\/span><span class=\"nx\">db<\/span><span class=\"p\">)({<\/span>\n          <span class=\"na\">id<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">INVALID<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n          <span class=\"na\">userId<\/span><span class=\"p\">:<\/span> <span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">}),<\/span>\n      <span class=\"p\">).<\/span><span class=\"nx\">rejects<\/span><span class=\"p\">.<\/span><span class=\"nf\">toThrow<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">The chart does not exist.<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n  <span class=\"p\">});<\/span>\n<span class=\"p\">});<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u0648\u0627\u0631\u062f \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<h2><span class=\"ez-toc-section\" id=\"%D9%86%D8%AA%DB%8C%D8%AC%D9%87\"><\/span>\n<p>  \u0646\u062a\u06cc\u062c\u0647<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0645\u0646 \u0646\u06a9\u0627\u062a\u06cc \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u0637\u0648\u0644 \u062a\u0648\u0633\u0639\u0647 Minute \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062f\u0645\u060c \u0645\u0639\u0631\u0641\u06cc \u06a9\u0631\u062f\u0645.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u0645\u0637\u0645\u0626\u0646 \u0646\u06cc\u0633\u062a\u0645 \u06a9\u0647 \u0647\u0645\u0647 \u0646\u06a9\u0627\u062a \u0645\u0647\u0645 \u0631\u0627 \u0641\u0647\u0631\u0633\u062a \u06a9\u0631\u062f\u0647 \u0628\u0627\u0634\u0645 (\u0627\u062d\u062a\u0645\u0627\u0644\u0627 \u0646\u0647\u060c \u0632\u06cc\u0631\u0627 \u0627\u06cc\u0646 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0647\u0633\u062a\u0646\u062f \u0648 \u0631\u0648\u0632 \u0628\u0647 \u0631\u0648\u0632 \u062a\u063a\u06cc\u06cc\u0631 \u0645\u06cc \u06a9\u0646\u0646\u062f).  \u0627\u0645\u0627 \u062d\u062f\u0627\u0642\u0644 \u0645\u0639\u062a\u0642\u062f\u0645 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0628\u0631\u0627\u06cc \u0647\u0645\u0647 \u06a9\u0633\u0627\u0646\u06cc \u06a9\u0647 \u0642\u0635\u062f \u062f\u0627\u0631\u0646\u062f \u0628\u0627 Next.js\u060c Prisma \u0648 \u063a\u06cc\u0631\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0633\u0627\u0632\u0646\u062f \u0645\u0641\u06cc\u062f \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n<p>\u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0628\u0631\u0627\u06cc \u0634\u0645\u0627 \u0645\u0641\u06cc\u062f \u0648 \u062c\u0627\u0644\u0628 \u0628\u0627\u0634\u062f!<\/p>\n<p>\u0627\u06af\u0631 \u0639\u0644\u0627\u0642\u0647 \u0645\u0646\u062f \u0628\u0647 Minute \u0647\u0633\u062a\u06cc\u062f\u060c \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u0644\u06cc\u0646\u06a9 \u0632\u06cc\u0631 \u0628\u0647 \u0645\u062e\u0632\u0646 \u062f\u0633\u062a\u0631\u0633\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u062f.  \u0645\u0627 \u0647\u0645\u0686\u0646\u06cc\u0646 \u0627\u0632 \u0645\u0634\u0627\u0631\u06a9\u062a \u0647\u0627 \u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0645\u06cc \u06a9\u0646\u06cc\u0645.<\/p>\n<div class=\"ltag-github-readme-tag\">\n<div class=\"readme-overview\">\n<h3><span class=\"ez-toc-section\" id=\"%E2%8F%B0_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87_%D8%B1%D8%AF%DB%8C%D8%A7%D8%A8%DB%8C_%D8%B2%D9%85%D8%A7%D9%86_%D9%85%D9%86%D8%A8%D8%B9_%D8%A8%D8%A7%D8%B2_%D8%A8%D8%B1%D8%A7%DB%8C_%D8%A7%D9%81%D8%B1%D8%A7%D8%AF\"><\/span>\n<p>      \u23f0 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f.<br \/>\n    <span class=\"ez-toc-section-end\"><\/span><\/h3>\n<\/p><\/div>\n<div class=\"ltag-github-body\">\n<div id=\"readme\" class=\"md\" data-path=\"README.md\">\n<article class=\"markdown-body entry-content container-lg\" itemprop=\"text\">\n<p><h3 align=\"center\" class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%E2%8F%B0_%D8%AF%D9%82%DB%8C%D9%82%D9%87\"><\/span>\u23f0<br \/>\u062f\u0642\u06cc\u0642\u0647<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<\/p>\n<p align=\"center\" dir=\"auto\">\u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f. <\/p>\n<p><h2 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D8%AF%D8%B1_%D8%A8%D8%A7%D8%B1%D9%87\"><\/span>\u062f\u0631 \u0628\u0627\u0631\u0647<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<\/p>\n<p dir=\"auto\">\u062f\u0642\u06cc\u0642\u0647 \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0627\u0633\u062a.<br \/>\u0628\u0631\u062e\u0644\u0627\u0641 \u0633\u0627\u06cc\u0631 \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646\u060c Minute \u0639\u0645\u062f\u062a\u0627\u064b \u0628\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0641\u0631\u062f\u06cc \u0645\u062a\u0645\u0631\u06a9\u0632 \u0627\u0633\u062a \u0648 \u0628\u0631\u0627\u06cc \u06a9\u0645\u06a9 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062f\u0631 \u0628\u0631\u0631\u0633\u06cc \u0646\u062d\u0648\u0647 \u06af\u0630\u0631\u0627\u0646\u062f\u0646 \u0632\u0645\u0627\u0646 \u0648 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0639\u0646\u0627\u062f\u0627\u0631\u062a\u0631 \u0627\u0632 \u0622\u0646 \u0637\u0631\u0627\u062d\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p><h2 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%86_%D8%B4%D8%A7%D8%AA_%D9%87%D8%A7\"><\/span>\u0627\u0633\u06a9\u0631\u06cc\u0646 \u0634\u0627\u062a \u0647\u0627<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<\/p>\n<p dir=\"auto\"><img decoding=\"async\" src=\"https:\/\/dev.to\/ktmouk\/max-width: 100%;\" loading=\"lazy\" alt=\"\" title=\"\"><\/p>\n<p dir=\"auto\"><img decoding=\"async\" src=\"https:\/\/dev.to\/ktmouk\/max-width: 100%;\" loading=\"lazy\" alt=\"\" title=\"\"><\/p>\n<p><h2 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D8%A7%D9%85%DA%A9%D8%A7%D9%86%D8%A7%D8%AA\"><\/span>\u0627\u0645\u06a9\u0627\u0646\u0627\u062a<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<\/p>\n<p><h3 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D9%BE%D9%88%D8%B4%D9%87_%D9%87%D8%A7\"><\/span>\u067e\u0648\u0634\u0647 \u0647\u0627<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<\/p>\n<p dir=\"auto\"><img decoding=\"async\" width=\"250\" src=\"https:\/\/dev.to\/ktmouk\/max-width: 100%;\" loading=\"lazy\" alt=\"\" title=\"\"><\/p>\n<p dir=\"auto\">\u0648\u0631\u0648\u062f\u06cc\u200c\u0647\u0627\u06cc \u0632\u0645\u0627\u0646 \u0631\u062f\u06cc\u0627\u0628\u06cc\u200c\u0634\u062f\u0647 \u062e\u0648\u062f \u0631\u0627 \u0628\u0627 \u067e\u0648\u0634\u0647\u200c\u0647\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u06cc\u062f \u0648 \u0632\u0645\u0627\u0646 \u0645\u0635\u0631\u0641 \u0627\u062e\u06cc\u0631 \u062e\u0648\u062f \u0631\u0627 \u062f\u0631 \u0647\u0631 \u067e\u0648\u0634\u0647 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u062a\u062c\u0632\u06cc\u0647 \u0648 \u062a\u062d\u0644\u06cc\u0644 \u06a9\u0646\u06cc\u062f.  \u0647\u0645\u0686\u0646\u06cc\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u0648\u0634\u0647 \u0647\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0648 \u0648\u0631\u0648\u062f\u06cc \u0647\u0627\u06cc \u0632\u0645\u0627\u0646 \u0631\u0627 \u062f\u0631 \u0647\u0631 \u0632\u0645\u0627\u0646 \u0627\u0632 \u0646\u0648\u0627\u0631 \u06a9\u0646\u0627\u0631\u06cc \u0645\u0634\u0627\u0647\u062f\u0647 \u0648 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u062f.<\/p>\n<p><h3 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D8%AF%D8%B3%D8%AA%D9%87_%D8%A8%D9%86%D8%AF%DB%8C_%D9%87%D8%A7\"><\/span>\u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<\/p>\n<p dir=\"auto\"><img decoding=\"async\" width=\"200\" src=\"https:\/\/dev.to\/ktmouk\/max-width: 100%;\" loading=\"lazy\" alt=\"\" title=\"\"><\/p>\n<p dir=\"auto\">\u0686\u0646\u062f\u06cc\u0646 \u067e\u0648\u0634\u0647 \u0631\u0627 \u062f\u0631 \u06cc\u06a9 \u062f\u0633\u062a\u0647 \u06af\u0631\u0648\u0647 \u0628\u0646\u062f\u06cc \u06a9\u0646\u06cc\u062f \u0648 \u0627\u0632 \u0622\u0646\u0647\u0627 \u0628\u0631\u0627\u06cc \u062a\u062c\u0632\u06cc\u0647 \u0648 \u062a\u062d\u0644\u06cc\u0644 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627\u06cc\u06cc \u0631\u0627 \u0628\u0631\u0627\u06cc \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u06a9\u0627\u0647\u0634 \u062f\u0647\u06cc\u062f \u0648 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u0627\u0641\u0632\u0627\u06cc\u0634 \u062f\u0647\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u062f \u0648 \u0627\u0632 \u0622\u0646\u0647\u0627 \u062f\u0631 \u0635\u0641\u062d\u0647 \u06af\u0632\u0627\u0631\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p><h3 class=\"heading-element\" dir=\"auto\"><span class=\"ez-toc-section\" id=\"%D9%86%D9%85%D9%88%D8%AF%D8%A7%D8%B1%D9%87%D8%A7%DB%8C_%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C\"><\/span>\u0646\u0645\u0648\u062f\u0627\u0631\u0647\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<\/p>\n<p dir=\"auto\"><img decoding=\"async\" width=\"250\" src=\"https:\/\/dev.to\/ktmouk\/max-width: 100%;\" loading=\"lazy\" alt=\"\" title=\"\"><\/p>\n<p dir=\"auto\">\u0627\u0632 \u067e\u0648\u0634\u0647 \u0647\u0627 \u0648 \u062f\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0647\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0628\u0631\u0627\u06cc \u0646\u0645\u0627\u06cc\u0634 \u0627\u0641\u0632\u0627\u06cc\u0634 \u0648 \u06a9\u0627\u0647\u0634 \u0632\u0645\u0627\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062f\u0631 \u0646\u0645\u0648\u062f\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0645\u0648\u0627\u0631\u062f \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u062f\u0631 \u0646\u0645\u0648\u062f\u0627\u0631\u2026<\/p>\n<\/article>\n<\/div><\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summarize this content to 400 words in Persian Lang \u0645\u0646 \u0627\u062e\u06cc\u0631\u0627 Minute: \u06cc\u06a9 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u062f\u06cc\u0627\u0628\u06cc \u0632\u0645\u0627\u0646 \u0645\u0646\u0628\u0639 \u0628\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0641\u0631\u0627\u062f\u06cc \u06a9\u0647 \u0627\u0632 T3 Stack \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u067e\u0631\u0648\u0698\u0647 \u0622\u062e\u0631 \u0647\u0641\u062a\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0646\u062f \u0633\u0627\u062e\u062a\u0647 \u0627\u0645. \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647\u060c \u0646\u06a9\u0627\u062a \u0627\u0645\u0646\u06cc\u062a\u06cc \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u062d\u06cc\u0646 \u0633\u0627\u062e\u062a Minute \u06cc\u0627\u062f \u06af\u0631\u0641\u062a\u0645\u060c \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0645. \u0633\u0627\u062e\u062a\u0627\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u06cc\u0646 \u0628\u062e\u0634 \u0628\u0647 &hellip;<\/p>\n","protected":false},"author":2,"featured_media":70913,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-70912","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/70912","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=70912"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/70912\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/70913"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=70912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=70912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=70912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}