Initial commit
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
import {
|
||||
collection,
|
||||
doc,
|
||||
getDoc,
|
||||
getDocs,
|
||||
setDoc,
|
||||
updateDoc,
|
||||
query,
|
||||
where,
|
||||
orderBy,
|
||||
Timestamp,
|
||||
addDoc,
|
||||
deleteDoc,
|
||||
} from 'firebase/firestore';
|
||||
import { db } from './firebase';
|
||||
import type {
|
||||
User,
|
||||
AgentSettings,
|
||||
CallTask,
|
||||
CallAttempt,
|
||||
CallRecord,
|
||||
CreditTransaction,
|
||||
NotificationSettings,
|
||||
BookedAppointment,
|
||||
DefaultLimits,
|
||||
Purchase,
|
||||
} from './types';
|
||||
|
||||
// Users
|
||||
export const getUser = async (uid: string): Promise<User | null> => {
|
||||
const docRef = doc(db, 'users', uid);
|
||||
const docSnap = await getDoc(docRef);
|
||||
return docSnap.exists() ? (docSnap.data() as User) : null;
|
||||
};
|
||||
|
||||
export const updateUserCredits = async (uid: string, newBalance: number) => {
|
||||
const docRef = doc(db, 'users', uid);
|
||||
await updateDoc(docRef, {
|
||||
creditBalance: newBalance,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
|
||||
export const updateUserOnboardingCompleted = async (uid: string, completed: boolean) => {
|
||||
const docRef = doc(db, 'users', uid);
|
||||
await updateDoc(docRef, {
|
||||
onboardingCompleted: completed,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
|
||||
// Agent Settings
|
||||
export const getAgentSettings = async (userId: string): Promise<AgentSettings | null> => {
|
||||
const docRef = doc(db, 'agentSettings', userId);
|
||||
const docSnap = await getDoc(docRef);
|
||||
if (docSnap.exists()) {
|
||||
return docSnap.data() as AgentSettings;
|
||||
}
|
||||
// Create default if not exists
|
||||
const defaults: AgentSettings = {
|
||||
userId,
|
||||
agentName: 'HolaCompi',
|
||||
appLanguage: 'English',
|
||||
primaryCallLanguage: 'English',
|
||||
secondaryCallLanguages: [],
|
||||
tone: 'Friendly',
|
||||
agentInstructions: 'You are HolaCompi, a helpful Spanish friend who makes phone calls on behalf of users.',
|
||||
createdAt: Timestamp.now(),
|
||||
updatedAt: Timestamp.now(),
|
||||
};
|
||||
await setDoc(docRef, defaults);
|
||||
return defaults;
|
||||
};
|
||||
|
||||
export const updateAgentSettings = async (userId: string, updates: Partial<AgentSettings>) => {
|
||||
const docRef = doc(db, 'agentSettings', userId);
|
||||
await updateDoc(docRef, {
|
||||
...updates,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
|
||||
// Call Tasks
|
||||
export const createCallTask = async (task: Omit<CallTask, 'id'>): Promise<string> => {
|
||||
const docRef = await addDoc(collection(db, 'callTasks'), task);
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const getCallTasks = async (userId: string): Promise<CallTask[]> => {
|
||||
const q = query(
|
||||
collection(db, 'callTasks'),
|
||||
where('userId', '==', userId),
|
||||
orderBy('scheduledAt', 'desc')
|
||||
);
|
||||
const snapshot = await getDocs(q);
|
||||
return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as CallTask));
|
||||
};
|
||||
|
||||
export const getCallTask = async (taskId: string): Promise<CallTask | null> => {
|
||||
const docRef = doc(db, 'callTasks', taskId);
|
||||
const docSnap = await getDoc(docRef);
|
||||
return docSnap.exists() ? ({ id: docSnap.id, ...docSnap.data() } as CallTask) : null;
|
||||
};
|
||||
|
||||
export const updateCallTask = async (taskId: string, updates: Partial<CallTask>) => {
|
||||
const docRef = doc(db, 'callTasks', taskId);
|
||||
await updateDoc(docRef, {
|
||||
...updates,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteCallTask = async (taskId: string) => {
|
||||
await deleteDoc(doc(db, 'callTasks', taskId));
|
||||
};
|
||||
|
||||
// Call Attempts
|
||||
export const createCallAttempt = async (
|
||||
taskId: string,
|
||||
attempt: Omit<CallAttempt, 'id'>
|
||||
): Promise<string> => {
|
||||
const docRef = await addDoc(
|
||||
collection(db, 'callTasks', taskId, 'attempts'),
|
||||
attempt
|
||||
);
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const getCallAttempts = async (taskId: string): Promise<CallAttempt[]> => {
|
||||
const q = query(
|
||||
collection(db, 'callTasks', taskId, 'attempts'),
|
||||
orderBy('startTime', 'desc')
|
||||
);
|
||||
const snapshot = await getDocs(q);
|
||||
return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as CallAttempt));
|
||||
};
|
||||
|
||||
export const updateCallAttempt = async (
|
||||
taskId: string,
|
||||
attemptId: string,
|
||||
updates: Partial<CallAttempt>
|
||||
) => {
|
||||
const docRef = doc(db, 'callTasks', taskId, 'attempts', attemptId);
|
||||
await updateDoc(docRef, updates);
|
||||
};
|
||||
|
||||
// Calls
|
||||
export const createCallRecord = async (
|
||||
record: Omit<CallRecord, 'id' | 'createdAt' | 'updatedAt'>
|
||||
): Promise<string> => {
|
||||
const docRef = await addDoc(collection(db, 'calls'), {
|
||||
...record,
|
||||
createdAt: Timestamp.now(),
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const updateCallRecord = async (
|
||||
callId: string,
|
||||
updates: Partial<CallRecord>
|
||||
) => {
|
||||
const docRef = doc(db, 'calls', callId);
|
||||
await updateDoc(docRef, { ...updates, updatedAt: Timestamp.now() });
|
||||
};
|
||||
|
||||
export const getCallByVapiCallId = async (vapiCallId: string): Promise<CallRecord | null> => {
|
||||
const q = query(collection(db, 'calls'), where('vapiCallId', '==', vapiCallId));
|
||||
const snapshot = await getDocs(q);
|
||||
if (snapshot.empty) return null;
|
||||
const docSnap = snapshot.docs[0];
|
||||
return { id: docSnap.id, ...(docSnap.data() as CallRecord) };
|
||||
};
|
||||
|
||||
// Credit Transactions
|
||||
export const createCreditTransaction = async (
|
||||
transaction: Omit<CreditTransaction, 'id'>
|
||||
): Promise<string> => {
|
||||
const docRef = await addDoc(collection(db, 'creditLedger'), transaction);
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const getCreditTransactions = async (userId: string): Promise<CreditTransaction[]> => {
|
||||
const q = query(
|
||||
collection(db, 'creditLedger'),
|
||||
where('userId', '==', userId),
|
||||
orderBy('createdAt', 'desc')
|
||||
);
|
||||
const snapshot = await getDocs(q);
|
||||
return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as CreditTransaction));
|
||||
};
|
||||
|
||||
// Purchases
|
||||
export const createPurchase = async (purchase: Omit<Purchase, 'id'>): Promise<string> => {
|
||||
const docRef = await addDoc(collection(db, 'purchases'), purchase);
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const getPurchasesByUser = async (userId: string): Promise<Purchase[]> => {
|
||||
const q = query(
|
||||
collection(db, 'purchases'),
|
||||
where('userId', '==', userId),
|
||||
orderBy('createdAt', 'desc')
|
||||
);
|
||||
const snapshot = await getDocs(q);
|
||||
return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as Purchase));
|
||||
};
|
||||
|
||||
// Notification Settings
|
||||
export const getNotificationSettings = async (userId: string): Promise<NotificationSettings> => {
|
||||
const docRef = doc(db, 'notificationSettings', userId);
|
||||
const docSnap = await getDoc(docRef);
|
||||
if (docSnap.exists()) {
|
||||
return docSnap.data() as NotificationSettings;
|
||||
}
|
||||
const defaults: NotificationSettings = {
|
||||
userId,
|
||||
notifyOnSuccess: true,
|
||||
notifyOnFailure: true,
|
||||
emailSummary: false,
|
||||
autoAddToCalendar: false,
|
||||
googleCalendarConnected: false,
|
||||
iCloudCalendarConnected: false,
|
||||
createdAt: Timestamp.now(),
|
||||
updatedAt: Timestamp.now(),
|
||||
};
|
||||
await setDoc(docRef, defaults);
|
||||
return defaults;
|
||||
};
|
||||
|
||||
export const updateNotificationSettings = async (
|
||||
userId: string,
|
||||
updates: Partial<NotificationSettings>
|
||||
) => {
|
||||
const docRef = doc(db, 'notificationSettings', userId);
|
||||
await updateDoc(docRef, {
|
||||
...updates,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
|
||||
// Booked Appointments
|
||||
export const createBookedAppointment = async (
|
||||
appointment: Omit<BookedAppointment, 'id'>
|
||||
): Promise<string> => {
|
||||
const docRef = await addDoc(collection(db, 'bookedAppointments'), appointment);
|
||||
return docRef.id;
|
||||
};
|
||||
|
||||
export const getBookedAppointments = async (userId: string): Promise<BookedAppointment[]> => {
|
||||
const q = query(
|
||||
collection(db, 'bookedAppointments'),
|
||||
where('userId', '==', userId),
|
||||
orderBy('dateTime', 'asc')
|
||||
);
|
||||
const snapshot = await getDocs(q);
|
||||
return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() } as BookedAppointment));
|
||||
};
|
||||
|
||||
// Default Limits
|
||||
export const getDefaultLimits = async (userId: string): Promise<DefaultLimits> => {
|
||||
const docRef = doc(db, 'defaultLimits', userId);
|
||||
const docSnap = await getDoc(docRef);
|
||||
if (docSnap.exists()) {
|
||||
return docSnap.data() as DefaultLimits;
|
||||
}
|
||||
const defaults: DefaultLimits = {
|
||||
userId,
|
||||
defaultMaxMinutes: 10,
|
||||
defaultMaxCredits: 10,
|
||||
allowAutoExtension: false,
|
||||
maxExtraMinutes: 0,
|
||||
defaultMaxRecalls: 2,
|
||||
minDelayBetweenRecalls: 15,
|
||||
updatedAt: Timestamp.now(),
|
||||
};
|
||||
await setDoc(docRef, defaults);
|
||||
return defaults;
|
||||
};
|
||||
|
||||
export const updateDefaultLimits = async (userId: string, updates: Partial<DefaultLimits>) => {
|
||||
const docRef = doc(db, 'defaultLimits', userId);
|
||||
await updateDoc(docRef, {
|
||||
...updates,
|
||||
updatedAt: Timestamp.now(),
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user