skill-calorie 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/anomaly/common.d.ts +53 -0
- package/dist/analysis/anomaly/common.d.ts.map +1 -0
- package/dist/analysis/anomaly/common.js +69 -0
- package/dist/analysis/anomaly/common.js.map +1 -0
- package/dist/analysis/anomaly/diet.d.ts +8 -0
- package/dist/analysis/anomaly/diet.d.ts.map +1 -0
- package/dist/analysis/anomaly/diet.js +95 -0
- package/dist/analysis/anomaly/diet.js.map +1 -0
- package/dist/analysis/anomaly/exercise.d.ts +9 -0
- package/dist/analysis/anomaly/exercise.d.ts.map +1 -0
- package/dist/analysis/anomaly/exercise.js +116 -0
- package/dist/analysis/anomaly/exercise.js.map +1 -0
- package/dist/analysis/anomaly/index.d.ts +19 -0
- package/dist/analysis/anomaly/index.d.ts.map +1 -0
- package/dist/analysis/anomaly/index.js +51 -0
- package/dist/analysis/anomaly/index.js.map +1 -0
- package/dist/analysis/anomaly/overall.d.ts +13 -0
- package/dist/analysis/anomaly/overall.d.ts.map +1 -0
- package/dist/analysis/anomaly/overall.js +128 -0
- package/dist/analysis/anomaly/overall.js.map +1 -0
- package/dist/analysis/anomaly/overall2.d.ts +5 -0
- package/dist/analysis/anomaly/overall2.d.ts.map +1 -0
- package/dist/analysis/anomaly/overall2.js +94 -0
- package/dist/analysis/anomaly/overall2.js.map +1 -0
- package/dist/analysis/anomaly/weight.d.ts +8 -0
- package/dist/analysis/anomaly/weight.d.ts.map +1 -0
- package/dist/analysis/anomaly/weight.js +106 -0
- package/dist/analysis/anomaly/weight.js.map +1 -0
- package/dist/analysis/anomaly/weight2.d.ts +4 -0
- package/dist/analysis/anomaly/weight2.d.ts.map +1 -0
- package/dist/analysis/anomaly/weight2.js +59 -0
- package/dist/analysis/anomaly/weight2.js.map +1 -0
- package/dist/analysis/contraindications.d.ts +63 -0
- package/dist/analysis/contraindications.d.ts.map +1 -0
- package/dist/analysis/contraindications.js +121 -0
- package/dist/analysis/contraindications.js.map +1 -0
- package/dist/analysis/cross.d.ts +75 -0
- package/dist/analysis/cross.d.ts.map +1 -0
- package/dist/analysis/cross.js +283 -0
- package/dist/analysis/cross.js.map +1 -0
- package/dist/analysis/dashboard.d.ts +18 -0
- package/dist/analysis/dashboard.d.ts.map +1 -0
- package/dist/analysis/dashboard.js +48 -0
- package/dist/analysis/dashboard.js.map +1 -0
- package/dist/analysis/deficit.d.ts +44 -0
- package/dist/analysis/deficit.d.ts.map +1 -0
- package/dist/analysis/deficit.js +54 -0
- package/dist/analysis/deficit.js.map +1 -0
- package/dist/analysis/diet.d.ts +76 -0
- package/dist/analysis/diet.d.ts.map +1 -0
- package/dist/analysis/diet.js +164 -0
- package/dist/analysis/diet.js.map +1 -0
- package/dist/analysis/exercise.d.ts +98 -0
- package/dist/analysis/exercise.d.ts.map +1 -0
- package/dist/analysis/exercise.js +298 -0
- package/dist/analysis/exercise.js.map +1 -0
- package/dist/analysis/exerciseReview.d.ts +36 -0
- package/dist/analysis/exerciseReview.d.ts.map +1 -0
- package/dist/analysis/exerciseReview.js +50 -0
- package/dist/analysis/exerciseReview.js.map +1 -0
- package/dist/analysis/precision.d.ts +15 -0
- package/dist/analysis/precision.d.ts.map +1 -0
- package/dist/analysis/precision.js +38 -0
- package/dist/analysis/precision.js.map +1 -0
- package/dist/analysis/result.d.ts +15 -0
- package/dist/analysis/result.d.ts.map +1 -0
- package/dist/analysis/result.js +13 -0
- package/dist/analysis/result.js.map +1 -0
- package/dist/analysis/review.d.ts +118 -0
- package/dist/analysis/review.d.ts.map +1 -0
- package/dist/analysis/review.js +195 -0
- package/dist/analysis/review.js.map +1 -0
- package/dist/analysis/series.d.ts +42 -0
- package/dist/analysis/series.d.ts.map +1 -0
- package/dist/analysis/series.js +127 -0
- package/dist/analysis/series.js.map +1 -0
- package/dist/analysis/simulate.d.ts +43 -0
- package/dist/analysis/simulate.d.ts.map +1 -0
- package/dist/analysis/simulate.js +109 -0
- package/dist/analysis/simulate.js.map +1 -0
- package/dist/analysis/simulate2.d.ts +65 -0
- package/dist/analysis/simulate2.d.ts.map +1 -0
- package/dist/analysis/simulate2.js +173 -0
- package/dist/analysis/simulate2.js.map +1 -0
- package/dist/analysis/trend.d.ts +39 -0
- package/dist/analysis/trend.d.ts.map +1 -0
- package/dist/analysis/trend.js +48 -0
- package/dist/analysis/trend.js.map +1 -0
- package/dist/analysis/utils.d.ts +17 -0
- package/dist/analysis/utils.d.ts.map +1 -0
- package/dist/analysis/utils.js +52 -0
- package/dist/analysis/utils.js.map +1 -0
- package/dist/analysis/volatility.d.ts +43 -0
- package/dist/analysis/volatility.d.ts.map +1 -0
- package/dist/analysis/volatility.js +96 -0
- package/dist/analysis/volatility.js.map +1 -0
- package/dist/analysis/weight.d.ts +86 -0
- package/dist/analysis/weight.d.ts.map +1 -0
- package/dist/analysis/weight.js +219 -0
- package/dist/analysis/weight.js.map +1 -0
- package/dist/analysis/weightCompare.d.ts +63 -0
- package/dist/analysis/weightCompare.d.ts.map +1 -0
- package/dist/analysis/weightCompare.js +212 -0
- package/dist/analysis/weightCompare.js.map +1 -0
- package/dist/analysis/weightCompare2.d.ts +63 -0
- package/dist/analysis/weightCompare2.d.ts.map +1 -0
- package/dist/analysis/weightCompare2.js +211 -0
- package/dist/analysis/weightCompare2.js.map +1 -0
- package/dist/analysis/weightCompare3.d.ts +13 -0
- package/dist/analysis/weightCompare3.d.ts.map +1 -0
- package/dist/analysis/weightCompare3.js +199 -0
- package/dist/analysis/weightCompare3.js.map +1 -0
- package/dist/cli/cmd_read.d.ts +8 -0
- package/dist/cli/cmd_read.d.ts.map +1 -0
- package/dist/cli/cmd_read.js +719 -0
- package/dist/cli/cmd_read.js.map +1 -0
- package/dist/cli/keys.d.ts +333 -0
- package/dist/cli/keys.d.ts.map +1 -0
- package/dist/cli/keys.js +103 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/write.d.ts +24 -0
- package/dist/cli/write.d.ts.map +1 -0
- package/dist/cli/write.js +832 -0
- package/dist/cli/write.js.map +1 -0
- package/dist/fetch/audit.d.ts +25 -0
- package/dist/fetch/audit.d.ts.map +1 -0
- package/dist/fetch/audit.js +46 -0
- package/dist/fetch/audit.js.map +1 -0
- package/dist/fetch/batch.d.ts +68 -0
- package/dist/fetch/batch.d.ts.map +1 -0
- package/dist/fetch/batch.js +183 -0
- package/dist/fetch/batch.js.map +1 -0
- package/dist/fetch/body.d.ts +89 -0
- package/dist/fetch/body.d.ts.map +1 -0
- package/dist/fetch/body.js +217 -0
- package/dist/fetch/body.js.map +1 -0
- package/dist/fetch/cli.d.ts +3 -0
- package/dist/fetch/cli.d.ts.map +1 -0
- package/dist/fetch/cli.js +195 -0
- package/dist/fetch/cli.js.map +1 -0
- package/dist/fetch/cross-skill.d.ts +29 -0
- package/dist/fetch/cross-skill.d.ts.map +1 -0
- package/dist/fetch/cross-skill.js +42 -0
- package/dist/fetch/cross-skill.js.map +1 -0
- package/dist/fetch/db.d.ts +5 -0
- package/dist/fetch/db.d.ts.map +1 -0
- package/dist/fetch/db.js +4 -0
- package/dist/fetch/db.js.map +1 -0
- package/dist/fetch/diet.d.ts +174 -0
- package/dist/fetch/diet.d.ts.map +1 -0
- package/dist/fetch/diet.js +239 -0
- package/dist/fetch/diet.js.map +1 -0
- package/dist/fetch/errors.d.ts +5 -0
- package/dist/fetch/errors.d.ts.map +1 -0
- package/dist/fetch/errors.js +8 -0
- package/dist/fetch/errors.js.map +1 -0
- package/dist/fetch/exercise.d.ts +72 -0
- package/dist/fetch/exercise.d.ts.map +1 -0
- package/dist/fetch/exercise.js +270 -0
- package/dist/fetch/exercise.js.map +1 -0
- package/dist/fetch/goal.d.ts +48 -0
- package/dist/fetch/goal.d.ts.map +1 -0
- package/dist/fetch/goal.js +73 -0
- package/dist/fetch/goal.js.map +1 -0
- package/dist/fetch/goalHistory.d.ts +24 -0
- package/dist/fetch/goalHistory.d.ts.map +1 -0
- package/dist/fetch/goalHistory.js +51 -0
- package/dist/fetch/goalHistory.js.map +1 -0
- package/dist/fetch/history.d.ts +28 -0
- package/dist/fetch/history.d.ts.map +1 -0
- package/dist/fetch/history.js +29 -0
- package/dist/fetch/history.js.map +1 -0
- package/dist/fetch/index.d.ts +23 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +16 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/fetch/nutritionGoal.d.ts +115 -0
- package/dist/fetch/nutritionGoal.d.ts.map +1 -0
- package/dist/fetch/nutritionGoal.js +154 -0
- package/dist/fetch/nutritionGoal.js.map +1 -0
- package/dist/fetch/photos.d.ts +76 -0
- package/dist/fetch/photos.d.ts.map +1 -0
- package/dist/fetch/photos.js +193 -0
- package/dist/fetch/photos.js.map +1 -0
- package/dist/fetch/plan.d.ts +145 -0
- package/dist/fetch/plan.d.ts.map +1 -0
- package/dist/fetch/plan.js +258 -0
- package/dist/fetch/plan.js.map +1 -0
- package/dist/fetch/products.d.ts +62 -0
- package/dist/fetch/products.d.ts.map +1 -0
- package/dist/fetch/products.js +73 -0
- package/dist/fetch/products.js.map +1 -0
- package/dist/fetch/profile.d.ts +46 -0
- package/dist/fetch/profile.d.ts.map +1 -0
- package/dist/fetch/profile.js +105 -0
- package/dist/fetch/profile.js.map +1 -0
- package/dist/fetch/shapes.d.ts +41 -0
- package/dist/fetch/shapes.d.ts.map +1 -0
- package/dist/fetch/shapes.js +38 -0
- package/dist/fetch/shapes.js.map +1 -0
- package/dist/fetch/validate.d.ts +11 -0
- package/dist/fetch/validate.d.ts.map +1 -0
- package/dist/fetch/validate.js +64 -0
- package/dist/fetch/validate.js.map +1 -0
- package/dist/fetch/weight.d.ts +109 -0
- package/dist/fetch/weight.d.ts.map +1 -0
- package/dist/fetch/weight.js +210 -0
- package/dist/fetch/weight.js.map +1 -0
- package/dist/fetch/xunji-catalog.d.ts +17 -0
- package/dist/fetch/xunji-catalog.d.ts.map +1 -0
- package/dist/fetch/xunji-catalog.js +57 -0
- package/dist/fetch/xunji-catalog.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/kcal.d.ts +21 -0
- package/dist/kcal.d.ts.map +1 -0
- package/dist/kcal.js +27 -0
- package/dist/kcal.js.map +1 -0
- package/dist/migrate/migrate.d.ts +71 -0
- package/dist/migrate/migrate.d.ts.map +1 -0
- package/dist/migrate/migrate.js +450 -0
- package/dist/migrate/migrate.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/render/analysisPlate.d.ts +49 -0
- package/dist/render/analysisPlate.d.ts.map +1 -0
- package/dist/render/analysisPlate.js +149 -0
- package/dist/render/analysisPlate.js.map +1 -0
- package/dist/render/bodyPlate.d.ts +55 -0
- package/dist/render/bodyPlate.d.ts.map +1 -0
- package/dist/render/bodyPlate.js +97 -0
- package/dist/render/bodyPlate.js.map +1 -0
- package/dist/render/diet.d.ts +47 -0
- package/dist/render/diet.d.ts.map +1 -0
- package/dist/render/diet.js +94 -0
- package/dist/render/diet.js.map +1 -0
- package/dist/render/envelope.d.ts +60 -0
- package/dist/render/envelope.d.ts.map +1 -0
- package/dist/render/envelope.js +111 -0
- package/dist/render/envelope.js.map +1 -0
- package/dist/render/errors.d.ts +10 -0
- package/dist/render/errors.d.ts.map +1 -0
- package/dist/render/errors.js +9 -0
- package/dist/render/errors.js.map +1 -0
- package/dist/render/exercise.d.ts +20 -0
- package/dist/render/exercise.d.ts.map +1 -0
- package/dist/render/exercise.js +32 -0
- package/dist/render/exercise.js.map +1 -0
- package/dist/render/goal.d.ts +24 -0
- package/dist/render/goal.d.ts.map +1 -0
- package/dist/render/goal.js +23 -0
- package/dist/render/goal.js.map +1 -0
- package/dist/render/goalExtra.d.ts +45 -0
- package/dist/render/goalExtra.d.ts.map +1 -0
- package/dist/render/goalExtra.js +94 -0
- package/dist/render/goalExtra.js.map +1 -0
- package/dist/render/goalPlate.d.ts +66 -0
- package/dist/render/goalPlate.d.ts.map +1 -0
- package/dist/render/goalPlate.js +110 -0
- package/dist/render/goalPlate.js.map +1 -0
- package/dist/render/health.d.ts +21 -0
- package/dist/render/health.d.ts.map +1 -0
- package/dist/render/health.js +41 -0
- package/dist/render/health.js.map +1 -0
- package/dist/render/help.d.ts +18 -0
- package/dist/render/help.d.ts.map +1 -0
- package/dist/render/help.js +58 -0
- package/dist/render/help.js.map +1 -0
- package/dist/render/home.d.ts +30 -0
- package/dist/render/home.d.ts.map +1 -0
- package/dist/render/home.js +73 -0
- package/dist/render/home.js.map +1 -0
- package/dist/render/html.d.ts +66 -0
- package/dist/render/html.d.ts.map +1 -0
- package/dist/render/html.js +510 -0
- package/dist/render/html.js.map +1 -0
- package/dist/render/index.d.ts +47 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +26 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/insightPlate.d.ts +55 -0
- package/dist/render/insightPlate.d.ts.map +1 -0
- package/dist/render/insightPlate.js +97 -0
- package/dist/render/insightPlate.js.map +1 -0
- package/dist/render/library.d.ts +32 -0
- package/dist/render/library.d.ts.map +1 -0
- package/dist/render/library.js +54 -0
- package/dist/render/library.js.map +1 -0
- package/dist/render/photo.d.ts +101 -0
- package/dist/render/photo.d.ts.map +1 -0
- package/dist/render/photo.js +241 -0
- package/dist/render/photo.js.map +1 -0
- package/dist/render/planPlate.d.ts +40 -0
- package/dist/render/planPlate.d.ts.map +1 -0
- package/dist/render/planPlate.js +72 -0
- package/dist/render/planPlate.js.map +1 -0
- package/dist/render/profilePlate.d.ts +17 -0
- package/dist/render/profilePlate.d.ts.map +1 -0
- package/dist/render/profilePlate.js +18 -0
- package/dist/render/profilePlate.js.map +1 -0
- package/dist/render/ranking.d.ts +22 -0
- package/dist/render/ranking.d.ts.map +1 -0
- package/dist/render/ranking.js +63 -0
- package/dist/render/ranking.js.map +1 -0
- package/dist/render/receipt.d.ts +71 -0
- package/dist/render/receipt.d.ts.map +1 -0
- package/dist/render/receipt.js +65 -0
- package/dist/render/receipt.js.map +1 -0
- package/dist/render/weightPlate.d.ts +54 -0
- package/dist/render/weightPlate.d.ts.map +1 -0
- package/dist/render/weightPlate.js +110 -0
- package/dist/render/weightPlate.js.map +1 -0
- package/dist/schema.d.ts +25 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +281 -0
- package/dist/schema.js.map +1 -0
- package/dist/triggers/help-lookup.d.ts +28 -0
- package/dist/triggers/help-lookup.d.ts.map +1 -0
- package/dist/triggers/help-lookup.js +163 -0
- package/dist/triggers/help-lookup.js.map +1 -0
- package/dist/triggers/index.d.ts +24 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +78 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/scene-01-home.d.ts +4 -0
- package/dist/triggers/scene-01-home.d.ts.map +1 -0
- package/dist/triggers/scene-01-home.js +13 -0
- package/dist/triggers/scene-01-home.js.map +1 -0
- package/dist/triggers/scene-02-diet.d.ts +4 -0
- package/dist/triggers/scene-02-diet.d.ts.map +1 -0
- package/dist/triggers/scene-02-diet.js +74 -0
- package/dist/triggers/scene-02-diet.js.map +1 -0
- package/dist/triggers/scene-03-weight.d.ts +4 -0
- package/dist/triggers/scene-03-weight.d.ts.map +1 -0
- package/dist/triggers/scene-03-weight.js +62 -0
- package/dist/triggers/scene-03-weight.js.map +1 -0
- package/dist/triggers/scene-04-exercise.d.ts +4 -0
- package/dist/triggers/scene-04-exercise.d.ts.map +1 -0
- package/dist/triggers/scene-04-exercise.js +43 -0
- package/dist/triggers/scene-04-exercise.js.map +1 -0
- package/dist/triggers/scene-05-workout.d.ts +4 -0
- package/dist/triggers/scene-05-workout.d.ts.map +1 -0
- package/dist/triggers/scene-05-workout.js +36 -0
- package/dist/triggers/scene-05-workout.js.map +1 -0
- package/dist/triggers/scene-06-goal.d.ts +4 -0
- package/dist/triggers/scene-06-goal.d.ts.map +1 -0
- package/dist/triggers/scene-06-goal.js +29 -0
- package/dist/triggers/scene-06-goal.js.map +1 -0
- package/dist/triggers/scene-07-profile.d.ts +4 -0
- package/dist/triggers/scene-07-profile.d.ts.map +1 -0
- package/dist/triggers/scene-07-profile.js +8 -0
- package/dist/triggers/scene-07-profile.js.map +1 -0
- package/dist/triggers/scene-08-body.d.ts +4 -0
- package/dist/triggers/scene-08-body.d.ts.map +1 -0
- package/dist/triggers/scene-08-body.js +17 -0
- package/dist/triggers/scene-08-body.js.map +1 -0
- package/dist/triggers/scene-09-photo.d.ts +4 -0
- package/dist/triggers/scene-09-photo.d.ts.map +1 -0
- package/dist/triggers/scene-09-photo.js +14 -0
- package/dist/triggers/scene-09-photo.js.map +1 -0
- package/dist/triggers/scene-10-analysis.d.ts +4 -0
- package/dist/triggers/scene-10-analysis.d.ts.map +1 -0
- package/dist/triggers/scene-10-analysis.js +180 -0
- package/dist/triggers/scene-10-analysis.js.map +1 -0
- package/dist/triggers/types.d.ts +66 -0
- package/dist/triggers/types.d.ts.map +1 -0
- package/dist/triggers/types.js +3 -0
- package/dist/triggers/types.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** T7 #26 · 赤字口径层(对照老家 scripts/render_calorie_deficit.py 数据段 + ADR-0013)。
|
|
2
|
+
*
|
|
3
|
+
* 薄壳:唯一数据源 = T5 buildSeries,不自算缺口(老家 v2 T5 薄壳化后同样)。
|
|
4
|
+
* 热量缺口 = 消耗 − 摄入,正=缺口;消耗 = TDEE + 当日运动;摄入 = 当日食物(不含水)。
|
|
5
|
+
* KCAL_PER_KG = 7700(脂肪);weekly_deficit_per_day: 300 沿老家 target 段。
|
|
6
|
+
*/
|
|
7
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
8
|
+
export declare const KCAL_PER_KG = 7700;
|
|
9
|
+
export declare const WEEKDAY_NAMES: string[];
|
|
10
|
+
export declare function weekdayName(isoDate: string): string;
|
|
11
|
+
export interface DeficitDay {
|
|
12
|
+
date: string;
|
|
13
|
+
intake: number;
|
|
14
|
+
burn: number;
|
|
15
|
+
deficit: number;
|
|
16
|
+
weekday: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DeficitSummary {
|
|
19
|
+
avgIntake: number;
|
|
20
|
+
avgBurn: number;
|
|
21
|
+
avgExerciseBurn: number;
|
|
22
|
+
avgDeficit: number;
|
|
23
|
+
weeklyDeficit: number;
|
|
24
|
+
predictedLossKg: number;
|
|
25
|
+
trend: 'loss' | 'gain' | 'flat';
|
|
26
|
+
}
|
|
27
|
+
export interface DeficitData {
|
|
28
|
+
summary: DeficitSummary;
|
|
29
|
+
target: {
|
|
30
|
+
intake: number;
|
|
31
|
+
tdee: number;
|
|
32
|
+
weeklyDeficitPerDay: number;
|
|
33
|
+
};
|
|
34
|
+
series: DeficitDay[];
|
|
35
|
+
meta: {
|
|
36
|
+
start: string;
|
|
37
|
+
end: string;
|
|
38
|
+
days: number;
|
|
39
|
+
weekdayCount: number;
|
|
40
|
+
weekendCount: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export declare function buildDeficitData(db: DatabaseSync, start: string, end: string): DeficitData;
|
|
44
|
+
//# sourceMappingURL=deficit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deficit.d.ts","sourceRoot":"","sources":["../../src/analysis/deficit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,eAAO,MAAM,WAAW,OAAO,CAAC;AAChC,eAAO,MAAM,aAAa,UAA6C,CAAC;AAExE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAC9E;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAChF,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CACjF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAChG;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAwC1F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { FetchError } from '../fetch/errors.js';
|
|
2
|
+
import { round2 } from '../kcal.js';
|
|
3
|
+
import { buildSeries } from './series.js';
|
|
4
|
+
export const KCAL_PER_KG = 7700;
|
|
5
|
+
export const WEEKDAY_NAMES = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
|
6
|
+
export function weekdayName(isoDate) {
|
|
7
|
+
const t = Date.parse(isoDate + 'T12:00:00Z');
|
|
8
|
+
if (Number.isNaN(t))
|
|
9
|
+
throw new FetchError('日期非法: ' + isoDate);
|
|
10
|
+
return WEEKDAY_NAMES[(new Date(t).getUTCDay() + 6) % 7];
|
|
11
|
+
}
|
|
12
|
+
export function buildDeficitData(db, start, end) {
|
|
13
|
+
const s = buildSeries(db, start, end);
|
|
14
|
+
if (!s.length)
|
|
15
|
+
throw new FetchError(`无数据:${start} ~ ${end}`);
|
|
16
|
+
const first = s[0];
|
|
17
|
+
const targetIntake = first.calorieGoal || 1800;
|
|
18
|
+
const tdee = first.tdee || 1800;
|
|
19
|
+
const series = s.map((day) => {
|
|
20
|
+
const intake = day.calories ?? 0;
|
|
21
|
+
const exerciseBurn = day.exerciseKcal ?? 0;
|
|
22
|
+
return {
|
|
23
|
+
date: day.date,
|
|
24
|
+
intake,
|
|
25
|
+
burn: (day.tdee || 0) + exerciseBurn,
|
|
26
|
+
deficit: day.deficit ?? 0,
|
|
27
|
+
weekday: weekdayName(day.date),
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
const n = series.length;
|
|
31
|
+
const sum = (f) => series.reduce((a, d) => a + f(d), 0);
|
|
32
|
+
const totalD = sum((d) => d.deficit);
|
|
33
|
+
const avgD = Math.round(totalD / n);
|
|
34
|
+
const totalEx = s.reduce((a, d) => a + (d.exerciseKcal ?? 0), 0);
|
|
35
|
+
return {
|
|
36
|
+
summary: {
|
|
37
|
+
avgIntake: Math.round(sum((d) => d.intake) / n),
|
|
38
|
+
avgBurn: Math.round(sum((d) => d.burn) / n),
|
|
39
|
+
avgExerciseBurn: Math.round(totalEx / n),
|
|
40
|
+
avgDeficit: avgD,
|
|
41
|
+
weeklyDeficit: totalD,
|
|
42
|
+
predictedLossKg: round2(totalD / KCAL_PER_KG),
|
|
43
|
+
trend: avgD > 0 ? 'loss' : avgD < 0 ? 'gain' : 'flat',
|
|
44
|
+
},
|
|
45
|
+
target: { intake: targetIntake, tdee, weeklyDeficitPerDay: 300 },
|
|
46
|
+
series,
|
|
47
|
+
meta: {
|
|
48
|
+
start, end, days: n,
|
|
49
|
+
weekdayCount: series.filter((d) => ['周一', '周二', '周三', '周四', '周五'].includes(d.weekday)).length,
|
|
50
|
+
weekendCount: series.filter((d) => d.weekday === '周六' || d.weekday === '周日').length,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=deficit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deficit.js","sourceRoot":"","sources":["../../src/analysis/deficit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** T5 #24 · 饮食分析口径(对照老家 scripts/analysis/diet.py)。
|
|
2
|
+
*
|
|
3
|
+
* dietCalorieTrend / dietMacroRatio / dietFoodRanking / dietDeficitAnalysis。
|
|
4
|
+
* 只取 as_dict=True 结构化形状;print 分支归 T11。空数据回 rejection(明确阻断)。
|
|
5
|
+
* 注意:trend/ranking 查询不过滤饮水行(老家原样);low_calorie/frequent 榜
|
|
6
|
+
* 排除含 water/💧水(B-205)。deficit 用 体重×24×系数 BMR(老家口径,非 Mifflin)。
|
|
7
|
+
*/
|
|
8
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
9
|
+
import type { AnalysisResult } from './result.js';
|
|
10
|
+
export interface TrendDay {
|
|
11
|
+
date: string;
|
|
12
|
+
totalCal: number;
|
|
13
|
+
totalProtein: number;
|
|
14
|
+
totalCarbs: number;
|
|
15
|
+
totalFat: number;
|
|
16
|
+
}
|
|
17
|
+
export interface CalorieTrend {
|
|
18
|
+
daysCount: number;
|
|
19
|
+
totalCal: number;
|
|
20
|
+
avgCal: number;
|
|
21
|
+
calGoal: number | null;
|
|
22
|
+
complianceDays: number;
|
|
23
|
+
weekdayAvg: number;
|
|
24
|
+
weekendAvg: number;
|
|
25
|
+
daily: TrendDay[];
|
|
26
|
+
}
|
|
27
|
+
export declare function dietCalorieTrend(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<CalorieTrend>;
|
|
28
|
+
export type MacroStatus = 'high' | 'low' | 'ok';
|
|
29
|
+
export interface MacroEval {
|
|
30
|
+
pct: number;
|
|
31
|
+
targetPct: number;
|
|
32
|
+
diff: number;
|
|
33
|
+
status: MacroStatus;
|
|
34
|
+
}
|
|
35
|
+
export interface MacroRatio {
|
|
36
|
+
protein: MacroEval | null;
|
|
37
|
+
carb: MacroEval | null;
|
|
38
|
+
fat: MacroEval | null;
|
|
39
|
+
}
|
|
40
|
+
export declare function dietMacroRatio(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<MacroRatio>;
|
|
41
|
+
export type FoodRankCategory = 'high_calorie' | 'low_calorie' | 'frequent' | 'high_carb' | 'high_protein';
|
|
42
|
+
export interface RankItem {
|
|
43
|
+
rank: number;
|
|
44
|
+
foodName: string;
|
|
45
|
+
totalCal: number;
|
|
46
|
+
totalGrams: number;
|
|
47
|
+
totalProtein: number;
|
|
48
|
+
totalCarbs: number;
|
|
49
|
+
totalFat: number;
|
|
50
|
+
cnt: number;
|
|
51
|
+
avgCalPerMeal: number;
|
|
52
|
+
}
|
|
53
|
+
export interface FoodRanking {
|
|
54
|
+
category: string;
|
|
55
|
+
title: string;
|
|
56
|
+
start: string;
|
|
57
|
+
end: string;
|
|
58
|
+
topN: number;
|
|
59
|
+
items: RankItem[];
|
|
60
|
+
}
|
|
61
|
+
export declare function dietFoodRanking(db: DatabaseSync, startDate: string, endDate?: string | null, category?: string, topN?: number): AnalysisResult<FoodRanking>;
|
|
62
|
+
export interface DeficitAnalysis {
|
|
63
|
+
daysCount: number;
|
|
64
|
+
avgIntake: number;
|
|
65
|
+
bmr: number;
|
|
66
|
+
currentWeight: number;
|
|
67
|
+
avgExerciseBurn: number;
|
|
68
|
+
avgDeficit: number;
|
|
69
|
+
totalDeficit: number;
|
|
70
|
+
kgEquivalent: number;
|
|
71
|
+
sizeLabel: string;
|
|
72
|
+
dietContribPct: number;
|
|
73
|
+
exerciseContribPct: number;
|
|
74
|
+
}
|
|
75
|
+
export declare function dietDeficitAnalysis(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<DeficitAnalysis>;
|
|
76
|
+
//# sourceMappingURL=diet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diet.d.ts","sourceRoot":"","sources":["../../src/analysis/diet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { FetchError } from '../fetch/errors.js';
|
|
2
|
+
import { getActivityFactor, parseDate } from './utils.js';
|
|
3
|
+
import { ok, rejection } from './result.js';
|
|
4
|
+
const round = (n) => Math.round(n);
|
|
5
|
+
const round1 = (n) => Math.round(n * 10) / 10;
|
|
6
|
+
const round2 = (n) => Math.round(n * 100) / 100;
|
|
7
|
+
function rangeOf(start, end) {
|
|
8
|
+
const s = parseDate(start);
|
|
9
|
+
if (!s)
|
|
10
|
+
throw new FetchError('起始日期非法: ' + String(start));
|
|
11
|
+
return [s, parseDate(end ?? undefined) ?? s];
|
|
12
|
+
}
|
|
13
|
+
function latestWeightKg(db) {
|
|
14
|
+
const row = db.prepare('SELECT weight_kg FROM weight_log ORDER BY date DESC LIMIT 1').get();
|
|
15
|
+
return row?.weight_kg ?? 70;
|
|
16
|
+
}
|
|
17
|
+
function profileActivityLevel(db) {
|
|
18
|
+
const row = db.prepare('SELECT activity_level FROM user_profile WHERE id = 1').get();
|
|
19
|
+
return row?.activity_level ?? 'moderate';
|
|
20
|
+
}
|
|
21
|
+
export function dietCalorieTrend(db, startDate, endDate) {
|
|
22
|
+
const [start, end] = rangeOf(startDate, endDate);
|
|
23
|
+
const raw = db.prepare('SELECT date, SUM(calories) AS c, SUM(protein) AS p, SUM(carbs) AS cb, SUM(fat) AS f FROM food_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
|
|
24
|
+
const rows = raw.map((r) => [r.date, r.c, r.p, r.cb, r.f]);
|
|
25
|
+
if (rows.length === 0)
|
|
26
|
+
return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
|
|
27
|
+
const totalCal = rows.reduce((a, r) => a + (r[1] ?? 0), 0);
|
|
28
|
+
const avgCal = totalCal / rows.length;
|
|
29
|
+
const goal = db.prepare('SELECT calorie_goal FROM daily_goal WHERE id = 1').get();
|
|
30
|
+
const calGoal = goal?.calorie_goal ?? null;
|
|
31
|
+
const onTarget = calGoal ? rows.filter((r) => Math.abs((r[1] ?? 0) - calGoal) <= calGoal * 0.1).length : 0;
|
|
32
|
+
let weekdayCal = 0;
|
|
33
|
+
let weekendCal = 0;
|
|
34
|
+
let wdCount = 0;
|
|
35
|
+
let weCount = 0;
|
|
36
|
+
for (const r of rows) {
|
|
37
|
+
const wd = new Date(r[0] + 'T12:00:00Z').getUTCDay();
|
|
38
|
+
if (wd >= 1 && wd <= 5) {
|
|
39
|
+
weekdayCal += r[1] ?? 0;
|
|
40
|
+
wdCount += 1;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
weekendCal += r[1] ?? 0;
|
|
44
|
+
weCount += 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const wdAvg = wdCount > 0 ? weekdayCal / wdCount : 0;
|
|
48
|
+
const weAvg = weCount > 0 ? weekendCal / weCount : 0;
|
|
49
|
+
const daily = rows.map((r) => ({ date: r[0], totalCal: r[1] ?? 0, totalProtein: r[2] ?? 0, totalCarbs: r[3] ?? 0, totalFat: r[4] ?? 0 }));
|
|
50
|
+
return ok({ daysCount: rows.length, totalCal: round(totalCal), avgCal: round(avgCal), calGoal, complianceDays: onTarget, weekdayAvg: round(wdAvg), weekendAvg: round(weAvg), daily }, '热量趋势 ' + rows.length + ' 天,日均 ' + round(avgCal) + ' 卡');
|
|
51
|
+
}
|
|
52
|
+
function evalMacro(pct, macro, goal) {
|
|
53
|
+
if (!goal)
|
|
54
|
+
return null;
|
|
55
|
+
const calGoal = goal.calorie_goal ?? 1800;
|
|
56
|
+
const target = macro === 'protein'
|
|
57
|
+
? ((goal.protein_goal ?? 150) * 4) / calGoal * 100
|
|
58
|
+
: macro === 'carb' ? ((goal.carbs_goal ?? 200) * 4) / calGoal * 100 : ((goal.fat_goal ?? 60) * 9) / calGoal * 100;
|
|
59
|
+
const diff = pct - target;
|
|
60
|
+
return { pct: round(pct), targetPct: round(target), diff: round1(diff), status: diff > 3 ? 'high' : diff < -3 ? 'low' : 'ok' };
|
|
61
|
+
}
|
|
62
|
+
export function dietMacroRatio(db, startDate, endDate) {
|
|
63
|
+
const [start, end] = rangeOf(startDate, endDate);
|
|
64
|
+
const row = db.prepare('SELECT SUM(protein)*4 AS p, SUM(carbs)*4 AS c, SUM(fat)*9 AS f FROM food_log WHERE date >= ? AND date <= ?').get(start, end);
|
|
65
|
+
const parts = [row?.p ?? 0, row?.c ?? 0, row?.f ?? 0];
|
|
66
|
+
if (!row || parts[0] + parts[1] + parts[2] === 0)
|
|
67
|
+
return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
|
|
68
|
+
const total = parts[0] + parts[1] + parts[2];
|
|
69
|
+
const denom = total === 0 ? 1 : total;
|
|
70
|
+
const pctPro = (parts[0] / denom) * 100;
|
|
71
|
+
const pctCarb = (parts[1] / denom) * 100;
|
|
72
|
+
const pctFat = (parts[2] / denom) * 100;
|
|
73
|
+
const goal = db.prepare('SELECT calorie_goal, protein_goal, carbs_goal, fat_goal FROM daily_goal WHERE id = 1').get();
|
|
74
|
+
const g = goal ?? undefined;
|
|
75
|
+
return ok({ protein: evalMacro(pctPro, 'protein', g), carb: evalMacro(pctCarb, 'carb', g), fat: evalMacro(pctFat, 'fat', g) }, '营养配比 蛋白/碳水/脂肪 = ' + round(pctPro) + '/' + round(pctCarb) + '/' + round(pctFat));
|
|
76
|
+
}
|
|
77
|
+
const RANK_TITLES = {
|
|
78
|
+
high_calorie: '🔥 热量炸弹榜',
|
|
79
|
+
low_calorie: '🥬 低热量健康榜',
|
|
80
|
+
frequent: '📅 频繁吃榜',
|
|
81
|
+
high_carb: '🍚 高碳水榜',
|
|
82
|
+
high_protein: '💪 高蛋白榜',
|
|
83
|
+
};
|
|
84
|
+
function isWaterFood(name) {
|
|
85
|
+
return name.toLowerCase().includes('water') || name === '💧水';
|
|
86
|
+
}
|
|
87
|
+
export function dietFoodRanking(db, startDate, endDate, category = 'high_calorie', topN = 5) {
|
|
88
|
+
const [start, end] = rangeOf(startDate, endDate);
|
|
89
|
+
if (!Number.isInteger(topN) || topN < 1)
|
|
90
|
+
throw new FetchError('topN 须为正整数');
|
|
91
|
+
const raw = db.prepare('SELECT food_name AS n, SUM(calories) AS c, SUM(grams) AS g, SUM(protein) AS p, SUM(carbs) AS cb, SUM(fat) AS f, COUNT(*) AS cnt FROM food_log WHERE date >= ? AND date <= ? GROUP BY food_name').all(start, end);
|
|
92
|
+
const rows = raw.map((r) => [r.n, r.c, r.g, r.p, r.cb, r.f, r.cnt]);
|
|
93
|
+
if (rows.length === 0)
|
|
94
|
+
return rejection('无饮食记录(' + start + ' ~ ' + end + ')');
|
|
95
|
+
const filtered = category === 'low_calorie' || category === 'frequent' ? rows.filter((r) => !isWaterFood(r[0])) : rows;
|
|
96
|
+
if (filtered.length === 0)
|
|
97
|
+
return rejection('过滤后无记录(' + category + ')');
|
|
98
|
+
const byCal = (x) => x[1] ?? 0;
|
|
99
|
+
const sorted = [...filtered].sort((a, b) => {
|
|
100
|
+
if (category === 'low_calorie') {
|
|
101
|
+
const avA = byCal(a) / Math.max(a[6], 1);
|
|
102
|
+
const avB = byCal(b) / Math.max(b[6], 1);
|
|
103
|
+
return avA - avB;
|
|
104
|
+
}
|
|
105
|
+
if (category === 'frequent')
|
|
106
|
+
return b[6] - a[6];
|
|
107
|
+
if (category === 'high_carb')
|
|
108
|
+
return (b[4] ?? 0) - (a[4] ?? 0);
|
|
109
|
+
if (category === 'high_protein')
|
|
110
|
+
return (b[3] ?? 0) - (a[3] ?? 0);
|
|
111
|
+
return byCal(b) - byCal(a);
|
|
112
|
+
}).slice(0, topN);
|
|
113
|
+
const title = (RANK_TITLES[category] ?? '📋 食物榜') + '(' + start + ' ~ ' + end + ')';
|
|
114
|
+
const items = sorted.map((r, i) => ({
|
|
115
|
+
rank: i + 1,
|
|
116
|
+
foodName: r[0],
|
|
117
|
+
totalCal: r[1] ?? 0,
|
|
118
|
+
totalGrams: r[2] ?? 0,
|
|
119
|
+
totalProtein: r[3] ?? 0,
|
|
120
|
+
totalCarbs: r[4] ?? 0,
|
|
121
|
+
totalFat: r[5] ?? 0,
|
|
122
|
+
cnt: r[6],
|
|
123
|
+
avgCalPerMeal: Math.floor((r[1] ?? 0) / Math.max(r[6], 1)),
|
|
124
|
+
}));
|
|
125
|
+
return ok({ category, title, start, end, topN: items.length, items }, category + ' 榜单 TOP ' + items.length);
|
|
126
|
+
}
|
|
127
|
+
export function dietDeficitAnalysis(db, startDate, endDate) {
|
|
128
|
+
const [start, end] = rangeOf(startDate, endDate);
|
|
129
|
+
const dietRaw = db.prepare('SELECT date, SUM(calories) AS v FROM food_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
|
|
130
|
+
const dietRows = dietRaw.map((r) => [r.date, r.v]);
|
|
131
|
+
const exRaw = db.prepare('SELECT date, SUM(calories_burned) AS v FROM exercise_log WHERE date >= ? AND date <= ? GROUP BY date ORDER BY date ASC').all(start, end);
|
|
132
|
+
const exRows = exRaw.map((r) => [r.date, r.v]);
|
|
133
|
+
if (dietRows.length === 0)
|
|
134
|
+
return rejection('无记录(' + start + ' ~ ' + end + ')');
|
|
135
|
+
const dietMap = new Map(dietRows.map((r) => [r[0], r[1] ?? 0]));
|
|
136
|
+
const exMap = new Map(exRows.map((r) => [r[0], r[1] ?? 0]));
|
|
137
|
+
const days = dietMap.size;
|
|
138
|
+
const totalIntake = [...dietMap.values()].reduce((a, b) => a + b, 0);
|
|
139
|
+
const totalEx = [...exMap.values()].reduce((a, b) => a + b, 0);
|
|
140
|
+
const avgIntake = totalIntake / days;
|
|
141
|
+
const avgEx = totalEx / days;
|
|
142
|
+
const currentWeight = latestWeightKg(db);
|
|
143
|
+
const bmr = currentWeight * 24 * getActivityFactor(profileActivityLevel(db));
|
|
144
|
+
const avgDeficit = bmr + avgEx - avgIntake;
|
|
145
|
+
const totalDeficit = avgDeficit * days;
|
|
146
|
+
const kgEquivalent = totalDeficit / 7700;
|
|
147
|
+
const dietContrib = totalDeficit !== 0 ? (Math.abs(totalDeficit - totalEx * days) / Math.abs(totalDeficit)) * 100 : 0;
|
|
148
|
+
const exContrib = totalDeficit !== 0 ? (totalEx / Math.abs(totalDeficit)) * 100 : 0;
|
|
149
|
+
const sizeLabel = avgDeficit > 0 && avgDeficit < 300 ? '偏小' : avgDeficit > 700 ? '过大' : '正常';
|
|
150
|
+
return ok({
|
|
151
|
+
daysCount: days,
|
|
152
|
+
avgIntake: round(avgIntake),
|
|
153
|
+
bmr: round(bmr),
|
|
154
|
+
currentWeight: round1(currentWeight),
|
|
155
|
+
avgExerciseBurn: round(avgEx),
|
|
156
|
+
avgDeficit: round(avgDeficit),
|
|
157
|
+
totalDeficit: round(totalDeficit),
|
|
158
|
+
kgEquivalent: round2(kgEquivalent),
|
|
159
|
+
sizeLabel,
|
|
160
|
+
dietContribPct: round(dietContrib),
|
|
161
|
+
exerciseContribPct: round(exContrib),
|
|
162
|
+
}, '日均缺口 ' + round(avgDeficit) + ' 卡(' + sizeLabel + ')');
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=diet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diet.js","sourceRoot":"","sources":["../../src/analysis/diet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/** T5 #24 · 运动分析口径(对照老家 scripts/analysis/exercise.py)。
|
|
2
|
+
*
|
|
3
|
+
* exerciseTrend / exerciseTypeBreakdown / exerciseDeficitContribution /
|
|
4
|
+
* exerciseReview(计划 vs 实绩:完成率=实做组数/计划组数,B-305;容量聚合
|
|
5
|
+
* #257:plan 仅 unit 缺省或 kg 且 weight>0,actual 仅 load_kg>0;TOP4 按
|
|
6
|
+
* 计划+实绩合计;by_severity 计数)。只取结构化形状,不 print。
|
|
7
|
+
* BMR 口径:体重×24×系数(老家原样)。
|
|
8
|
+
*/
|
|
9
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
10
|
+
import type { AnalysisResult } from './result.js';
|
|
11
|
+
export interface ExerciseTrend {
|
|
12
|
+
daysWithExercise: number;
|
|
13
|
+
totalDays: number;
|
|
14
|
+
coveragePct: number;
|
|
15
|
+
totalCalories: number;
|
|
16
|
+
totalMinutes: number;
|
|
17
|
+
avgCaloriesPerDay: number;
|
|
18
|
+
avgMinutesPerDay: number | null;
|
|
19
|
+
longestStreakDays: number;
|
|
20
|
+
longestRestDays: number;
|
|
21
|
+
alert: string | null;
|
|
22
|
+
durationMissing: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function exerciseTrend(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<ExerciseTrend>;
|
|
25
|
+
export interface ExerciseTypeStat {
|
|
26
|
+
type: string;
|
|
27
|
+
calories: number;
|
|
28
|
+
count: number;
|
|
29
|
+
minutes: number;
|
|
30
|
+
calPct: number;
|
|
31
|
+
countPct: number;
|
|
32
|
+
minutesPct: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ExerciseBreakdown {
|
|
35
|
+
totalCalories: number;
|
|
36
|
+
totalCount: number;
|
|
37
|
+
totalMinutes: number;
|
|
38
|
+
types: ExerciseTypeStat[];
|
|
39
|
+
}
|
|
40
|
+
export declare function exerciseTypeBreakdown(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<ExerciseBreakdown>;
|
|
41
|
+
export interface DeficitContribution {
|
|
42
|
+
dietDeficit: number;
|
|
43
|
+
dietContribPct: number;
|
|
44
|
+
exerciseDeficit: number;
|
|
45
|
+
exerciseContribPct: number;
|
|
46
|
+
evaluation: string;
|
|
47
|
+
bmr: number;
|
|
48
|
+
currentWeight: number;
|
|
49
|
+
}
|
|
50
|
+
export declare function exerciseDeficitContribution(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<DeficitContribution>;
|
|
51
|
+
export interface ReviewAnomaly {
|
|
52
|
+
type: 'low_completion' | 'over_completion' | 'no_actual' | 'rest_but_done';
|
|
53
|
+
msg: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ReviewDay {
|
|
56
|
+
date: string;
|
|
57
|
+
planWeek: number | null;
|
|
58
|
+
sessions: string[];
|
|
59
|
+
planTotalSets: number;
|
|
60
|
+
actualTotalSets: number;
|
|
61
|
+
caloriesBurned: number;
|
|
62
|
+
completionRate: number | null;
|
|
63
|
+
anomalies: ReviewAnomaly[];
|
|
64
|
+
note: string | null;
|
|
65
|
+
isRestDay: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface ReviewMeta {
|
|
68
|
+
bySeverityCount: Record<string, number>;
|
|
69
|
+
totalDays: number;
|
|
70
|
+
trainDays: number;
|
|
71
|
+
restDays: number;
|
|
72
|
+
totalCalories: number;
|
|
73
|
+
volume: {
|
|
74
|
+
weeks: Array<{
|
|
75
|
+
week: string;
|
|
76
|
+
label: string;
|
|
77
|
+
plan: number;
|
|
78
|
+
actual: number;
|
|
79
|
+
actualSets: number;
|
|
80
|
+
}>;
|
|
81
|
+
movements: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
planTotal: number;
|
|
84
|
+
actualTotal: number;
|
|
85
|
+
weeks: Array<{
|
|
86
|
+
week: string;
|
|
87
|
+
label: string;
|
|
88
|
+
plan: number;
|
|
89
|
+
actual: number;
|
|
90
|
+
}>;
|
|
91
|
+
}>;
|
|
92
|
+
totalPlan: number;
|
|
93
|
+
totalActual: number;
|
|
94
|
+
hasActual: boolean;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export declare function exerciseReview(db: DatabaseSync, startDate: string, endDate?: string | null): AnalysisResult<Record<string, ReviewDay>>;
|
|
98
|
+
//# sourceMappingURL=exercise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exercise.d.ts","sourceRoot":"","sources":["../../src/analysis/exercise.ts"],"names":[],"mappings":"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"}
|