service refactor to namespaces

This commit is contained in:
Michael Dausmann
2024-02-17 10:49:23 +11:00
parent d8f20d9896
commit 23c248a08b
10 changed files with 80 additions and 90 deletions

View File

@@ -14,15 +14,17 @@ import { AccountLimitError } from './errors';
const config = useRuntimeConfig(); const config = useRuntimeConfig();
export default class AccountService { export namespace AccountService {
async getAccountById(account_id: number): Promise<AccountWithMembers> { export async function getAccountById(
account_id: number
): Promise<AccountWithMembers> {
return prisma_client.account.findFirstOrThrow({ return prisma_client.account.findFirstOrThrow({
where: { id: account_id }, where: { id: account_id },
...accountWithMembers ...accountWithMembers
}); });
} }
async getAccountByJoinPassword( export async function getAccountByJoinPassword(
join_password: string join_password: string
): Promise<AccountWithMembers> { ): Promise<AccountWithMembers> {
return prisma_client.account.findFirstOrThrow({ return prisma_client.account.findFirstOrThrow({
@@ -31,14 +33,16 @@ export default class AccountService {
}); });
} }
async getAccountMembers(account_id: number): Promise<MembershipWithUser[]> { export async function getAccountMembers(
account_id: number
): Promise<MembershipWithUser[]> {
return prisma_client.membership.findMany({ return prisma_client.membership.findMany({
where: { account_id }, where: { account_id },
...membershipWithUser ...membershipWithUser
}); });
} }
async updateAccountStipeCustomerId( export async function updateAccountStipeCustomerId(
account_id: number, account_id: number,
stripe_customer_id: string stripe_customer_id: string
) { ) {
@@ -50,7 +54,7 @@ export default class AccountService {
}); });
} }
async updateStripeSubscriptionDetailsForAccount( export async function updateStripeSubscriptionDetailsForAccount(
stripe_customer_id: string, stripe_customer_id: string,
stripe_subscription_id: string, stripe_subscription_id: string,
current_period_ends: Date, current_period_ends: Date,
@@ -93,7 +97,7 @@ export default class AccountService {
} }
} }
async acceptPendingMembership( export async function acceptPendingMembership(
account_id: number, account_id: number,
membership_id: number membership_id: number
): Promise<MembershipWithAccount> { ): Promise<MembershipWithAccount> {
@@ -118,7 +122,7 @@ export default class AccountService {
}); });
} }
async deleteMembership( export async function deleteMembership(
account_id: number, account_id: number,
membership_id: number membership_id: number
): Promise<MembershipWithAccount> { ): Promise<MembershipWithAccount> {
@@ -140,7 +144,7 @@ export default class AccountService {
}); });
} }
async joinUserToAccount( export async function joinUserToAccount(
user_id: number, user_id: number,
account_id: number, account_id: number,
pending: boolean pending: boolean
@@ -179,7 +183,10 @@ export default class AccountService {
}); });
} }
async changeAccountName(account_id: number, new_name: string) { export async function changeAccountName(
account_id: number,
new_name: string
) {
return prisma_client.account.update({ return prisma_client.account.update({
where: { id: account_id }, where: { id: account_id },
data: { data: {
@@ -188,7 +195,7 @@ export default class AccountService {
}); });
} }
async changeAccountPlan(account_id: number, plan_id: number) { export async function changeAccountPlan(account_id: number, plan_id: number) {
const plan = await prisma_client.plan.findFirstOrThrow({ const plan = await prisma_client.plan.findFirstOrThrow({
where: { id: plan_id } where: { id: plan_id }
}); });
@@ -202,7 +209,7 @@ export default class AccountService {
}); });
} }
async rotateJoinPassword(account_id: number) { export async function rotateJoinPassword(account_id: number) {
const join_password: string = generator.generate({ const join_password: string = generator.generate({
length: 10, length: 10,
numbers: true numbers: true
@@ -217,7 +224,7 @@ export default class AccountService {
// User must already be an ADMIN for the Account // User must already be an ADMIN for the Account
// Existing OWNER memberships are downgraded to ADMIN // Existing OWNER memberships are downgraded to ADMIN
// In future, some sort of Billing/Stripe tie in here e.g. changing email details on the Account, not sure. // In future, some sort of Billing/Stripe tie in here e.g. changing email details on the Account, not sure.
async claimOwnershipOfAccount( export async function claimOwnershipOfAccount(
user_id: number, user_id: number,
account_id: number account_id: number
): Promise<MembershipWithUser[]> { ): Promise<MembershipWithUser[]> {
@@ -278,7 +285,7 @@ export default class AccountService {
} }
// Upgrade access of a membership. Cannot use this method to upgrade to or downgrade from OWNER access // Upgrade access of a membership. Cannot use this method to upgrade to or downgrade from OWNER access
async changeUserAccessWithinAccount( export async function changeUserAccessWithinAccount(
user_id: number, user_id: number,
account_id: number, account_id: number,
access: ACCOUNT_ACCESS access: ACCOUNT_ACCESS
@@ -333,15 +340,14 @@ export default class AccountService {
Note.. for each usage limit, you will need another pair of check/increment methods and of course the count and max limit in the account schema Note.. for each usage limit, you will need another pair of check/increment methods and of course the count and max limit in the account schema
How to use in a service method.... How to use in a service method....
async someServiceMethod(account_id: number, .....etc) { export async function someServiceMethod(account_id: number, .....etc) {
const accountService = new AccountService(); const account = await AccountService.checkAIGenCount(account_id);
const account = await accountService.checkAIGenCount(account_id);
... User is under the limit so do work ... User is under the limit so do work
await accountService.incrementAIGenCount(account); await AccountService.incrementAIGenCount(account);
} }
*/ */
async getAccountWithPeriodRollover(account_id: number) { export async function getAccountWithPeriodRollover(account_id: number) {
const account = await prisma_client.account.findFirstOrThrow({ const account = await prisma_client.account.findFirstOrThrow({
where: { id: account_id } where: { id: account_id }
}); });
@@ -366,8 +372,8 @@ export default class AccountService {
return account; return account;
} }
async checkAIGenCount(account_id: number) { export async function checkAIGenCount(account_id: number) {
const account = await this.getAccountWithPeriodRollover(account_id); const account = await getAccountWithPeriodRollover(account_id);
if (account.ai_gen_count >= account.ai_gen_max_pm) { if (account.ai_gen_count >= account.ai_gen_max_pm) {
throw new AccountLimitError( throw new AccountLimitError(
@@ -378,7 +384,7 @@ export default class AccountService {
return account; return account;
} }
async incrementAIGenCount(account: any) { export async function incrementAIGenCount(account: any) {
return await prisma_client.account.update({ return await prisma_client.account.update({
where: { id: account.id }, where: { id: account.id },
data: { data: {

View File

@@ -6,8 +6,8 @@ import generator from 'generate-password-ts';
const config = useRuntimeConfig(); const config = useRuntimeConfig();
export default class AuthService { export namespace AuthService {
async getFullUserBySupabaseId( export async function getFullUserBySupabaseId(
supabase_uid: string supabase_uid: string
): Promise<FullDBUser | null> { ): Promise<FullDBUser | null> {
return prisma_client.user.findFirst({ return prisma_client.user.findFirst({
@@ -16,14 +16,16 @@ export default class AuthService {
}); });
} }
async getUserById(user_id: number): Promise<FullDBUser | null> { export async function getUserById(
user_id: number
): Promise<FullDBUser | null> {
return prisma_client.user.findFirstOrThrow({ return prisma_client.user.findFirstOrThrow({
where: { id: user_id }, where: { id: user_id },
...fullDBUser ...fullDBUser
}); });
} }
async createUser( export async function createUser(
supabase_uid: string, supabase_uid: string,
display_name: string, display_name: string,
email: string email: string
@@ -65,7 +67,7 @@ export default class AuthService {
}); });
} }
async deleteUser(user_id: number): Promise<FullDBUser> { export async function deleteUser(user_id: number): Promise<FullDBUser> {
return prisma_client.user.delete({ return prisma_client.user.delete({
where: { id: user_id }, where: { id: user_id },
...fullDBUser ...fullDBUser

View File

@@ -1,22 +1,22 @@
import prisma_client from '~~/prisma/prisma.client'; import prisma_client from '~~/prisma/prisma.client';
import { openai } from './openai.client'; import { openai } from './openai.client';
import { AccountLimitError } from './errors'; import { AccountLimitError } from './errors';
import AccountService from './account.service'; import { AccountService } from './account.service';
export default class NotesService { export namespace NotesService {
async getAllNotes() { export async function getAllNotes() {
return prisma_client.note.findMany(); return prisma_client.note.findMany();
} }
async getNoteById(id: number) { export async function getNoteById(id: number) {
return prisma_client.note.findUniqueOrThrow({ where: { id } }); return prisma_client.note.findUniqueOrThrow({ where: { id } });
} }
async getNotesForAccountId(account_id: number) { export async function getNotesForAccountId(account_id: number) {
return prisma_client.note.findMany({ where: { account_id } }); return prisma_client.note.findMany({ where: { account_id } });
} }
async createNote(account_id: number, note_text: string) { export async function createNote(account_id: number, note_text: string) {
const account = await prisma_client.account.findFirstOrThrow({ const account = await prisma_client.account.findFirstOrThrow({
where: { id: account_id }, where: { id: account_id },
include: { notes: true } include: { notes: true }
@@ -31,17 +31,19 @@ export default class NotesService {
return prisma_client.note.create({ data: { account_id, note_text } }); return prisma_client.note.create({ data: { account_id, note_text } });
} }
async updateNote(id: number, note_text: string) { export async function updateNote(id: number, note_text: string) {
return prisma_client.note.update({ where: { id }, data: { note_text } }); return prisma_client.note.update({ where: { id }, data: { note_text } });
} }
async deleteNote(id: number) { export async function deleteNote(id: number) {
return prisma_client.note.delete({ where: { id } }); return prisma_client.note.delete({ where: { id } });
} }
async generateAINoteFromPrompt(userPrompt: string, account_id: number) { export async function generateAINoteFromPrompt(
const accountService = new AccountService(); userPrompt: string,
const account = await accountService.checkAIGenCount(account_id); account_id: number
) {
const account = await AccountService.checkAIGenCount(account_id);
const prompt = ` const prompt = `
Write an interesting short note about ${userPrompt}. Write an interesting short note about ${userPrompt}.
@@ -56,7 +58,7 @@ export default class NotesService {
n: 1 n: 1
}); });
await accountService.incrementAIGenCount(account); await AccountService.incrementAIGenCount(account);
return completion.data.choices[0].text; return completion.data.choices[0].text;
} }

View File

@@ -1,5 +1,5 @@
export class UtilService { export namespace UtilService {
public static addMonths(date: Date, months: number): Date { export function addMonths(date: Date, months: number): Date {
const d = date.getDate(); const d = date.getDate();
date.setMonth(date.getMonth() + +months); date.setMonth(date.getMonth() + +months);
if (date.getDate() != d) { if (date.getDate() != d) {
@@ -8,12 +8,12 @@ export class UtilService {
return date; return date;
} }
public static getErrorMessage(error: unknown) { export function getErrorMessage(error: unknown) {
if (error instanceof Error) return error.message; if (error instanceof Error) return error.message;
return String(error); return String(error);
} }
public static stringifySafely(obj: any) { export function stringifySafely(obj: any) {
let cache: any[] = []; let cache: any[] = [];
let str = JSON.stringify(obj, function (key, value) { let str = JSON.stringify(obj, function (key, value) {
if (typeof value === 'object' && value !== null) { if (typeof value === 'object' && value !== null) {

View File

@@ -1,6 +1,6 @@
import { H3Event, getQuery } from 'h3'; import { H3Event, getQuery } from 'h3';
import { defineProtectedEventHandler } from '../defineProtectedEventHandler'; import { defineProtectedEventHandler } from '../defineProtectedEventHandler';
import NotesService from '~/lib/services/notes.service'; import { NotesService } from '~/lib/services/notes.service';
// Example API Route with query params ... /api/note?note_id=41 // Example API Route with query params ... /api/note?note_id=41
export default defineProtectedEventHandler(async (event: H3Event) => { export default defineProtectedEventHandler(async (event: H3Event) => {
@@ -14,8 +14,7 @@ export default defineProtectedEventHandler(async (event: H3Event) => {
} }
} }
const notesService = new NotesService(); const note = await NotesService.getNoteById(+note_id);
const note = await notesService.getNoteById(+note_id);
return { return {
note note

View File

@@ -1,6 +1,6 @@
import { defineEventHandler, parseCookies, setCookie, getCookie } from 'h3'; import { defineEventHandler, parseCookies, setCookie, getCookie } from 'h3';
import { serverSupabaseUser } from '#supabase/server'; import { serverSupabaseUser } from '#supabase/server';
import AuthService from '~/lib/services/auth.service'; import { AuthService } from '~/lib/services/auth.service';
import { User } from '@supabase/supabase-js'; import { User } from '@supabase/supabase-js';
import { FullDBUser } from '~~/lib/services/service.types'; import { FullDBUser } from '~~/lib/services/service.types';
@@ -27,11 +27,10 @@ export default defineEventHandler(async event => {
if (user) { if (user) {
event.context.user = user; event.context.user = user;
const authService = new AuthService(); let dbUser = await AuthService.getFullUserBySupabaseId(user.id);
let dbUser = await authService.getFullUserBySupabaseId(user.id);
if (!dbUser && user) { if (!dbUser && user) {
dbUser = await authService.createUser( dbUser = await AuthService.createUser(
user.id, user.id,
user.user_metadata.full_name user.user_metadata.full_name
? user.user_metadata.full_name ? user.user_metadata.full_name

View File

@@ -1,6 +1,6 @@
import { ACCOUNT_ACCESS } from '~~/prisma/account-access-enum'; import { ACCOUNT_ACCESS } from '~~/prisma/account-access-enum';
import Stripe from 'stripe'; import Stripe from 'stripe';
import AccountService from '~~/lib/services/account.service'; import { AccountService } from '~~/lib/services/account.service';
import { AccountWithMembers } from '~~/lib/services/service.types'; import { AccountWithMembers } from '~~/lib/services/service.types';
const config = useRuntimeConfig(); const config = useRuntimeConfig();
@@ -14,8 +14,7 @@ export default defineEventHandler(async event => {
`session.post.ts recieved price_id:${price_id}, account_id:${account_id}` `session.post.ts recieved price_id:${price_id}, account_id:${account_id}`
); );
const accountService = new AccountService(); const account: AccountWithMembers = await AccountService.getAccountById(
const account: AccountWithMembers = await accountService.getAccountById(
account_id account_id
); );
let customer_id: string; let customer_id: string;
@@ -32,7 +31,7 @@ export default defineEventHandler(async event => {
email: owner?.user.email email: owner?.user.email
}); });
customer_id = customer.id; customer_id = customer.id;
accountService.updateAccountStipeCustomerId(account_id, customer.id); AccountService.updateAccountStipeCustomerId(account_id, customer.id);
} else { } else {
customer_id = account.stripe_customer_id; customer_id = account.stripe_customer_id;
} }

View File

@@ -1,5 +1,5 @@
import Stripe from 'stripe'; import Stripe from 'stripe';
import AccountService from '~~/lib/services/account.service'; import { AccountService } from '~~/lib/services/account.service';
const config = useRuntimeConfig(); const config = useRuntimeConfig();
const stripe = new Stripe(config.stripeSecretKey, { apiVersion: '2022-11-15' }); const stripe = new Stripe(config.stripeSecretKey, { apiVersion: '2022-11-15' });
@@ -56,8 +56,6 @@ export default defineEventHandler(async event => {
}); });
} }
const accountService = new AccountService();
let current_period_ends: Date = new Date( let current_period_ends: Date = new Date(
subscription.current_period_end * 1000 subscription.current_period_end * 1000
); );
@@ -68,7 +66,7 @@ export default defineEventHandler(async event => {
console.log( console.log(
`updating stripe sub details subscription.current_period_end:${subscription.current_period_end}, subscription.id:${subscription.id}, stripe_product_id:${stripe_product_id}` `updating stripe sub details subscription.current_period_end:${subscription.current_period_end}, subscription.id:${subscription.id}, stripe_product_id:${stripe_product_id}`
); );
accountService.updateStripeSubscriptionDetailsForAccount( AccountService.updateStripeSubscriptionDetailsForAccount(
subscription.customer.toString(), subscription.customer.toString(),
subscription.id, subscription.id,
current_period_ends, current_period_ends,

View File

@@ -8,7 +8,7 @@ import {
} from '../trpc'; } from '../trpc';
import { ACCOUNT_ACCESS } from '~~/prisma/account-access-enum'; import { ACCOUNT_ACCESS } from '~~/prisma/account-access-enum';
import { z } from 'zod'; import { z } from 'zod';
import AccountService from '~~/lib/services/account.service'; import { AccountService } from '~~/lib/services/account.service';
import { MembershipWithAccount } from '~~/lib/services/service.types'; import { MembershipWithAccount } from '~~/lib/services/service.types';
/* /*
@@ -48,8 +48,7 @@ export const accountRouter = router({
changeAccountName: adminProcedure changeAccountName: adminProcedure
.input(z.object({ new_name: z.string() })) .input(z.object({ new_name: z.string() }))
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const accountService = new AccountService(); const account = await AccountService.changeAccountName(
const account = await accountService.changeAccountName(
ctx.activeAccountId!, ctx.activeAccountId!,
input.new_name input.new_name
); );
@@ -58,8 +57,7 @@ export const accountRouter = router({
}; };
}), }),
rotateJoinPassword: adminProcedure.mutation(async ({ ctx }) => { rotateJoinPassword: adminProcedure.mutation(async ({ ctx }) => {
const accountService = new AccountService(); const account = await AccountService.rotateJoinPassword(
const account = await accountService.rotateJoinPassword(
ctx.activeAccountId! ctx.activeAccountId!
); );
return { return {
@@ -69,8 +67,7 @@ export const accountRouter = router({
getAccountByJoinPassword: publicProcedure getAccountByJoinPassword: publicProcedure
.input(z.object({ join_password: z.string() })) .input(z.object({ join_password: z.string() }))
.query(async ({ input }) => { .query(async ({ input }) => {
const accountService = new AccountService(); const account = await AccountService.getAccountByJoinPassword(
const account = await accountService.getAccountByJoinPassword(
input.join_password input.join_password
); );
return { return {
@@ -80,9 +77,8 @@ export const accountRouter = router({
joinUserToAccountPending: publicProcedure // this uses a passed account id rather than using the active account because user is usually active on their personal or some other account when they attempt to join a new account joinUserToAccountPending: publicProcedure // this uses a passed account id rather than using the active account because user is usually active on their personal or some other account when they attempt to join a new account
.input(z.object({ account_id: z.number(), user_id: z.number() })) .input(z.object({ account_id: z.number(), user_id: z.number() }))
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
const accountService = new AccountService();
const membership: MembershipWithAccount = const membership: MembershipWithAccount =
await accountService.joinUserToAccount( await AccountService.joinUserToAccount(
input.user_id, input.user_id,
input.account_id, input.account_id,
true true
@@ -94,9 +90,8 @@ export const accountRouter = router({
acceptPendingMembership: adminProcedure acceptPendingMembership: adminProcedure
.input(z.object({ membership_id: z.number() })) .input(z.object({ membership_id: z.number() }))
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const accountService = new AccountService();
const membership: MembershipWithAccount = const membership: MembershipWithAccount =
await accountService.acceptPendingMembership( await AccountService.acceptPendingMembership(
ctx.activeAccountId!, ctx.activeAccountId!,
input.membership_id input.membership_id
); );
@@ -107,9 +102,8 @@ export const accountRouter = router({
rejectPendingMembership: adminProcedure rejectPendingMembership: adminProcedure
.input(z.object({ membership_id: z.number() })) .input(z.object({ membership_id: z.number() }))
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const accountService = new AccountService();
const membership: MembershipWithAccount = const membership: MembershipWithAccount =
await accountService.deleteMembership( await AccountService.deleteMembership(
ctx.activeAccountId!, ctx.activeAccountId!,
input.membership_id input.membership_id
); );
@@ -120,9 +114,8 @@ export const accountRouter = router({
deleteMembership: ownerProcedure deleteMembership: ownerProcedure
.input(z.object({ membership_id: z.number() })) .input(z.object({ membership_id: z.number() }))
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const accountService = new AccountService();
const membership: MembershipWithAccount = const membership: MembershipWithAccount =
await accountService.deleteMembership( await AccountService.deleteMembership(
ctx.activeAccountId!, ctx.activeAccountId!,
input.membership_id input.membership_id
); );
@@ -143,8 +136,7 @@ export const accountRouter = router({
}) })
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const accountService = new AccountService(); const membership = await AccountService.changeUserAccessWithinAccount(
const membership = await accountService.changeUserAccessWithinAccount(
input.user_id, input.user_id,
ctx.activeAccountId!, ctx.activeAccountId!,
input.access input.access
@@ -154,8 +146,7 @@ export const accountRouter = router({
}; };
}), }),
claimOwnershipOfAccount: adminProcedure.mutation(async ({ ctx }) => { claimOwnershipOfAccount: adminProcedure.mutation(async ({ ctx }) => {
const accountService = new AccountService(); const memberships = await AccountService.claimOwnershipOfAccount(
const memberships = await accountService.claimOwnershipOfAccount(
ctx.dbUser!.id, ctx.dbUser!.id,
ctx.activeAccountId! ctx.activeAccountId!
); );
@@ -164,8 +155,7 @@ export const accountRouter = router({
}; };
}), }),
getAccountMembers: adminProcedure.query(async ({ ctx }) => { getAccountMembers: adminProcedure.query(async ({ ctx }) => {
const accountService = new AccountService(); const memberships = await AccountService.getAccountMembers(
const memberships = await accountService.getAccountMembers(
ctx.activeAccountId! ctx.activeAccountId!
); );
return { return {

View File

@@ -1,4 +1,4 @@
import NotesService from '~~/lib/services/notes.service'; import { NotesService } from '~~/lib/services/notes.service';
import { import {
accountHasSpecialFeature, accountHasSpecialFeature,
adminProcedure, adminProcedure,
@@ -11,9 +11,8 @@ import { z } from 'zod';
export const notesRouter = router({ export const notesRouter = router({
getForActiveAccount: memberProcedure.query(async ({ ctx, input }) => { getForActiveAccount: memberProcedure.query(async ({ ctx, input }) => {
const notesService = new NotesService();
const notes = ctx.activeAccountId const notes = ctx.activeAccountId
? await notesService.getNotesForAccountId(ctx.activeAccountId) ? await NotesService.getNotesForAccountId(ctx.activeAccountId)
: []; : [];
return { return {
notes notes
@@ -22,8 +21,7 @@ export const notesRouter = router({
getById: publicProcedure getById: publicProcedure
.input(z.object({ note_id: z.number() })) .input(z.object({ note_id: z.number() }))
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const notesService = new NotesService(); const note = await NotesService.getNoteById(input.note_id);
const note = await notesService.getNoteById(input.note_id);
return { return {
note note
}; };
@@ -31,9 +29,8 @@ export const notesRouter = router({
createNote: readWriteProcedure createNote: readWriteProcedure
.input(z.object({ note_text: z.string() })) .input(z.object({ note_text: z.string() }))
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const notesService = new NotesService();
const note = ctx.activeAccountId const note = ctx.activeAccountId
? await notesService.createNote(ctx.activeAccountId, input.note_text) ? await NotesService.createNote(ctx.activeAccountId, input.note_text)
: null; : null;
return { return {
note note
@@ -42,9 +39,8 @@ export const notesRouter = router({
deleteNote: adminProcedure deleteNote: adminProcedure
.input(z.object({ note_id: z.number() })) .input(z.object({ note_id: z.number() }))
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const notesService = new NotesService();
const note = ctx.activeAccountId const note = ctx.activeAccountId
? await notesService.deleteNote(input.note_id) ? await NotesService.deleteNote(input.note_id)
: null; : null;
return { return {
note note
@@ -54,9 +50,8 @@ export const notesRouter = router({
.use(accountHasSpecialFeature) .use(accountHasSpecialFeature)
.input(z.object({ user_prompt: z.string() })) .input(z.object({ user_prompt: z.string() }))
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const notesService = new NotesService();
const noteText = ctx.activeAccountId const noteText = ctx.activeAccountId
? await notesService.generateAINoteFromPrompt( ? await NotesService.generateAINoteFromPrompt(
input.user_prompt, input.user_prompt,
ctx.activeAccountId ctx.activeAccountId
) )