fix(csv-import): Normalize source unit representation and update CI workflows
Some checks failed
Deploy Development / deploy (push) Successful in 49s
Build Test / pytest-backend (push) Failing after 3s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s

- Changed source unit representation from "kJ" to "kj" for consistency across CSV templates and migrations.
- Updated CI workflow to enhance testing conditions, ensuring tests run in the correct environment based on deployment context.
- Improved job steps for backend testing and syntax checking by utilizing deployed application directories, streamlining the CI process.
This commit is contained in:
Lars 2026-04-10 10:42:59 +02:00
parent 0d0ab62674
commit bb6eefc837
5 changed files with 91 additions and 39 deletions

View File

@ -36,9 +36,7 @@ INSERT INTO csv_field_mappings (
},
"kcal": {
"type": "float",
"source_unit": "kJ",
"target_unit": "kcal",
"conversion_factor": 0.239,
"source_unit": "kj",
"decimal_separator": ","
},
"fat_g": {

View File

@ -8,54 +8,83 @@ on:
types: [completed]
jobs:
pytest-backend-csv:
pytest-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:
# 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
- name: Run backend pytest suite in deployed container
run: |
pip install -r backend/requirements.txt -r backend/requirements-dev.txt
- name: Pytest — CSV-Import & Parser (Smoke)
run: |
cd backend
python -m pytest tests/test_csv_parser_core.py tests/test_csv_import_executor.py tests/test_mapping_suggest.py -q --tb=short
EVENT_NAME="${{ github.event_name }}"
REF_NAME="${{ github.ref_name }}"
RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
APP_DIR="/home/lars/docker/bodytrack"
COMPOSE_FILE="docker-compose.yml"
if [ "$EVENT_NAME" = "workflow_run" ]; then
if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
COMPOSE_FILE="docker-compose.dev-env.yml"
fi
elif [ "$REF_NAME" = "develop" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
COMPOSE_FILE="docker-compose.dev-env.yml"
fi
cd "$APP_DIR"
docker compose -f "$COMPOSE_FILE" exec -T backend sh -lc "
pip install -r /app/requirements-dev.txt &&
cd /app &&
python -m pytest \
tests/test_csv_parser_core.py \
tests/test_csv_import_executor.py \
tests/test_mapping_suggest.py \
tests/test_placeholder_metadata.py \
tests/test_placeholder_metadata_v2.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
- name: Check backend syntax on deployed app
run: |
python -m py_compile backend/main.py
EVENT_NAME="${{ github.event_name }}"
REF_NAME="${{ github.ref_name }}"
RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
APP_DIR="/home/lars/docker/bodytrack"
if [ "$EVENT_NAME" = "workflow_run" ]; then
if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
fi
elif [ "$REF_NAME" = "develop" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
fi
python3 -m py_compile "$APP_DIR/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
- name: Build frontend on deployed app
run: |
cd frontend
EVENT_NAME="${{ github.event_name }}"
REF_NAME="${{ github.ref_name }}"
RUN_WORKFLOW="${{ github.event.workflow_run.name }}"
APP_DIR="/home/lars/docker/bodytrack"
if [ "$EVENT_NAME" = "workflow_run" ]; then
if [ "$RUN_WORKFLOW" = "Deploy Development" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
fi
elif [ "$REF_NAME" = "develop" ]; then
APP_DIR="/home/lars/docker/bodytrack-dev"
fi
cd "$APP_DIR/frontend"
npm install
npm run build
echo "✓ Frontend build OK"

View File

@ -31,9 +31,7 @@ SELECT
},
"kcal": {
"type": "float",
"source_unit": "kJ",
"target_unit": "kcal",
"conversion_factor": 0.239,
"source_unit": "kj",
"decimal_separator": ","
},
"fat_g": {"type": "float", "decimal_separator": ","},

View File

@ -0,0 +1,19 @@
-- Migration 046: FDDB-Systemvorlage — kcal ohne legacy conversion_factor/target_unit (Issue #21, source_unit-Registry)
-- Doppelte Umrechnung (kj-Faktor * 0.239) wurde fälschlich gespeichert; target_unit ist nur für duration vorgesehen.
UPDATE csv_field_mappings
SET type_conversions = jsonb_set(
type_conversions,
'{kcal}',
((type_conversions->'kcal') - 'conversion_factor' - 'target_unit')
|| jsonb_build_object('source_unit', 'kj')
)
WHERE is_system = true
AND profile_id IS NULL
AND module = 'nutrition'
AND mapping_name = 'FDDB Export (Standard)'
AND (type_conversions->'kcal') IS NOT NULL
AND (
(type_conversions->'kcal') ? 'conversion_factor'
OR (type_conversions->'kcal') ? 'target_unit'
);

View File

@ -182,7 +182,11 @@ export default function AdminCsvTemplateEditorPage() {
const opts = modMeta?.fields?.[fieldKey]?.source_unit_options || []
const canonical = opts.find((o) => o.is_canonical)?.id || opts[0]?.id
const su = tc[fieldKey]?.source_unit
if (su && opts.some((o) => o.id === su)) return su
if (su != null && su !== '') {
const sid = String(su).toLowerCase()
const hit = opts.find((o) => o.id === sid)
if (hit) return hit.id
}
return canonical || ''
}
@ -205,6 +209,8 @@ export default function AdminCsvTemplateEditorPage() {
} else {
base.source_unit = sourceUnitId
}
delete base.target_unit
delete base.conversion_factor
tc[fieldKey] = base
setTypeConversionsText(JSON.stringify(tc, null, 2))
setError(null)
@ -586,7 +592,9 @@ export default function AdminCsvTemplateEditorPage() {
<div className="form-label">3b. Quelleinheit (optional)</div>
<p style={{ fontSize: 13, color: 'var(--text2)', marginTop: 8, lineHeight: 1.55 }}>
Ziel-Einheit kommt aus dem Datenmodell (z. B. kcal, g, kg, km). Hier nur angeben, falls die CSV
abweicht (z. B. FDDB kJ → kcal, Makros in kg → g, Gewicht in lb → kg).
abweicht (z. B. FDDB kJ → kcal, Makros in kg → g, Gewicht in lb → kg). Beim Ändern hier werden
pro Feld <code>conversion_factor</code> und <code>target_unit</code> entfernt (verhindert
Doppel-Umrechnung); bei Bedarf wieder in Abschnitt 4 ergänzen.
</p>
<div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 12 }}>
{unitTargets.map(({ field: fkey, options }) => (