feat(workflows): Update CI configuration and enhance testing conditions
Some checks failed
Deploy Development / deploy (push) Successful in 48s
Build Test / pytest-backend-csv (push) Failing after 24s
Build Test / lint-backend (push) Failing after 3s
Build Test / build-frontend (push) Successful in 1m25s

- Added workflow_run triggers for "Deploy Development" and "Deploy Production" to ensure tests run only after successful deployments.
- Updated Python version in CI from 3.12 to 3.11 for better compatibility with the Debian 12 ARM64 runner.
- Enhanced job conditions to skip tests on failed workflow runs.
- Improved frontend build process by updating Node.js setup and ensuring correct directory navigation.
- Refined CSV parsing logic to handle custom and unknown source units, enhancing conversion flexibility.
- Added new tests for custom source unit handling in CSV conversions, ensuring accurate processing.
This commit is contained in:
Lars 2026-04-10 10:27:59 +02:00
parent d6d7e738a5
commit 0d0ab62674
5 changed files with 53 additions and 9 deletions

View File

@ -3,9 +3,13 @@ name: Build Test
on:
push:
branches: [main, develop]
workflow_run:
workflows: ["Deploy Development", "Deploy Production"]
types: [completed]
jobs:
pytest-backend-csv:
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -13,7 +17,9 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
# Debian 12 ARM64 runner hat fuer 3.12 oft kein setup-python Build.
# 3.11 ist dort breit verfuegbar und fuer unsere Tests ausreichend.
python-version: "3.11"
- name: Install dependencies
run: |
pip install -r backend/requirements.txt -r backend/requirements-dev.txt
@ -23,19 +29,33 @@ jobs:
python -m pytest tests/test_csv_parser_core.py tests/test_csv_import_executor.py tests/test_mapping_suggest.py -q --tb=short
lint-backend:
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Check backend syntax
run: |
python3 -m py_compile /home/lars/docker/bodytrack/backend/main.py
python -m py_compile backend/main.py
echo "✓ Backend syntax OK"
build-frontend:
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Build frontend
run: |
cd /home/lars/docker/bodytrack/frontend
cd frontend
npm install
npm run build
echo "✓ Frontend build OK"

View File

@ -83,12 +83,17 @@ def factor_source_to_canonical(module: str, db_field: str, source_unit: str | No
"""
Multiplikator: CSV-Zahl * Faktor Wert in kanonischer DB-Einheit.
Unbekannte/None/leer/Passthrough 1.0
``source_unit`` ``custom`` / ``none``: kein Registry-Faktor (1.0); freie Skalierung nur über
``conversion_factor`` in type_conversions (JSON).
"""
if source_unit is None:
return 1.0
su = str(source_unit).strip().lower()
if not su:
return 1.0
if su in ("custom", "none"):
return 1.0
cu = get_canonical_unit(module, db_field)
if not cu:
return 1.0

View File

@ -312,8 +312,11 @@ def convert_value(
- decimal_separator: ".", ",", "auto" bei auto Heuristik EU/US-Mischformen.
- formats: [ "yyyy-mm-dd", "%d.%m.%y", ... ] weitere strptime-/Alias-Ketten.
- dayfirst: true|false nur für dateutil-Fallback; Standard: true dann false.
- source_unit: z. B. "kj", "kg" Quelleinheit; Ziel aus Modul-Feld (unit in module_registry);
Faktor wird serverseitig ermittelt. Optional zusätzlich conversion_factor (legacy/zusätzlich).
- source_unit: Registry-IDs (z. B. "kj", "kg") oder "custom"/"none" letztere ohne
vordefinierten Faktor; beliebige Skalierung dann nur über conversion_factor.
- conversion_factor: Zusätzlicher Multiplikator nach dem Parsen (und nach source_unit);
für nicht vordefinierte Umrechnungen source_unit weglassen oder "custom" setzen und
hier den Faktor angeben.
"""
if spec is None:
return raw.strip() if raw else None
@ -331,7 +334,7 @@ def convert_value(
v = _float_from_spec(raw, spec)
if module:
su = spec.get("source_unit")
if su is not None:
if su is not None and str(su).strip() != "":
v = float(v) * factor_source_to_canonical(module, db_field, str(su))
factor = spec.get("conversion_factor")
if factor is not None:

View File

@ -86,6 +86,19 @@ def test_convert_protein_kg_to_g():
assert abs(g - 100.0) < 0.001
def test_convert_custom_source_unit_only_conversion_factor():
"""Nicht vordefinierte Umrechnung: conversion_factor (optional mit source_unit: custom)."""
spec = {"type": "float", "source_unit": "custom", "conversion_factor": 2.5, "decimal_separator": "."}
k = convert_value("100", "kcal", spec, module="nutrition")
assert abs(k - 250.0) < 0.001
def test_convert_unknown_source_unit_uses_conversion_factor_only():
spec = {"type": "float", "source_unit": "exotic_unit", "conversion_factor": 0.5, "decimal_separator": "."}
k = convert_value("200", "kcal", spec, module="nutrition")
assert abs(k - 100.0) < 0.001
def test_build_row_source_unit_without_module_no_factor():
"""Ohne module bleibt source_unit wirkungslos (Abwärtskompatibilität)."""
spec = {"type": "float", "source_unit": "kj", "decimal_separator": "."}

View File

@ -620,9 +620,12 @@ export default function AdminCsvTemplateEditorPage() {
<div className="card" style={{ padding: 16, marginBottom: 16 }}>
<div className="form-label">4. type_conversions (JSON)</div>
<p style={{ fontSize: 13, color: 'var(--text2)', marginTop: 8 }}>
Vom Vorschlag übernommen; Quelleinheiten setzen zusätzlich <code>source_unit</code> (siehe 3b).
Manuell z.B. Datumsformat oder legacy <code>conversion_factor</code>.
<p style={{ fontSize: 13, color: 'var(--text2)', marginTop: 8, lineHeight: 1.55 }}>
Vom Vorschlag übernommen; bei Dropdowns 3b wird <code>source_unit</code> ergänzt. Zusätzlich manuell
z.B. Datumsformat. <strong>Freie Umrechnung (nicht in der Liste 3b):</strong>{' '}
<code>conversion_factor</code> als Multiplikator nach dem Parsen (und nach Registry-
<code>source_unit</code>). Optional im JSON <code>source_unit: &apos;custom&apos;</code>, wenn nur{' '}
<code>conversion_factor</code> gelten soll.
</p>
<textarea
className="form-input"