# Energy Diagnosis API

Manage DPE certificates (Diagnostic de Performance Energetique) — the mandatory energy performance assessments required for all French rental properties. Track energy ratings, validity, and compliance.

## Quick Example

```bash
curl -X POST https://api.faireplace.com/api/energy-diagnoses \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "place_id": "<place_uuid>",
    "reference_number": "DPE-2024-002",
    "diagnosis_date": "2024-02-10",
    "valid_until": "2034-02-10",
    "energy_label": "B",
    "ges_label": "A",
    "energy_consumption": 125.8,
    "ges_emission": 28.7,
    "heated_area": 65.0,
    "construction_year": 2010,
    "diagnostician_contact_id": "550e8400-e29b-41d4-a716-446655440003",
    "media_id": "550e8400-e29b-41d4-a716-446655440010"
  }'
```

## Common Workflows

### Ensure compliance before leasing
1. `GET /api/places/{place_id}/energy-diagnoses` -- Check if a valid DPE exists
2. `POST /api/energy-diagnoses` -- Upload DPE if missing (specify `place_id` in the body)
3. The DPE rating will appear on the lease document

### Monitor DPE expiration across portfolio
1. `GET /api/energy-diagnoses` -- List all diagnoses (supports filtering by `place_id`, `energy_label`, `ges_label`)
2. Check the `valid_until` field on each diagnosis to identify upcoming expirations
3. Schedule renewal before expiration (DPE valid for 10 years)

---

## Overview

Energy diagnosis management includes:
- **DPE Certificates**: Official energy performance certificates
- **Energy Ratings**: A-G energy efficiency classifications (energy label and GES label)
- **Compliance Tracking**: Mandatory diagnosis requirements
- **Validity Management**: Certificate expiration and renewal
- **Building vs Unit**: Assessments at place level or estate (unit) level

## Authentication

Requires **PropertiesRead**, **PropertiesWrite**, or **PropertiesDelete** permissions.

## Base URL

Energy diagnosis endpoints:
- **Main CRUD**: `/api/energy-diagnoses` and `/api/energy-diagnoses/{id}`
- **By Place**: `/api/places/{place_id}/energy-diagnoses`
- **By Estate**: `/api/places/{place_id}/estates/{estate_id}/energy-diagnoses`

---

## Core Operations

### List All Energy Diagnoses
**GET** `/api/energy-diagnoses`

Supports pagination (`page`, `limit`) and filtering by `place_id`, `estate_id`, `energy_label`, `ges_label`.

**Response:**
```json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "place_id": "550e8400-e29b-41d4-a716-446655440002",
      "estate_id": null,
      "reference_number": "DPE-2024-002",
      "diagnosis_date": "2024-02-10",
      "valid_until": "2034-02-10",
      "energy_label": "B",
      "energy_consumption": 125.8,
      "ges_label": "A",
      "ges_emission": 28.7,
      "heated_area": 65.0,
      "construction_year": 2010,
      "diagnostician_contact_id": "550e8400-e29b-41d4-a716-446655440003",
      "notes": "Apartment with reinforced insulation",
      "media_id": "550e8400-e29b-41d4-a716-446655440010",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 1 }
}
```

### List Energy Diagnoses by Place
**GET** `/api/places/{place_id}/energy-diagnoses`

Returns all diagnoses associated with a specific place.

### Create Energy Diagnosis
**POST** `/api/energy-diagnoses`

Must specify either `place_id` or `estate_id` in the body, but not both.

**Request:**
```json
{
  "place_id": "550e8400-e29b-41d4-a716-446655440002",
  "reference_number": "DPE-2024-002",
  "diagnosis_date": "2024-02-10",
  "valid_until": "2034-02-10",
  "energy_label": "B",
  "ges_label": "A",
  "energy_consumption": 125.8,
  "ges_emission": 28.7,
  "heated_area": 65.0,
  "construction_year": 2010,
  "diagnostician_contact_id": "550e8400-e29b-41d4-a716-446655440003",
  "notes": "Apartment with reinforced insulation",
  "media_id": "550e8400-e29b-41d4-a716-446655440010"
}
```

**Required fields:** `reference_number`, `diagnosis_date`, `valid_until`, `energy_label`, `ges_label`, `construction_year`

