From bc4fd3ff1a7019bff962d0262c76647767d8e997 Mon Sep 17 00:00:00 2001 From: Fahim Ali Zain Date: Fri, 22 Dec 2023 12:24:24 +0530 Subject: [PATCH] feat: RPC get_user_by_mobile RPC for Admin --- libs/supabase/prisma/seed.ts | 21 +- .../prisma/seeds/get_user_by_mobile.ts | 22 + libs/supabase/project.json | 5 +- libs/supabase/src/supabase_types.ts | 8 +- libs/supabase/supabase/.env.example | 1 + libs/supabase/supabase/README.md | 5 + .../functions/_shared/database_type.ts | 419 ++++++++++++++++++ 7 files changed, 467 insertions(+), 14 deletions(-) create mode 100644 libs/supabase/prisma/seeds/get_user_by_mobile.ts create mode 100644 libs/supabase/supabase/.env.example create mode 100644 libs/supabase/supabase/README.md create mode 100644 libs/supabase/supabase/functions/_shared/database_type.ts diff --git a/libs/supabase/prisma/seed.ts b/libs/supabase/prisma/seed.ts index 2c1adda..a8b7838 100644 --- a/libs/supabase/prisma/seed.ts +++ b/libs/supabase/prisma/seed.ts @@ -1,19 +1,20 @@ -import { PrismaClient } from '@prisma/client' -import { create_profile_on_signup } from './seeds/create_profile_on_signup' +import { PrismaClient } from '@prisma/client'; +import { create_profile_on_signup } from './seeds/create_profile_on_signup'; +import { create_get_user_by_mobile } from './seeds/get_user_by_mobile'; -const prisma = new PrismaClient() +const prisma = new PrismaClient(); async function main() { - await create_profile_on_signup(prisma) + await create_profile_on_signup(prisma); + await create_get_user_by_mobile(prisma); } - main() .then(async () => { - await prisma.$disconnect() + await prisma.$disconnect(); }) .catch(async (e) => { - console.error(e) - await prisma.$disconnect() - process.exit(1) - }) \ No newline at end of file + console.error(e); + await prisma.$disconnect(); + process.exit(1); + }); diff --git a/libs/supabase/prisma/seeds/get_user_by_mobile.ts b/libs/supabase/prisma/seeds/get_user_by_mobile.ts new file mode 100644 index 0000000..faa1f52 --- /dev/null +++ b/libs/supabase/prisma/seeds/get_user_by_mobile.ts @@ -0,0 +1,22 @@ +import { PrismaClient } from '@prisma/client'; + +export async function create_get_user_by_mobile(prisma: PrismaClient) { + await prisma.$executeRaw` + CREATE OR REPLACE FUNCTION public.get_user_by_mobile(mobile text) + RETURNS SETOF auth.users AS + $$ + BEGIN + RETURN QUERY + SELECT + -- id, email, email_confirmed_at, invited_at, + -- phone, phone_confirmed_at + -- raw_app_meta_data, raw_user_meta_data, is_super_admin, + -- created_at, updated_at, deleted_at + * + FROM auth.users WHERE phone = mobile; + END; + $$ + LANGUAGE plpgsql + SECURITY INVOKER; + `; +} diff --git a/libs/supabase/project.json b/libs/supabase/project.json index 6c5917c..129fd59 100644 --- a/libs/supabase/project.json +++ b/libs/supabase/project.json @@ -19,7 +19,8 @@ "outputs": ["{options.outputFile}"], "options": { "lintFilePatterns": [ - "libs/supabase/**/*.ts", + "libs/supabase/src/**/*.ts", + "libs/supabase/prisma/**/*.ts", "libs/supabase/package.json" ] } @@ -48,7 +49,7 @@ "cwd": "libs/supabase", "commands": [ "npx supabase gen types typescript --linked --schema public> ./src/supabase_types.ts", - "npx nx lint supabase --fix" + "npx nx lint supabase --fix --force" ] } } diff --git a/libs/supabase/src/supabase_types.ts b/libs/supabase/src/supabase_types.ts index e2b30c0..bcbed1a 100644 --- a/libs/supabase/src/supabase_types.ts +++ b/libs/supabase/src/supabase_types.ts @@ -1,4 +1,3 @@ - export type Json = | string | number @@ -323,7 +322,12 @@ export interface Database { [_ in never]: never } Functions: { - [_ in never]: never + get_user_by_mobile: { + Args: { + mobile: string + } + Returns: unknown[] + } } Enums: { [_ in never]: never diff --git a/libs/supabase/supabase/.env.example b/libs/supabase/supabase/.env.example new file mode 100644 index 0000000..50d681b --- /dev/null +++ b/libs/supabase/supabase/.env.example @@ -0,0 +1 @@ +FAST2SMS_API_KEY= \ No newline at end of file diff --git a/libs/supabase/supabase/README.md b/libs/supabase/supabase/README.md new file mode 100644 index 0000000..0697879 --- /dev/null +++ b/libs/supabase/supabase/README.md @@ -0,0 +1,5 @@ +# Updating Secrets + +``` +supabase secrets set --env-file ./supabase/.env +``` \ No newline at end of file diff --git a/libs/supabase/supabase/functions/_shared/database_type.ts b/libs/supabase/supabase/functions/_shared/database_type.ts new file mode 100644 index 0000000..bcbed1a --- /dev/null +++ b/libs/supabase/supabase/functions/_shared/database_type.ts @@ -0,0 +1,419 @@ +export type Json = + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] + +export interface Database { + public: { + Tables: { + _prisma_migrations: { + Row: { + applied_steps_count: number + checksum: string + finished_at: string | null + id: string + logs: string | null + migration_name: string + rolled_back_at: string | null + started_at: string + } + Insert: { + applied_steps_count?: number + checksum: string + finished_at?: string | null + id: string + logs?: string | null + migration_name: string + rolled_back_at?: string | null + started_at?: string + } + Update: { + applied_steps_count?: number + checksum?: string + finished_at?: string | null + id?: string + logs?: string | null + migration_name?: string + rolled_back_at?: string | null + started_at?: string + } + Relationships: [] + } + Course: { + Row: { + createdAt: string + createdById: string | null + id: string + title: string + updatedAt: string | null + updatedById: string | null + } + Insert: { + createdAt?: string + createdById?: string | null + id?: string + title: string + updatedAt?: string | null + updatedById?: string | null + } + Update: { + createdAt?: string + createdById?: string | null + id?: string + title?: string + updatedAt?: string | null + updatedById?: string | null + } + Relationships: [ + { + foreignKeyName: "Course_createdById_fkey" + columns: ["createdById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Course_updatedById_fkey" + columns: ["updatedById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + } + ] + } + McqQuestion: { + Row: { + correctOption: number + explanation: string + id: string + options: string[] | null + question: string + topicId: string + } + Insert: { + correctOption: number + explanation: string + id?: string + options?: string[] | null + question: string + topicId: string + } + Update: { + correctOption?: number + explanation?: string + id?: string + options?: string[] | null + question?: string + topicId?: string + } + Relationships: [ + { + foreignKeyName: "McqQuestion_topicId_fkey" + columns: ["topicId"] + isOneToOne: false + referencedRelation: "Topic" + referencedColumns: ["id"] + } + ] + } + Profile: { + Row: { + city: string + email: string | null + firstName: string + id: string + lastName: string + mobile: string | null + state: string + } + Insert: { + city: string + email?: string | null + firstName: string + id: string + lastName: string + mobile?: string | null + state: string + } + Update: { + city?: string + email?: string | null + firstName?: string + id?: string + lastName?: string + mobile?: string | null + state?: string + } + Relationships: [] + } + Stage: { + Row: { + courseId: string + createdAt: string + createdById: string | null + id: string + title: string + updatedAt: string | null + updatedById: string | null + } + Insert: { + courseId: string + createdAt?: string + createdById?: string | null + id?: string + title: string + updatedAt?: string | null + updatedById?: string | null + } + Update: { + courseId?: string + createdAt?: string + createdById?: string | null + id?: string + title?: string + updatedAt?: string | null + updatedById?: string | null + } + Relationships: [ + { + foreignKeyName: "Stage_courseId_fkey" + columns: ["courseId"] + isOneToOne: false + referencedRelation: "Course" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Stage_createdById_fkey" + columns: ["createdById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Stage_updatedById_fkey" + columns: ["updatedById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + } + ] + } + Subject: { + Row: { + createdAt: string + createdById: string | null + description: string + id: string + stageId: string + title: string + updatedAt: string | null + updatedById: string | null + } + Insert: { + createdAt?: string + createdById?: string | null + description: string + id?: string + stageId: string + title: string + updatedAt?: string | null + updatedById?: string | null + } + Update: { + createdAt?: string + createdById?: string | null + description?: string + id?: string + stageId?: string + title?: string + updatedAt?: string | null + updatedById?: string | null + } + Relationships: [ + { + foreignKeyName: "Subject_createdById_fkey" + columns: ["createdById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Subject_stageId_fkey" + columns: ["stageId"] + isOneToOne: false + referencedRelation: "Stage" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Subject_updatedById_fkey" + columns: ["updatedById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + } + ] + } + Topic: { + Row: { + createdAt: string + createdById: string | null + description: string + id: string + studyMaterial: string + subjectId: string + title: string + updatedAt: string | null + updatedById: string | null + videoLink: string + } + Insert: { + createdAt?: string + createdById?: string | null + description: string + id?: string + studyMaterial: string + subjectId: string + title: string + updatedAt?: string | null + updatedById?: string | null + videoLink: string + } + Update: { + createdAt?: string + createdById?: string | null + description?: string + id?: string + studyMaterial?: string + subjectId?: string + title?: string + updatedAt?: string | null + updatedById?: string | null + videoLink?: string + } + Relationships: [ + { + foreignKeyName: "Topic_createdById_fkey" + columns: ["createdById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Topic_subjectId_fkey" + columns: ["subjectId"] + isOneToOne: false + referencedRelation: "Subject" + referencedColumns: ["id"] + }, + { + foreignKeyName: "Topic_updatedById_fkey" + columns: ["updatedById"] + isOneToOne: false + referencedRelation: "Profile" + referencedColumns: ["id"] + } + ] + } + } + Views: { + [_ in never]: never + } + Functions: { + get_user_by_mobile: { + Args: { + mobile: string + } + Returns: unknown[] + } + } + Enums: { + [_ in never]: never + } + CompositeTypes: { + [_ in never]: never + } + } +} + +export type Tables< + PublicTableNameOrOptions extends + | keyof (Database["public"]["Tables"] & Database["public"]["Views"]) + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & + Database[PublicTableNameOrOptions["schema"]]["Views"]) + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & + Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { + Row: infer R + } + ? R + : never + : PublicTableNameOrOptions extends keyof (Database["public"]["Tables"] & + Database["public"]["Views"]) + ? (Database["public"]["Tables"] & + Database["public"]["Views"])[PublicTableNameOrOptions] extends { + Row: infer R + } + ? R + : never + : never + +export type TablesInsert< + PublicTableNameOrOptions extends + | keyof Database["public"]["Tables"] + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Insert: infer I + } + ? I + : never + : PublicTableNameOrOptions extends keyof Database["public"]["Tables"] + ? Database["public"]["Tables"][PublicTableNameOrOptions] extends { + Insert: infer I + } + ? I + : never + : never + +export type TablesUpdate< + PublicTableNameOrOptions extends + | keyof Database["public"]["Tables"] + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + Update: infer U + } + ? U + : never + : PublicTableNameOrOptions extends keyof Database["public"]["Tables"] + ? Database["public"]["Tables"][PublicTableNameOrOptions] extends { + Update: infer U + } + ? U + : never + : never + +export type Enums< + PublicEnumNameOrOptions extends + | keyof Database["public"]["Enums"] + | { schema: keyof Database }, + EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] + : never = never +> = PublicEnumNameOrOptions extends { schema: keyof Database } + ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] + : PublicEnumNameOrOptions extends keyof Database["public"]["Enums"] + ? Database["public"]["Enums"][PublicEnumNameOrOptions] + : never