]> Nutra Git (v1) - nutratech/gui.git/commitdiff
config update, gitignore, docs feature roadmap
authorShane Jaroch <chown_tee@proton.me>
Mon, 26 Jan 2026 04:11:46 +0000 (23:11 -0500)
committerShane Jaroch <chown_tee@proton.me>
Mon, 26 Jan 2026 04:11:46 +0000 (23:11 -0500)
.gitignore
CMakeLists.txt
docs/todo.md [new file with mode: 0644]

index b25244e1d73815d508e97824ffd62f4dec4ecc4f..2c49320e85d2d10d7f7364245a9891560b764ac3 100644 (file)
@@ -8,3 +8,26 @@
 # C++ stuff
 build/
 
+
+# CMake
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+install_manifest.txt
+CTestTestfile.cmake
+Makefile
+
+# Qt
+*_autogen/
+*.qrc.cpp
+
+# Generated binaries and libs
+*.a
+*.so
+*.dylib
+*.exe
+
+# Specific executables (if in-source build happens)
+/nutra
+/test_*
+/nutra.desktop
index 08ba242520f84e2c05055529ad3096c3332c1e14..8b80074fb22e366195a296cae7aa158e19971d4c 100644 (file)
@@ -13,9 +13,13 @@ set(CMAKE_AUTOUIC ON)
 find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Sql)
 find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Sql)
 
