import { initializeApp, cert } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
import { getFirestore, FieldValue } from 'firebase-admin/firestore';
import path from 'path';
const serviceAccount = require(path.join(__dirname, '../../firebase-credentials.json'));
// Initialize Firebase Admin
const app = initializeApp({
credential: cert(serviceAccount),
});
// Initialize Auth and Firestore
const auth = getAuth(app);
const db = getFirestore(app);
export interface UserRole {
uid: string;
email: string;
role: 'user' | 'ngo_worker' | 'advocate';
name: string;
phoneNumber?: string;
createdAt: Date;
}
export interface Case {
id: string;
userId: string;
advocateId?: string;
status: 'new' | 'assigned' | 'in_progress' | 'resolved';
type: string;
description: string;
createdAt: Date;
updatedAt: Date;
transcripts: string[];
followUps: {
question: string;
answer?: string;
ngoWorkerId: string;
timestamp: Date;
}[];
}
export interface UserHistory {
cases: Case[];
questions: {
text: string;
answer: string;
timestamp: Date;
audioUrl?: string;
}[];
}
class FirebaseService {
// User Management
async createUser(email: string, password: string, role: UserRole['role'], name: string, phoneNumber?: string): Promise<UserRole> {
const userRecord = await auth.createUser({
email,
password,
displayName: name,
phoneNumber,
});
const userData: UserRole = {
uid: userRecord.uid,
email,
role,
name,
phoneNumber,
createdAt: new Date(),
};
await db.collection('users').doc(userRecord.uid).set(userData);
return userData;
}
async getUserRole(uid: string): Promise<UserRole | null> {
const userDoc = await db.collection('users').doc(uid).get();
return userDoc.exists ? (userDoc.data() as UserRole) : null;
}
async getUserByPhone(phoneNumber: string): Promise<UserRole | null> {
const usersSnapshot = await db.collection('users')
.where('phoneNumber', '==', phoneNumber)
.limit(1)
.get();
if (usersSnapshot.empty) {
return null;
}
return usersSnapshot.docs[0].data() as UserRole;
}
async getUserHistory(userId: string): Promise<UserHistory> {
const [casesSnapshot, questionsSnapshot] = await Promise.all([
db.collection('cases')
.where('userId', '==', userId)
.orderBy('createdAt', 'desc')
.get(),
db.collection('questions')
.where('userId', '==', userId)
.orderBy('timestamp', 'desc')
.get(),
]);
return {
cases: casesSnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() } as Case)),
questions: questionsSnapshot.docs.map(doc => doc.data()),
};
}
// Case Management
async createCase(userId: string, type: string, description: string): Promise<Case> {
const caseData: Omit<Case, 'id'> = {
userId,
status: 'new',
type,
description,
createdAt: new Date(),
updatedAt: new Date(),
transcripts: [],
followUps: [],
};
const caseRef = await db.collection('cases').add(caseData);
return { id: caseRef.id, ...caseData };
}
async assignCase(caseId: string, advocateId: string): Promise<void> {
await db.collection('cases').doc(caseId).update({
advocateId,
status: 'assigned',
updatedAt: new Date(),
});
}
async updateCaseStatus(caseId: string, status: Case['status']): Promise<void> {
await db.collection('cases').doc(caseId).update({
status,
updatedAt: new Date(),
});
}
async addTranscript(caseId: string, transcript: string): Promise<void> {
await db.collection('cases').doc(caseId).update({
transcripts: FieldValue.arrayUnion(transcript),
updatedAt: new Date(),
});
}
async addFollowUp(caseId: string, question: string, ngoWorkerId: string): Promise<void> {
const followUp = {
question,
ngoWorkerId,
timestamp: new Date(),
};
await db.collection('cases').doc(caseId).update({
followUps: FieldValue.arrayUnion(followUp),
updatedAt: new Date(),
});
}
// Advocate Dashboard Data
async getAdvocateCases(advocateId: string): Promise<Case[]> {
const casesSnapshot = await db.collection('cases')
.where('advocateId', '==', advocateId)
.orderBy('updatedAt', 'desc')
.get();
return casesSnapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
} as Case));
}
async getAdvocateStats(advocateId: string): Promise<{
totalCases: number;
activeCases: number;
resolvedCases: number;
}> {
const casesSnapshot = await db.collection('cases')
.where('advocateId', '==', advocateId)
.get();
const cases = casesSnapshot.docs.map(doc => doc.data() as Case);
return {
totalCases: cases.length,
activeCases: cases.filter(c => c.status === 'in_progress').length,
resolvedCases: cases.filter(c => c.status === 'resolved').length,
};
}
// NGO Worker Operations
async getUnassignedCases(): Promise<Case[]> {
const casesSnapshot = await db.collection('cases')
.where('status', '==', 'new')
.orderBy('createdAt', 'desc')
.get();
return casesSnapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
} as Case));
}
}
export const firebaseService = new FirebaseService();