perplexity-hackathon-LawMitra / perplexity_hackathon / src / services / firebaseService.ts
firebaseService.ts
Raw
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();