feat(workflows): Update CI configuration and enhance testing conditions
- 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:
parent
d6d7e738a5
commit
0d0ab62674
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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": "."}
|
||||
|
|
|
|||
|
|
@ -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: 'custom'</code>, wenn nur{' '}
|
||||
<code>conversion_factor</code> gelten soll.
|
||||
</p>
|
||||
<textarea
|
||||
className="form-input"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user