### Get Energy Diagnosis
**GET** `/api/energy-diagnoses/{id}`

### Update Energy Diagnosis
**PUT** `/api/energy-diagnoses/{id}`

For optional fields, omitting the field preserves the existing value, sending `null` removes it.

### Delete Energy Diagnosis
**DELETE** `/api/energy-diagnoses/{id}`

---

## Estate-Level Diagnoses

### List Estate Energy Diagnoses
**GET** `/api/places/{place_id}/estates/{estate_id}/energy-diagnoses`

Returns all diagnoses associated with a specific estate (unit) within a place.

---

## Energy Ratings

### Energy Label Scale (EnergyLabel)
- **A**: <= 50 kWh/m2/year (Very efficient)
- **B**: 51-90 kWh/m2/year (Efficient)
- **C**: 91-150 kWh/m2/year (Good)
- **D**: 151-230 kWh/m2/year (Average)
- **E**: 231-330 kWh/m2/year (Poor)
- **F**: 331-420 kWh/m2/year (Very poor)
- **G**: > 420 kWh/m2/year (Extremely poor)

### GES Label Scale (GesLabel) -- Greenhouse Gas Emissions
- **A**: <= 5 kg CO2/m2/year (Very low impact)
- **B**: 6-10 kg CO2/m2/year (Low impact)
- **C**: 11-20 kg CO2/m2/year (Moderate impact)
- **D**: 21-35 kg CO2/m2/year (Average impact)
- **E**: 36-55 kg CO2/m2/year (High impact)
- **F**: 56-80 kg CO2/m2/year (Very high impact)
- **G**: > 80 kg CO2/m2/year (Extremely high impact)

---

## Validation Rules

The following business rules are enforced server-side:

- **Exclusivity**: A DPE must be associated with either a `place_id` or an `estate_id`, but not both. At least one must be provided during creation.
- **Value constraints**: `energy_consumption` >= 0, `ges_emission` >= 0, `heated_area` > 0, `construction_year` between 1800 and the current year.
- **Format constraints**: `reference_number` is 1-100 characters (required), `notes` max 1000 characters, dates in ISO format (YYYY-MM-DD).
- **Temporal constraints**: `valid_until` must be later than `diagnosis_date`, with a maximum validity of 10 years.
- **Label constraints**: `energy_label` and `ges_label` are required and must be one of A, B, C, D, E, F, G.

---

## Error Responses

**400 Bad Request**
```json
{
  "error": "ValidationError",
  "message": "Invalid energy label",
  "details": {
    "valid_labels": ["A", "B", "C", "D", "E", "F", "G"]
  }
}
```

**422 Unprocessable Entity**
```json
{
  "error": "BusinessValidationError",
  "message": "estate_id and place_id cannot both be provided simultaneously"
}
```

---

## Common Use Cases

### Property Marketing
1. Display energy ratings in property listings
2. Highlight energy-efficient properties
3. Provide energy cost estimates to tenants

### Compliance Management
1. Track diagnosis validity dates via the `valid_until` field
2. Schedule renewal reminders
3. Ensure all properties have valid diagnoses

### Energy Performance Tracking
1. Monitor building energy efficiency
2. Track improvements after renovations
3. Compare performance across portfolio

### Legal Requirements
1. Provide mandatory diagnosis for lease agreements
2. Include energy ratings in property advertisements
3. Archive diagnosis certificates for legal compliance

---

## French Legal Requirements

### Mandatory Diagnoses
- **All Rentals**: DPE required for all rental properties
- **Sales**: DPE mandatory for property sales
- **Validity**: 10-year validity period for DPE
- **Display**: Energy rating must be shown in advertisements

### Penalties
- Missing or invalid DPE can result in fines
- Incorrect information can invalidate lease agreements
- Professional liability for diagnosticians

### Recent Changes
- New DPE methodology since July 2021
- Stricter energy consumption calculations
- Enhanced reliability and accuracy requirements

---

## Integration Notes

- **Property Listings**: Energy ratings displayed in marketing materials
- **Lease Compliance**: Automatic validation of diagnosis requirements
- **Renewal Tracking**: Monitor `valid_until` dates for expiring diagnoses
- **Document Storage**: Use `media_id` to link uploaded DPE PDF documents
- **Reporting**: Energy performance analytics and portfolio reporting