wiki:AdvancedReports

Version 6 (modified by 201165, 7 days ago) ( diff )

--

Nutritioneer | Напредни извештаи од базата

​Алатка за релациона алгебра

Ознака Операција
σ Selection
π Projection
⋈ Join
⟕ Left outer join
γ Аggregation
τ Sorting
− Difference
ω Complete Set
← Temp relation
SUM(x | у) Conditional Sum

Извештај 1: Преглед на активноста во заедницата

Account Activity Log

Опис на барањата за податоци

Извештајот покажува колку е активна секоја сметка во четирите дела на апликацијата. За секој корисник ги брои креираните рецепти, објавите, коментарите и записите во дневникот, заедно со неговата улога од USER кон RECIPE, POST, COMMENT и INTAKE_PLANNER.

SQL - приказ

SELECT u.username,
       u.role,
       COUNT(DISTINCT r.id)  AS recipes_created,
       COUNT(DISTINCT p.id)  AS posts_created,
       COUNT(DISTINCT c.id)  AS comments_written,
       COUNT(DISTINCT ip.id) AS diary_entries
FROM "user" u
LEFT JOIN recipe r          ON r.user_id  = u.id
LEFT JOIN post p            ON p.user_id  = u.id
LEFT JOIN comment c         ON c.user_id  = u.id
LEFT JOIN intake_planner ip ON ip.user_id = u.id
GROUP BY u.id, u.username, u.role
ORDER BY recipes_created DESC, posts_created DESC, u.username;

Релациона алгебра - приказ

τ_{recipes_created DESC, posts_created DESC, username} (
  γ_{u.id, u.username, u.role;
      COUNT(DISTINCT r.id)  → recipes_created,
      COUNT(DISTINCT p.id)  → posts_created,
      COUNT(DISTINCT c.id)  → comments_written,
      COUNT(DISTINCT ip.id) → diary_entries} (
    User ⟕_{u.id = r.user_id}  Recipe
         ⟕_{u.id = p.user_id}  Post
         ⟕_{u.id = c.user_id}  Comment
         ⟕_{u.id = ip.user_id} Intake_Planner
  )
)

Извештај 2: Профил на макронутриенти по порција

Health Stat Check

Опис на барањата за податоци

Протеини, јаглехидрати, масти и влакна во една порција од секој рецепт. Спојува две одделни M:N врски во еден нутритивен приказ: рецепт содржи состојки, а состојка содржи нутриенти. За секој рецепт пресметува колку грама од секој макронутриент дава една порција, и ги рангира рецептите по протеини.

  • (нутриент на 100 g) × (употребени грамови) / 100 преку сите состојки, поделен со бројот на порции.

SQL - приказ

SELECT r.name                          AS recipe,
       ROUND(r.kcal_sum / r.servings)  AS kcal_per_portion,
       ROUND(SUM(CASE WHEN n.description = 'Protein'
                      THEN icn.quantity * rci.ingredient_quantity / 100
                 END) / r.servings, 1) AS protein_g,
       ROUND(SUM(CASE WHEN n.description = 'Total carbohydrate'
                      THEN icn.quantity * rci.ingredient_quantity / 100
                 END) / r.servings, 1) AS carbs_g,
       ROUND(SUM(CASE WHEN n.description = 'Total fat'
                      THEN icn.quantity * rci.ingredient_quantity / 100
                 END) / r.servings, 1) AS fat_g,
       ROUND(SUM(CASE WHEN n.description = 'Dietary fibre'
                      THEN icn.quantity * rci.ingredient_quantity / 100
                 END) / r.servings, 1) AS fibre_g
FROM recipe r
JOIN recipe_contains_ingredient   rci ON rci.recipe_id     = r.id
JOIN ingredient_contains_nutrient icn ON icn.ingredient_id = rci.ingredient_id
JOIN nutrient n                       ON n.id              = icn.nutrient_id
WHERE n.type = 'macro'
GROUP BY r.id, r.name, r.kcal_sum, r.servings
ORDER BY protein_g DESC;

Релациона алгебра - приказ

amount ≡ icn.quantity · rci.ingredient_quantity / 100

τ_{protein_g DESC} (
  γ_{r.id, r.name, r.kcal_sum, r.servings;
      SUM(amount | n.description = 'Protein')            / r.servings → protein_g,
      SUM(amount | n.description = 'Total carbohydrate') / r.servings → carbs_g,
      SUM(amount | n.description = 'Total fat')          / r.servings → fat_g,
      SUM(amount | n.description = 'Dietary fibre')      / r.servings → fibre_g} (
    σ_{n.type = 'macro'} (
      Recipe
        ⋈_{r.id = rci.recipe_id}              Recipe_Contains_Ingredient
        ⋈_{rci.ingredient_id = icn.ingredient_id} Ingredient_Contains_Nutrient
        ⋈_{icn.nutrient_id = n.id}            Nutrient
    )
  )
)

Извештај 3: Ден со најголем внес по корисник

Callorie-maxing view

Опис на барањата за податоци

Фокус на денот со најмногу калории на секој корисник наспроти неговиот сопствен просек. секој корисник што води дневник на исхрана, извештајот го наоѓа денот во кој внел најмногу енергија. Тој ден го споредува со просечниот дневен внес на истиот корисник.

  • RANK() ги дели деновите по корисник и ги подредува по енергија
  • AVG() врз истата партиција го дава просекот.