+
+# Sources
 file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/*.cpp")
 file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS "include/*.h")
-set(PROJECT_SOURCES ${SOURCES} ${HEADERS} "resources.qrc")
+
+# Filter out main.cpp for the library
+list(FILTER SOURCES EXCLUDE REGEX ".*src/main\\.cpp$")
 
 # Versioning
 if(NOT NUTRA_VERSION)
@@ -34,43 +38,30 @@ if(NOT NUTRA_VERSION)
 endif()
 add_compile_definitions(NUTRA_VERSION_STRING="${NUTRA_VERSION}")
 
+# Core Library
+add_library(nutra_lib STATIC ${SOURCES} ${HEADERS} "resources.qrc")
+target_include_directories(nutra_lib PUBLIC ${CMAKE_SOURCE_DIR}/include)
+target_link_libraries(nutra_lib PUBLIC Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql)
 
+# Main Executable
+add_executable(nutra src/main.cpp)
+target_link_libraries(nutra PRIVATE nutra_lib)
 
-
-
-
-add_executable(nutra
-    ${PROJECT_SOURCES}
-)
-
-target_include_directories(nutra PRIVATE ${CMAKE_SOURCE_DIR}/include)
-
-target_link_libraries(nutra PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql)
-
+# Testing
 enable_testing()
 find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED)
 
-add_executable(test_nutra EXCLUDE_FROM_ALL tests/test_foodrepository.cpp src/db/databasemanager.cpp src/db/foodrepository.cpp src/utils/string_utils.cpp)
-target_include_directories(test_nutra PRIVATE ${CMAKE_SOURCE_DIR}/include)
-target_link_libraries(test_nutra PRIVATE Qt${QT_VERSION_MAJOR}::Test Qt${QT_VERSION_MAJOR}::Sql)
-
-add_test(NAME FoodRepoTest COMMAND test_nutra)
-
-file(GLOB_RECURSE TEST_DB_SOURCES
-    tests/test_databasemanager.cpp
-    tests/test_databasemanager.h
-    src/db/*.cpp
-    src/utils/*.cpp
-)
-add_executable(test_databasemanager ${TEST_DB_SOURCES})
-target_include_directories(test_databasemanager PRIVATE ${CMAKE_SOURCE_DIR}/include)
-target_link_libraries(test_databasemanager PRIVATE Qt${QT_VERSION_MAJOR}::Test Qt${QT_VERSION_MAJOR}::Sql)
-add_test(NAME DatabaseManagerTest COMMAND test_databasemanager)
-
-add_executable(test_calculations tests/test_calculations.cpp tests/test_calculations.h)
-target_include_directories(test_calculations PRIVATE ${CMAKE_SOURCE_DIR}/include)
-target_link_libraries(test_calculations PRIVATE Qt${QT_VERSION_MAJOR}::Test)
-add_test(NAME CalculationsTest COMMAND test_calculations)
+# Dynamic Test Discovery
+file(GLOB TEST_SOURCES "tests/test_*.cpp")
+
+foreach(TEST_SOURCE ${TEST_SOURCES})
+    get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE)
+    
+    add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_SOURCE})
+    target_link_libraries(${TEST_NAME} PRIVATE nutra_lib Qt${QT_VERSION_MAJOR}::Test)
+    
+    add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
+endforeach()
 
 
 include(GNUInstallDirs)
diff --git a/docs/todo.md b/docs/todo.md
new file mode 100644 (file)
index 0000000..8f1bea9
--- /dev/null
@@ -0,0 +1,79 @@
+Based on your current setup—which utilizes `usda-sqlite` to process the USDA SR-Legacy database—you have a solid foundation for commodity ingredients (raw fruits, vegetables, meats). However, SR-Legacy is static (stopped updating in 2018) and lacks the vast universe of branded products (UPC scanning) and modern micronutrient density data.
+
+To augment this for a "good user experience" (effortless search + rich data), you should integrate the following open-source and public APIs.
+
+### 1. USDA FoodData Central (FDC) API
+
+Since your project is already built on USDA logic, this is the most seamless integration. SR-Legacy (which you currently use) is now just one subset of FoodData Central.
+
+* **Why use it:** It includes **"Branded Foods"** (over 300,000 items from labels) and **"Foundation Foods"** (newer, highly granular micronutrient data that replaces SR-Legacy).
+* **Integration Strategy:**
+* Your `food_des` table uses `fdgrp_id`. FDC uses `fdcId`. You can create a mapping table to link your legacy IDs to new FDC IDs.
+* **Search:** The FDC API allows for keyword search which returns `fdcId`. You can use this to backfill missing nutrients in your `nut_data` table.
+
+* **Cost/License:** Free, Public Domain (U.S. Government).
+
+### 2. Open Food Facts (OFF)
+
+This is the "Wikipedia of food." It is the best open-source resource for scanning barcodes and finding branded products internationally.
+
+* **Why use it:**
+* **Barcodes:** It relies heavily on UPC/EAN codes. If your UX involves a camera/scanner, this is essential.
+* **Crowdsourced:** It covers niche brands that the USDA might miss.
+* **Nutri-Score:** It provides calculated scores (Nutri-Score, NOVA group) which you can store in your `food_des` or a new `food_metadata` table.
+
+* **Integration Strategy:**
+* Query by barcode: `https://world.openfoodfacts.org/api/v0/product/[barcode].json`
+* Map their JSON `nutriments` object to your `nutr_def` IDs (e.g., map OFF `saturated-fat_100g` to your `nutr_def` ID for saturated fat).
+
+* **Cost/License:** Free, Open Database License (ODbL).
+
+### 3. SQLite FTS5 (Full-Text Search)
+
+You are currently using SQLite. To make search "effortless" without calling an external API for every keystroke, you should utilize SQLite's native Full-Text Search extension.
+
+* **Why use it:** Your `food_des` table contains `long_desc`, `shrt_desc`, and `com_name`. Standard SQL `LIKE` queries are slow and bad at matching "natural" language. FTS5 allows for lightning-fast, ranked search results (e.g., typing "chk brst" finds "Chicken Breast").
+* **Integration:**
+* Modify your `sql/tables.sql` to include a virtual table:
+
+```sql
+CREATE VIRTUAL TABLE food_search USING fts5(long_desc, shrt_desc, com_name, content=food_des, content_rowid=id);
+
+```
+
+* Add a trigger to keep it updated. This will make your local search instant.
+
+### 4. Natural Language Processing (NLP) Parsers
+
+If "effortless search" means the user types "1 cup of oatmeal with 2 tbsp honey," you need a parser, not just a database.
+
+* **New York Times Ingredient Phrase Tagger (CRF++):** A structured learning model released by NYT to parse ingredient lines into amount, unit, and food.
+* **Price:** Open Source (Apache 2.0).
+* **Integration:** You can run this as a microservice (Python) alongside your `process.py`. When a user types a sentence, parse it to extract the quantity (to calculate `gram` weight) and the food subject (to query your SQLite DB).
+
+### Recommended Architecture Update
+
+Given your file structure, here is how you should integrate these sources:
+
+1. **Augment `nutr_def`:** Ensure your `nutr_def` table aligns with Open Food Facts tag naming conventions (add a column `off_tag` to map `fat` -> `fat_100g`).
+2. **New Table `external_links`:**
+Don't pollute `food_des` with mixed data. Create a linking table:
+
+```sql
+CREATE TABLE external_links (
+  local_food_id INT,
+  service_name TEXT, -- 'FDC', 'OFF'
+  external_id TEXT,  -- '123456' or UPC
+  last_updated DATETIME,
+  FOREIGN KEY(local_food_id) REFERENCES food_des(id)
+);
+
+```
+
+1. **Python Script (`data/process.py` extension):**
+Write a new script (e.g., `fetch_external.py`) that:
+
+* Takes a user query.
+* Checks local SQLite FTS5 first.
+* If no hit, queries Open Food Facts API.
+* Inserts the result into `food_des` and `nut_data`, and saves the link in `external_links`.