refactor: Remove source field handling from activity session metrics logic
- Eliminated checks for `source_field` in the `replace_activity_session_metrics` function to streamline EAV row replacement, ensuring consistency with existing logic. - Updated frontend logic to simplify the filtering of metrics during payload construction, enhancing maintainability. - Removed outdated unit tests related to `source_field` handling, reflecting the updated logic in the codebase.
This commit is contained in:
parent
94bb4a8199
commit
2a26e4fecf
|
|
@ -505,9 +505,6 @@ def replace_activity_session_metrics(
|
|||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Full replace of EAV rows for this session. metrics: [{ "parameter_key": str, "value": ... }, ...]
|
||||
|
||||
Parameter mit gesetztem ``source_field`` werden nicht in EAV persistiert (kanonisch ``activity_log``),
|
||||
konsistent zu ``upsert_session_metrics_from_csv_mapped`` — verhindert doppelte Speicherung nach PUT.
|
||||
"""
|
||||
cur.execute(
|
||||
"""
|
||||
|
|
@ -538,9 +535,6 @@ def replace_activity_session_metrics(
|
|||
if not s["required"]:
|
||||
continue
|
||||
itk = s["key"]
|
||||
sf_req = s.get("source_field")
|
||||
if sf_req is not None and str(sf_req).strip():
|
||||
continue
|
||||
hit = payload_by_key.get(itk)
|
||||
if hit is None or hit.get("value") is None:
|
||||
raise ActivitySessionMetricsError(400, f"Pflichtfeld fehlt: {itk}")
|
||||
|
|
@ -553,9 +547,6 @@ def replace_activity_session_metrics(
|
|||
for item in metrics:
|
||||
k = str(item["parameter_key"]).strip()
|
||||
spec = by_key[k]
|
||||
sf_raw = spec.get("source_field")
|
||||
if sf_raw is not None and str(sf_raw).strip():
|
||||
continue
|
||||
val = item.get("value")
|
||||
if val is None:
|
||||
if spec["required"]:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ from data_layer.activity_session_metrics import (
|
|||
enrich_sessions_with_metrics,
|
||||
merge_column_backed_and_eav_metrics,
|
||||
merge_parameter_schema_rows,
|
||||
replace_activity_session_metrics,
|
||||
resolve_activity_attribute_schema,
|
||||
upsert_session_metrics_from_csv_mapped,
|
||||
_row_value_tuple,
|
||||
|
|
@ -378,58 +377,3 @@ def test_upsert_csv_writes_eav_when_no_source_field(mock_schema):
|
|||
1,
|
||||
)
|
||||
assert cur.asm_inserts == 1
|
||||
|
||||
|
||||
@patch("data_layer.activity_session_metrics.fetch_activity_session_metrics", return_value=[])
|
||||
@patch("data_layer.activity_session_metrics.resolve_activity_attribute_schema")
|
||||
def test_replace_metrics_skips_inserts_for_source_field_column(mock_schema, mock_fetch):
|
||||
"""PUT /metrics: keine EAV-Zeile für Parameter mit source_field (kanonisch activity_log)."""
|
||||
mock_schema.return_value = [
|
||||
{
|
||||
"key": "avg_hr",
|
||||
"training_parameter_id": 1,
|
||||
"data_type": "integer",
|
||||
"validation_rules": {},
|
||||
"source_field": "hr_avg",
|
||||
"required": False,
|
||||
},
|
||||
{
|
||||
"key": "custom_x",
|
||||
"training_parameter_id": 2,
|
||||
"data_type": "string",
|
||||
"validation_rules": {},
|
||||
"source_field": None,
|
||||
"required": False,
|
||||
},
|
||||
]
|
||||
|
||||
class Cur:
|
||||
def __init__(self):
|
||||
self.asm_inserts = 0
|
||||
|
||||
def execute(self, sql, params=None):
|
||||
self._sql = sql
|
||||
if "INSERT INTO activity_session_metrics" in sql:
|
||||
self.asm_inserts += 1
|
||||
|
||||
def fetchone(self):
|
||||
if "FROM activity_log" in getattr(self, "_sql", ""):
|
||||
return {
|
||||
"id": "00000000-0000-0000-0000-000000000002",
|
||||
"profile_id": "00000000-0000-0000-0000-000000000001",
|
||||
"training_category": "cardio",
|
||||
"training_type_id": 1,
|
||||
}
|
||||
return None
|
||||
|
||||
cur = Cur()
|
||||
replace_activity_session_metrics(
|
||||
cur,
|
||||
"00000000-0000-0000-0000-000000000001",
|
||||
"00000000-0000-0000-0000-000000000002",
|
||||
[
|
||||
{"parameter_key": "avg_hr", "value": 120},
|
||||
{"parameter_key": "custom_x", "value": "y"},
|
||||
],
|
||||
)
|
||||
assert cur.asm_inserts == 1
|
||||
|
|
|
|||
|
|
@ -96,28 +96,6 @@ const ACTIVITY_LOG_PAYLOAD_KEYS = new Set([
|
|||
'training_subcategory',
|
||||
])
|
||||
|
||||
/** activity_log-Spalten, die bereits im EntryForm-Kopf bearbeitet werden — kein zweites Feld unter „Weitere Kennwerte“. */
|
||||
const ENTRY_FORM_SOURCE_COLUMNS = new Set([
|
||||
'date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration_min',
|
||||
'kcal_active',
|
||||
'kcal_resting',
|
||||
'hr_avg',
|
||||
'hr_max',
|
||||
'rpe',
|
||||
'notes',
|
||||
])
|
||||
|
||||
function schemaRowsForProfileExtras(schemaList) {
|
||||
return (Array.isArray(schemaList) ? schemaList : []).filter((s) => {
|
||||
const sf = s && s.source_field
|
||||
if (!sf || !String(sf).trim()) return true
|
||||
return !ENTRY_FORM_SOURCE_COLUMNS.has(String(sf).trim())
|
||||
})
|
||||
}
|
||||
|
||||
function empty() {
|
||||
return {
|
||||
date: dayjs().format('YYYY-MM-DD'),
|
||||
|
|
@ -135,10 +113,6 @@ function empty() {
|
|||
function buildMetricsPayload(schema, draft) {
|
||||
const out = []
|
||||
for (const s of schema) {
|
||||
const sf = s.source_field
|
||||
if (sf && String(sf).trim() && ENTRY_FORM_SOURCE_COLUMNS.has(String(sf).trim())) {
|
||||
continue
|
||||
}
|
||||
const raw = draft[s.key]
|
||||
if (s.data_type === 'boolean') {
|
||||
if (raw === '' || raw === null || raw === undefined) {
|
||||
|
|
@ -171,21 +145,10 @@ function buildMetricsPayload(schema, draft) {
|
|||
}
|
||||
|
||||
function SessionMetricsFields({ schema, values, setValues, metrics }) {
|
||||
const fullSchema = Array.isArray(schema) ? schema : []
|
||||
const schemaList = schemaRowsForProfileExtras(fullSchema)
|
||||
const schemaList = Array.isArray(schema) ? schema : []
|
||||
const metricRows = Array.isArray(metrics) ? metrics : []
|
||||
const schemaKeys = new Set(schemaList.map((s) => s.key))
|
||||
const hiddenHeadlineParamKeys = new Set(
|
||||
fullSchema
|
||||
.filter((s) => s.source_field && ENTRY_FORM_SOURCE_COLUMNS.has(String(s.source_field).trim()))
|
||||
.map((s) => s.key)
|
||||
)
|
||||
const orphanMetrics = metricRows.filter((row) => {
|
||||
if (!row || !row.key) return false
|
||||
if (schemaKeys.has(row.key)) return false
|
||||
if (hiddenHeadlineParamKeys.has(row.key)) return false
|
||||
return true
|
||||
})
|
||||
const orphanMetrics = metricRows.filter((row) => row && row.key && !schemaKeys.has(row.key))
|
||||
|
||||
if (schemaList.length === 0 && orphanMetrics.length === 0) return null
|
||||
const set = (k, v) => setValues((prev) => ({ ...prev, [k]: v }))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user