ROW_NUMBER() прикажуваше само една инстанца ако имаше дупликати/денови со ист број калории

SQL - приказ

WITH daily_intake AS (
    SELECT u.username,
           ip.date_time::date AS intake_day,
           SUM(ip.kcal)       AS kcal_consumed,
           COUNT(*)           AS meals_logged,
           ROUND(AVG(SUM(ip.kcal)) OVER (PARTITION BY u.id)) AS avg_daily_kcal,
           RANK() OVER (PARTITION BY u.id ORDER BY SUM(ip.kcal) DESC) AS day_rank
    FROM "user" u
    JOIN intake_planner ip ON ip.user_id = u.id
    WHERE ip.is_consumed = TRUE
    GROUP BY u.id, u.username, ip.date_time::date
)
SELECT username, intake_day, kcal_consumed, meals_logged, avg_daily_kcal
FROM daily_intake
WHERE day_rank = 1
ORDER BY kcal_consumed DESC;

Релациона алгебра - приказ

Daily ← γ_{u.id, u.username, date(ip.date_time) → intake_day;
          SUM(ip.kcal) → kcal_consumed, COUNT(*) → meals_logged} (
    σ_{ip.is_consumed = TRUE} (User ⋈_{u.id = ip.user_id} Intake_Planner)
)

τ_{kcal_consumed DESC} (
  π_{username, intake_day, kcal_consumed, meals_logged, avg_daily_kcal} (
    σ_{day_rank = 1} (
      ω_{PARTITION BY u.id;
         RANK() ORDER BY kcal_consumed DESC → day_rank,
         AVG(kcal_consumed)                 → avg_daily_kcal} (Daily)
    )
  )
)

Извештај 4: Целосно растителни рецепти

Go Green Filter

Опис на барањата за податоци

Рецепти чија секоја состојка е од растителна категорија, проверени наспроти веганската ознака. пронаоѓа рецептите во кои секоја состојка е од растително потекло. Тоа е релациско делење: рецептот се квалификува само ако бројот на неговите растителни состојки е еднаков на бројот на сите негови состојки. Една состојка од животинско потекло го дисквалификува целиот рецепт. Растителни се типовите:

  • vegetable
  • fruit
  • legume
  • nut
  • seed
  • oil
  • herb
  • spice
  • carb
  • beverage
  • Медот и јајцето се од типот other -> дисквалификуваат

SQL - приказ

SELECT r.name                          AS recipe,
       u.username                      AS author,
       COUNT(*)                        AS ingredient_count,
       ROUND(r.kcal_sum / r.servings)  AS kcal_per_portion,
       EXISTS (SELECT 1
               FROM recipe_contains_restriction rcr
               JOIN restriction res ON res.id = rcr.restriction_id
               WHERE rcr.recipe_id = r.id
                 AND res.type = 'vegan')  AS tagged_vegan
FROM recipe r
JOIN "user" u                        ON u.id = r.user_id
JOIN recipe_contains_ingredient rci  ON rci.recipe_id = r.id
JOIN ingredient i                    ON i.id = rci.ingredient_id
WHERE i.type IN ('vegetable', 'fruit', 'legume', 'nut', 'seed',
                 'oil', 'herb', 'spice', 'carb', 'beverage')
GROUP BY r.id, r.name, u.username, r.kcal_sum, r.servings
HAVING COUNT(*) = (SELECT COUNT(*)
                   FROM recipe_contains_ingredient rci2
                   WHERE rci2.recipe_id = r.id)
ORDER BY kcal_per_portion;

Релациона алгебра - приказ

Plant ← {'vegetable', 'fruit', 'legume', 'nut', 'seed',
          'oil', 'herb', 'spice', 'carb', 'beverage'}

AnimalUse ← π_{rci.recipe_id} (
    σ_{i.type ∉ Plant} (
        Recipe_Contains_Ingredient ⋈_{rci.ingredient_id = i.id} Ingredient
    )
)

PlantOnly ← π_{rci.recipe_id} (Recipe_Contains_Ingredient) − AnimalUse

τ_{kcal_per_portion} (
  γ_{r.id, r.name, u.username; COUNT(*) → ingredient_count} (
    (PlantOnly ⋈_{recipe_id = r.id} Recipe)
      ⋈_{r.user_id = u.id} User
      ⋈_{r.id = rci.recipe_id} Recipe_Contains_Ingredient
  )
)

AI алатки во процесот

Искрористен беше агентот „deepseek.ai“ за тестирање на функциите на релационата алгебра во локален sandbox и зафаќање на edge-cases и оптимизирање на извештаите.

Навигација низ проектот

Почетна страна

Фаза Име на фаза Статус
P0 Дефинирање проект Одобрен
P1 Концептуален дизајн и ЕР Дијаграм Одобрен
P2 Логички и физички дизајн - DDL Одобрен
P3 Кориснички/апикациски сценарија со базата на податоци Одобрен
P4 Протип со основни функционалности WIP
М1 Презентација на прототип WIP
P5 Нормализација и оптимизација на дизајн WIP
P6 Напредни извештаи од базата WIP
P7 Понапреден развој на базата WIP
P8 Напреден апликативен развој WIP
P9 Дополнителни имплементации WIP
М2 Финализиран проект WIP

(Trac навигација)

Note: See TracWiki for help on using the wiki.