# Procedure Aggregation Service (Admin)

This service centralizes the logic for updating aggregated data in various Firestore collections _when a procedure is created, updated, or deleted/inactivated_. It is designed primarily for use by Cloud Functions triggered by changes in the `procedures` collection.

## `ProcedureAggregationService` Class

### Constructor

```typescript
constructor(firestore?: admin.firestore.Firestore)
```

Initializes the service with an Admin Firestore instance. Uses the default instance if none is provided.

### Methods Triggered by Procedure **Creation**

- **`addProcedureToPractitioner(practitionerId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>`**
  - Adds the `procedureId` (from `procedureSummary.id`) and the `procedureSummary` object to the `procedureIds` and `proceduresInfo` arrays respectively in the specified `Practitioner` document.
- **`addProcedureToClinic(clinicId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>`**
  - Adds the `procedureId` (from `procedureSummary.id`) and the `procedureSummary` object to the `procedures` and `proceduresInfo` arrays respectively in the specified `Clinic` document.

### Methods Triggered by Procedure **Update**

- **`updateProcedureInfoInPractitioner(practitionerId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>`**
  - Updates the `proceduresInfo` array within the specified `Practitioner` document.
  - Uses a transaction to read the existing array, filter out the old summary (matching by `id`), add the updated `procedureSummary`, and write the modified array back. This prevents race conditions.
- **`updateProcedureInfoInClinic(clinicId: string, procedureSummary: ProcedureSummaryInfo): Promise<void>`**
  - Updates the `proceduresInfo` array within the specified `Clinic` document using the same transaction-based read-modify-write pattern as above.
- **`updateProcedureInfoInCalendarEvents(procedureId: string, procedureInfo: any): Promise<void>`**
  - Uses a Collection Group query (`calendar` subcollection) to find all _upcoming_ calendar events associated with the `procedureId`.
  - Updates the embedded `procedureInfo` object in these calendar events with the provided `procedureInfo`.

### Methods Triggered by Procedure **Deletion / Deactivation**

- **`cancelUpcomingCalendarEventsForProcedure(procedureId: string): Promise<void>`**
  - Uses a Collection Group query (`calendar` subcollection) to find all _upcoming_ calendar events associated with the `procedureId`.
  - Sets the `status` of these events to `CANCELED` and adds a `cancelReason` ("Procedure deleted or inactivated").
- **`removeProcedureFromPractitioner(practitionerId: string, procedureId: string): Promise<void>`**
  - Removes the `procedureId` from the `procedureIds` array and the corresponding `ProcedureSummaryInfo` object (matching by `id`) from the `proceduresInfo` array in the specified `Practitioner` document.
  - Uses a transaction-based read-modify-write pattern.
- **`removeProcedureFromClinic(clinicId: string, procedureId: string): Promise<void>`**
  - Removes the `procedureId` from the `procedures` array and the corresponding `ProcedureSummaryInfo` object (matching by `id`) from the `proceduresInfo` array in the specified `Clinic` document.
  - Uses a transaction-based read-modify-write pattern.
