# Internal API Reference

**Purpose:** Prevent guessing function signatures and module exports.

Last updated: 2026-03-28

---

## goal_utils.py

### Focus Area Functions

```python
def get_focus_weights(conn, profile_id: str) -> Dict[str, float]
```
Returns user's focus area weights as `{area_key: weight_percent}`.
Keys are **English** (weight_loss, muscle_gain, etc.).

```python
def get_focus_weights_v2(conn, profile_id: str) -> Dict[str, float]
```
Newer version with auto-normalization. Use this for new code.

```python
def get_primary_focus(conn, profile_id: str) -> str
```
Returns area_key of highest weighted focus area.

```python
def get_focus_description(focus_area: str) -> str
```
Returns German description for a focus area key.

---

### Goal Functions

```python
def get_active_goals(profile_id: str) -> List[Dict]
```
Returns ALL active goals for a profile.
Each dict has: id, type_key, current_value, target_value, is_primary, etc.

**To filter by type:**
```python
goals = get_active_goals(profile_id)
weight_goals = [g for g in goals if g.get('type_key') == 'weight']
```

```python
def get_goal_by_id(goal_id: str) -> Optional[Dict]
```
Returns single goal by UUID.

```python
def get_goal_type_config(conn, type_key: str) -> Optional[Dict[str, Any]]
```
Returns goal type metadata from `goal_type_definitions` table:
- source_table, source_column, aggregation_method, unit

```python
def get_current_value_for_goal(conn, profile_id: str, goal_type: str) -> Optional[float]
```
Calculates current value for a goal type using its aggregation method.

---

### Aggregation Functions

```python
def calculate_current_value(
    profile_id: str,
    table: str,
    column: str,
    method: str,
    date_column: str = 'date',
    filter_conditions: Optional[List[Tuple[str, Any]]] = None
) -> Optional[float]
```

**Available methods:**
- `latest` - Most recent value
- `avg_7d` - 7-day average (numeric values only)
- `avg_30d` - 30-day average
- `max_30d` - Maximum in 30 days
- `avg_per_week_30d` - Count per week over 30 days (for frequency tracking)

**Filter conditions format:**
```python
[("training_type", "strength"), ("quality", "good")]
```

---

## calculations/body_metrics.py

### Score Functions

```python
def calculate_body_progress_score(profile_id: str, focus_weights: Dict[str, float] = None) -> Optional[int]
```
Returns 0-100 score for body composition progress.
Weighted by focus areas: weight_loss, muscle_gain, body_recomposition.

**Sub-functions (private):**
- `_score_weight_trend(profile_id)` - Alignment with weight goal
- `_score_body_composition(profile_id)` - BF% + lean mass progress

---

## calculations/nutrition_metrics.py

### Score Functions

```python
def calculate_nutrition_score(profile_id: str, focus_weights: Dict[str, float] = None) -> Optional[int]
```
Returns 0-100 score for nutrition adherence.
Weighted by: protein_intake, calorie_balance, macro_consistency, meal_timing, hydration.

**Sub-functions (private):**
- `_score_calorie_adherence(profile_id)` - Energy balance vs goal
- `_score_protein_adequacy(profile_id)` - Protein target adherence

---

## calculations/activity_metrics.py

### Score Functions

```python
def calculate_activity_score(profile_id: str, focus_weights: Dict[str, float] = None) -> Optional[int]
```
Returns 0-100 score for training quality.
Weighted by: strength, endurance (aerobic+anaerobic+cardiovascular), mobility/coordination.

**Sub-functions (private):**
- `_score_training_quality(profile_id)` - Session quality %
- `_score_training_consistency(profile_id)` - Frequency adherence

---

## calculations/scores.py

### Main Score Aggregator

```python
def calculate_goal_progress_score(profile_id: str) -> Optional[int]
```
Master score aggregating body, nutrition, activity progress.
Weighted by user's category weights from focus areas.

```python
def calculate_category_progress(profile_id: str, category: str) -> Optional[int]
```
Maps category name to appropriate score function.
Categories: körper, ernährung, aktivität, erholung, vitalwerte, mental, lebensstil

---

## Common Patterns

### Getting Goals for a Specific Type

```python
# ❌ DON'T (function doesn't exist):
from goal_utils import get_goals_by_type
goals = get_goals_by_type(profile_id, 'weight')

# ✅ DO:
from goal_utils import get_active_goals
goals = get_active_goals(profile_id)
weight_goals = [g for g in goals if g.get('type_key') == 'weight']
```

### Accessing Focus Area Weights

```python
# ❌ DON'T (German keys don't exist in DB):
weight_focus = focus_weights.get('körpergewicht', 0)

# ✅ DO (English keys from Migration 031):
weight_loss = focus_weights.get('weight_loss', 0)
muscle_gain = focus_weights.get('muscle_gain', 0)
```

### Querying Sleep Data

```python
# ❌ DON'T:
SELECT duration FROM sleep_log

# ✅ DO:
SELECT duration_minutes, deep_minutes, rem_minutes FROM sleep_log
```

---

## Verification Checklist

Before using any function:

1. ✅ Verify function exists: `grep "^def function_name" backend/module.py`
2. ✅ Check signature: `Read module.py` to see parameters
3. ✅ Check what it returns: Read docstring or implementation
4. ✅ Verify imported correctly: Check module path

Before writing SQL:

1. ✅ Check table schema: `grep "CREATE TABLE" backend/schema.sql`
2. ✅ Verify column names: Check migration files
3. ✅ Test query logic: Use actual data, not assumptions
