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.
Files changed (373) hide show
  1. package/dist/analysis/anomaly/common.d.ts +53 -0
  2. package/dist/analysis/anomaly/common.d.ts.map +1 -0
  3. package/dist/analysis/anomaly/common.js +69 -0
  4. package/dist/analysis/anomaly/common.js.map +1 -0
  5. package/dist/analysis/anomaly/diet.d.ts +8 -0
  6. package/dist/analysis/anomaly/diet.d.ts.map +1 -0
  7. package/dist/analysis/anomaly/diet.js +95 -0
  8. package/dist/analysis/anomaly/diet.js.map +1 -0
  9. package/dist/analysis/anomaly/exercise.d.ts +9 -0
  10. package/dist/analysis/anomaly/exercise.d.ts.map +1 -0
  11. package/dist/analysis/anomaly/exercise.js +116 -0
  12. package/dist/analysis/anomaly/exercise.js.map +1 -0
  13. package/dist/analysis/anomaly/index.d.ts +19 -0
  14. package/dist/analysis/anomaly/index.d.ts.map +1 -0
  15. package/dist/analysis/anomaly/index.js +51 -0
  16. package/dist/analysis/anomaly/index.js.map +1 -0
  17. package/dist/analysis/anomaly/overall.d.ts +13 -0
  18. package/dist/analysis/anomaly/overall.d.ts.map +1 -0
  19. package/dist/analysis/anomaly/overall.js +128 -0
  20. package/dist/analysis/anomaly/overall.js.map +1 -0
  21. package/dist/analysis/anomaly/overall2.d.ts +5 -0
  22. package/dist/analysis/anomaly/overall2.d.ts.map +1 -0
  23. package/dist/analysis/anomaly/overall2.js +94 -0
  24. package/dist/analysis/anomaly/overall2.js.map +1 -0
  25. package/dist/analysis/anomaly/weight.d.ts +8 -0
  26. package/dist/analysis/anomaly/weight.d.ts.map +1 -0
  27. package/dist/analysis/anomaly/weight.js +106 -0
  28. package/dist/analysis/anomaly/weight.js.map +1 -0
  29. package/dist/analysis/anomaly/weight2.d.ts +4 -0
  30. package/dist/analysis/anomaly/weight2.d.ts.map +1 -0
  31. package/dist/analysis/anomaly/weight2.js +59 -0
  32. package/dist/analysis/anomaly/weight2.js.map +1 -0
  33. package/dist/analysis/contraindications.d.ts +63 -0
  34. package/dist/analysis/contraindications.d.ts.map +1 -0
  35. package/dist/analysis/contraindications.js +121 -0
  36. package/dist/analysis/contraindications.js.map +1 -0
  37. package/dist/analysis/cross.d.ts +75 -0
  38. package/dist/analysis/cross.d.ts.map +1 -0
  39. package/dist/analysis/cross.js +283 -0
  40. package/dist/analysis/cross.js.map +1 -0
  41. package/dist/analysis/dashboard.d.ts +18 -0
  42. package/dist/analysis/dashboard.d.ts.map +1 -0
  43. package/dist/analysis/dashboard.js +48 -0
  44. package/dist/analysis/dashboard.js.map +1 -0
  45. package/dist/analysis/deficit.d.ts +44 -0
  46. package/dist/analysis/deficit.d.ts.map +1 -0
  47. package/dist/analysis/deficit.js +54 -0
  48. package/dist/analysis/deficit.js.map +1 -0
  49. package/dist/analysis/diet.d.ts +76 -0
  50. package/dist/analysis/diet.d.ts.map +1 -0
  51. package/dist/analysis/diet.js +164 -0
  52. package/dist/analysis/diet.js.map +1 -0
  53. package/dist/analysis/exercise.d.ts +98 -0
  54. package/dist/analysis/exercise.d.ts.map +1 -0
  55. package/dist/analysis/exercise.js +298 -0
  56. package/dist/analysis/exercise.js.map +1 -0
  57. package/dist/analysis/exerciseReview.d.ts +36 -0
  58. package/dist/analysis/exerciseReview.d.ts.map +1 -0
  59. package/dist/analysis/exerciseReview.js +50 -0
  60. package/dist/analysis/exerciseReview.js.map +1 -0
  61. package/dist/analysis/precision.d.ts +15 -0
  62. package/dist/analysis/precision.d.ts.map +1 -0
  63. package/dist/analysis/precision.js +38 -0
  64. package/dist/analysis/precision.js.map +1 -0
  65. package/dist/analysis/result.d.ts +15 -0
  66. package/dist/analysis/result.d.ts.map +1 -0
  67. package/dist/analysis/result.js +13 -0
  68. package/dist/analysis/result.js.map +1 -0
  69. package/dist/analysis/review.d.ts +118 -0
  70. package/dist/analysis/review.d.ts.map +1 -0
  71. package/dist/analysis/review.js +195 -0
  72. package/dist/analysis/review.js.map +1 -0
  73. package/dist/analysis/series.d.ts +42 -0
  74. package/dist/analysis/series.d.ts.map +1 -0
  75. package/dist/analysis/series.js +127 -0
  76. package/dist/analysis/series.js.map +1 -0
  77. package/dist/analysis/simulate.d.ts +43 -0
  78. package/dist/analysis/simulate.d.ts.map +1 -0
  79. package/dist/analysis/simulate.js +109 -0
  80. package/dist/analysis/simulate.js.map +1 -0
  81. package/dist/analysis/simulate2.d.ts +65 -0
  82. package/dist/analysis/simulate2.d.ts.map +1 -0
  83. package/dist/analysis/simulate2.js +173 -0
  84. package/dist/analysis/simulate2.js.map +1 -0
  85. package/dist/analysis/trend.d.ts +39 -0
  86. package/dist/analysis/trend.d.ts.map +1 -0
  87. package/dist/analysis/trend.js +48 -0
  88. package/dist/analysis/trend.js.map +1 -0
  89. package/dist/analysis/utils.d.ts +17 -0
  90. package/dist/analysis/utils.d.ts.map +1 -0
  91. package/dist/analysis/utils.js +52 -0
  92. package/dist/analysis/utils.js.map +1 -0
  93. package/dist/analysis/volatility.d.ts +43 -0
  94. package/dist/analysis/volatility.d.ts.map +1 -0
  95. package/dist/analysis/volatility.js +96 -0
  96. package/dist/analysis/volatility.js.map +1 -0
  97. package/dist/analysis/weight.d.ts +86 -0
  98. package/dist/analysis/weight.d.ts.map +1 -0
  99. package/dist/analysis/weight.js +219 -0
  100. package/dist/analysis/weight.js.map +1 -0
  101. package/dist/analysis/weightCompare.d.ts +63 -0
  102. package/dist/analysis/weightCompare.d.ts.map +1 -0
  103. package/dist/analysis/weightCompare.js +212 -0
  104. package/dist/analysis/weightCompare.js.map +1 -0
  105. package/dist/analysis/weightCompare2.d.ts +63 -0
  106. package/dist/analysis/weightCompare2.d.ts.map +1 -0
  107. package/dist/analysis/weightCompare2.js +211 -0
  108. package/dist/analysis/weightCompare2.js.map +1 -0
  109. package/dist/analysis/weightCompare3.d.ts +13 -0
  110. package/dist/analysis/weightCompare3.d.ts.map +1 -0
  111. package/dist/analysis/weightCompare3.js +199 -0
  112. package/dist/analysis/weightCompare3.js.map +1 -0
  113. package/dist/cli/cmd_read.d.ts +8 -0
  114. package/dist/cli/cmd_read.d.ts.map +1 -0
  115. package/dist/cli/cmd_read.js +719 -0
  116. package/dist/cli/cmd_read.js.map +1 -0
  117. package/dist/cli/keys.d.ts +333 -0
  118. package/dist/cli/keys.d.ts.map +1 -0
  119. package/dist/cli/keys.js +103 -0
  120. package/dist/cli/keys.js.map +1 -0
  121. package/dist/cli/write.d.ts +24 -0
  122. package/dist/cli/write.d.ts.map +1 -0
  123. package/dist/cli/write.js +832 -0
  124. package/dist/cli/write.js.map +1 -0
  125. package/dist/fetch/audit.d.ts +25 -0
  126. package/dist/fetch/audit.d.ts.map +1 -0
  127. package/dist/fetch/audit.js +46 -0
  128. package/dist/fetch/audit.js.map +1 -0
  129. package/dist/fetch/batch.d.ts +68 -0
  130. package/dist/fetch/batch.d.ts.map +1 -0
  131. package/dist/fetch/batch.js +183 -0
  132. package/dist/fetch/batch.js.map +1 -0
  133. package/dist/fetch/body.d.ts +89 -0
  134. package/dist/fetch/body.d.ts.map +1 -0
  135. package/dist/fetch/body.js +217 -0
  136. package/dist/fetch/body.js.map +1 -0
  137. package/dist/fetch/cli.d.ts +3 -0
  138. package/dist/fetch/cli.d.ts.map +1 -0
  139. package/dist/fetch/cli.js +195 -0
  140. package/dist/fetch/cli.js.map +1 -0
  141. package/dist/fetch/cross-skill.d.ts +29 -0
  142. package/dist/fetch/cross-skill.d.ts.map +1 -0
  143. package/dist/fetch/cross-skill.js +42 -0
  144. package/dist/fetch/cross-skill.js.map +1 -0
  145. package/dist/fetch/db.d.ts +5 -0
  146. package/dist/fetch/db.d.ts.map +1 -0
  147. package/dist/fetch/db.js +4 -0
  148. package/dist/fetch/db.js.map +1 -0
  149. package/dist/fetch/diet.d.ts +174 -0
  150. package/dist/fetch/diet.d.ts.map +1 -0
  151. package/dist/fetch/diet.js +239 -0
  152. package/dist/fetch/diet.js.map +1 -0
  153. package/dist/fetch/errors.d.ts +5 -0
  154. package/dist/fetch/errors.d.ts.map +1 -0
  155. package/dist/fetch/errors.js +8 -0
  156. package/dist/fetch/errors.js.map +1 -0
  157. package/dist/fetch/exercise.d.ts +72 -0
  158. package/dist/fetch/exercise.d.ts.map +1 -0
  159. package/dist/fetch/exercise.js +270 -0
  160. package/dist/fetch/exercise.js.map +1 -0
  161. package/dist/fetch/goal.d.ts +48 -0
  162. package/dist/fetch/goal.d.ts.map +1 -0
  163. package/dist/fetch/goal.js +73 -0
  164. package/dist/fetch/goal.js.map +1 -0
  165. package/dist/fetch/goalHistory.d.ts +24 -0
  166. package/dist/fetch/goalHistory.d.ts.map +1 -0
  167. package/dist/fetch/goalHistory.js +51 -0
  168. package/dist/fetch/goalHistory.js.map +1 -0
  169. package/dist/fetch/history.d.ts +28 -0
  170. package/dist/fetch/history.d.ts.map +1 -0
  171. package/dist/fetch/history.js +29 -0
  172. package/dist/fetch/history.js.map +1 -0
  173. package/dist/fetch/index.d.ts +23 -0
  174. package/dist/fetch/index.d.ts.map +1 -0
  175. package/dist/fetch/index.js +16 -0
  176. package/dist/fetch/index.js.map +1 -0
  177. package/dist/fetch/nutritionGoal.d.ts +115 -0
  178. package/dist/fetch/nutritionGoal.d.ts.map +1 -0
  179. package/dist/fetch/nutritionGoal.js +154 -0
  180. package/dist/fetch/nutritionGoal.js.map +1 -0
  181. package/dist/fetch/photos.d.ts +76 -0
  182. package/dist/fetch/photos.d.ts.map +1 -0
  183. package/dist/fetch/photos.js +193 -0
  184. package/dist/fetch/photos.js.map +1 -0
  185. package/dist/fetch/plan.d.ts +145 -0
  186. package/dist/fetch/plan.d.ts.map +1 -0
  187. package/dist/fetch/plan.js +258 -0
  188. package/dist/fetch/plan.js.map +1 -0
  189. package/dist/fetch/products.d.ts +62 -0
  190. package/dist/fetch/products.d.ts.map +1 -0
  191. package/dist/fetch/products.js +73 -0
  192. package/dist/fetch/products.js.map +1 -0
  193. package/dist/fetch/profile.d.ts +46 -0
  194. package/dist/fetch/profile.d.ts.map +1 -0
  195. package/dist/fetch/profile.js +105 -0
  196. package/dist/fetch/profile.js.map +1 -0
  197. package/dist/fetch/shapes.d.ts +41 -0
  198. package/dist/fetch/shapes.d.ts.map +1 -0
  199. package/dist/fetch/shapes.js +38 -0
  200. package/dist/fetch/shapes.js.map +1 -0
  201. package/dist/fetch/validate.d.ts +11 -0
  202. package/dist/fetch/validate.d.ts.map +1 -0
  203. package/dist/fetch/validate.js +64 -0
  204. package/dist/fetch/validate.js.map +1 -0
  205. package/dist/fetch/weight.d.ts +109 -0
  206. package/dist/fetch/weight.d.ts.map +1 -0
  207. package/dist/fetch/weight.js +210 -0
  208. package/dist/fetch/weight.js.map +1 -0
  209. package/dist/fetch/xunji-catalog.d.ts +17 -0
  210. package/dist/fetch/xunji-catalog.d.ts.map +1 -0
  211. package/dist/fetch/xunji-catalog.js +57 -0
  212. package/dist/fetch/xunji-catalog.js.map +1 -0
  213. package/dist/index.d.ts +17 -0
  214. package/dist/index.d.ts.map +1 -0
  215. package/dist/index.js +12 -0
  216. package/dist/index.js.map +1 -0
  217. package/dist/kcal.d.ts +21 -0
  218. package/dist/kcal.d.ts.map +1 -0
  219. package/dist/kcal.js +27 -0
  220. package/dist/kcal.js.map +1 -0
  221. package/dist/migrate/migrate.d.ts +71 -0
  222. package/dist/migrate/migrate.d.ts.map +1 -0
  223. package/dist/migrate/migrate.js +450 -0
  224. package/dist/migrate/migrate.js.map +1 -0
  225. package/dist/paths.d.ts +6 -0
  226. package/dist/paths.d.ts.map +1 -0
  227. package/dist/paths.js +34 -0
  228. package/dist/paths.js.map +1 -0
  229. package/dist/render/analysisPlate.d.ts +49 -0
  230. package/dist/render/analysisPlate.d.ts.map +1 -0
  231. package/dist/render/analysisPlate.js +149 -0
  232. package/dist/render/analysisPlate.js.map +1 -0
  233. package/dist/render/bodyPlate.d.ts +55 -0
  234. package/dist/render/bodyPlate.d.ts.map +1 -0
  235. package/dist/render/bodyPlate.js +97 -0
  236. package/dist/render/bodyPlate.js.map +1 -0
  237. package/dist/render/diet.d.ts +47 -0
  238. package/dist/render/diet.d.ts.map +1 -0
  239. package/dist/render/diet.js +94 -0
  240. package/dist/render/diet.js.map +1 -0
  241. package/dist/render/envelope.d.ts +60 -0
  242. package/dist/render/envelope.d.ts.map +1 -0
  243. package/dist/render/envelope.js +111 -0
  244. package/dist/render/envelope.js.map +1 -0
  245. package/dist/render/errors.d.ts +10 -0
  246. package/dist/render/errors.d.ts.map +1 -0
  247. package/dist/render/errors.js +9 -0
  248. package/dist/render/errors.js.map +1 -0
  249. package/dist/render/exercise.d.ts +20 -0
  250. package/dist/render/exercise.d.ts.map +1 -0
  251. package/dist/render/exercise.js +32 -0
  252. package/dist/render/exercise.js.map +1 -0
  253. package/dist/render/goal.d.ts +24 -0
  254. package/dist/render/goal.d.ts.map +1 -0
  255. package/dist/render/goal.js +23 -0
  256. package/dist/render/goal.js.map +1 -0
  257. package/dist/render/goalExtra.d.ts +45 -0
  258. package/dist/render/goalExtra.d.ts.map +1 -0
  259. package/dist/render/goalExtra.js +94 -0
  260. package/dist/render/goalExtra.js.map +1 -0
  261. package/dist/render/goalPlate.d.ts +66 -0
  262. package/dist/render/goalPlate.d.ts.map +1 -0
  263. package/dist/render/goalPlate.js +110 -0
  264. package/dist/render/goalPlate.js.map +1 -0
  265. package/dist/render/health.d.ts +21 -0
  266. package/dist/render/health.d.ts.map +1 -0
  267. package/dist/render/health.js +41 -0
  268. package/dist/render/health.js.map +1 -0
  269. package/dist/render/help.d.ts +18 -0
  270. package/dist/render/help.d.ts.map +1 -0
  271. package/dist/render/help.js +58 -0
  272. package/dist/render/help.js.map +1 -0
  273. package/dist/render/home.d.ts +30 -0
  274. package/dist/render/home.d.ts.map +1 -0
  275. package/dist/render/home.js +73 -0
  276. package/dist/render/home.js.map +1 -0
  277. package/dist/render/html.d.ts +66 -0
  278. package/dist/render/html.d.ts.map +1 -0
  279. package/dist/render/html.js +510 -0
  280. package/dist/render/html.js.map +1 -0
  281. package/dist/render/index.d.ts +47 -0
  282. package/dist/render/index.d.ts.map +1 -0
  283. package/dist/render/index.js +26 -0
  284. package/dist/render/index.js.map +1 -0
  285. package/dist/render/insightPlate.d.ts +55 -0
  286. package/dist/render/insightPlate.d.ts.map +1 -0
  287. package/dist/render/insightPlate.js +97 -0
  288. package/dist/render/insightPlate.js.map +1 -0
  289. package/dist/render/library.d.ts +32 -0
  290. package/dist/render/library.d.ts.map +1 -0
  291. package/dist/render/library.js +54 -0
  292. package/dist/render/library.js.map +1 -0
  293. package/dist/render/photo.d.ts +101 -0
  294. package/dist/render/photo.d.ts.map +1 -0
  295. package/dist/render/photo.js +241 -0
  296. package/dist/render/photo.js.map +1 -0
  297. package/dist/render/planPlate.d.ts +40 -0
  298. package/dist/render/planPlate.d.ts.map +1 -0
  299. package/dist/render/planPlate.js +72 -0
  300. package/dist/render/planPlate.js.map +1 -0
  301. package/dist/render/profilePlate.d.ts +17 -0
  302. package/dist/render/profilePlate.d.ts.map +1 -0
  303. package/dist/render/profilePlate.js +18 -0
  304. package/dist/render/profilePlate.js.map +1 -0
  305. package/dist/render/ranking.d.ts +22 -0
  306. package/dist/render/ranking.d.ts.map +1 -0
  307. package/dist/render/ranking.js +63 -0
  308. package/dist/render/ranking.js.map +1 -0
  309. package/dist/render/receipt.d.ts +71 -0
  310. package/dist/render/receipt.d.ts.map +1 -0
  311. package/dist/render/receipt.js +65 -0
  312. package/dist/render/receipt.js.map +1 -0
  313. package/dist/render/weightPlate.d.ts +54 -0
  314. package/dist/render/weightPlate.d.ts.map +1 -0
  315. package/dist/render/weightPlate.js +110 -0
  316. package/dist/render/weightPlate.js.map +1 -0
  317. package/dist/schema.d.ts +25 -0
  318. package/dist/schema.d.ts.map +1 -0
  319. package/dist/schema.js +281 -0
  320. package/dist/schema.js.map +1 -0
  321. package/dist/triggers/help-lookup.d.ts +28 -0
  322. package/dist/triggers/help-lookup.d.ts.map +1 -0
  323. package/dist/triggers/help-lookup.js +163 -0
  324. package/dist/triggers/help-lookup.js.map +1 -0
  325. package/dist/triggers/index.d.ts +24 -0
  326. package/dist/triggers/index.d.ts.map +1 -0
  327. package/dist/triggers/index.js +78 -0
  328. package/dist/triggers/index.js.map +1 -0
  329. package/dist/triggers/scene-01-home.d.ts +4 -0
  330. package/dist/triggers/scene-01-home.d.ts.map +1 -0
  331. package/dist/triggers/scene-01-home.js +13 -0
  332. package/dist/triggers/scene-01-home.js.map +1 -0
  333. package/dist/triggers/scene-02-diet.d.ts +4 -0
  334. package/dist/triggers/scene-02-diet.d.ts.map +1 -0
  335. package/dist/triggers/scene-02-diet.js +74 -0
  336. package/dist/triggers/scene-02-diet.js.map +1 -0
  337. package/dist/triggers/scene-03-weight.d.ts +4 -0
  338. package/dist/triggers/scene-03-weight.d.ts.map +1 -0
  339. package/dist/triggers/scene-03-weight.js +62 -0
  340. package/dist/triggers/scene-03-weight.js.map +1 -0
  341. package/dist/triggers/scene-04-exercise.d.ts +4 -0
  342. package/dist/triggers/scene-04-exercise.d.ts.map +1 -0
  343. package/dist/triggers/scene-04-exercise.js +43 -0
  344. package/dist/triggers/scene-04-exercise.js.map +1 -0
  345. package/dist/triggers/scene-05-workout.d.ts +4 -0
  346. package/dist/triggers/scene-05-workout.d.ts.map +1 -0
  347. package/dist/triggers/scene-05-workout.js +36 -0
  348. package/dist/triggers/scene-05-workout.js.map +1 -0
  349. package/dist/triggers/scene-06-goal.d.ts +4 -0
  350. package/dist/triggers/scene-06-goal.d.ts.map +1 -0
  351. package/dist/triggers/scene-06-goal.js +29 -0
  352. package/dist/triggers/scene-06-goal.js.map +1 -0
  353. package/dist/triggers/scene-07-profile.d.ts +4 -0
  354. package/dist/triggers/scene-07-profile.d.ts.map +1 -0
  355. package/dist/triggers/scene-07-profile.js +8 -0
  356. package/dist/triggers/scene-07-profile.js.map +1 -0
  357. package/dist/triggers/scene-08-body.d.ts +4 -0
  358. package/dist/triggers/scene-08-body.d.ts.map +1 -0
  359. package/dist/triggers/scene-08-body.js +17 -0
  360. package/dist/triggers/scene-08-body.js.map +1 -0
  361. package/dist/triggers/scene-09-photo.d.ts +4 -0
  362. package/dist/triggers/scene-09-photo.d.ts.map +1 -0
  363. package/dist/triggers/scene-09-photo.js +14 -0
  364. package/dist/triggers/scene-09-photo.js.map +1 -0
  365. package/dist/triggers/scene-10-analysis.d.ts +4 -0
  366. package/dist/triggers/scene-10-analysis.d.ts.map +1 -0
  367. package/dist/triggers/scene-10-analysis.js +180 -0
  368. package/dist/triggers/scene-10-analysis.js.map +1 -0
  369. package/dist/triggers/types.d.ts +66 -0
  370. package/dist/triggers/types.d.ts.map +1 -0
  371. package/dist/triggers/types.js +3 -0
  372. package/dist/triggers/types.js.map +1 -0
  373. package/package.json +35 -0
@@ -0,0 +1,270 @@
1
+ import { sql } from './db.js';
2
+ import { FetchError } from './errors.js';
3
+ function todayStr() { return new Date().toISOString().slice(0, 10); }
4
+ function nowTime() { return new Date().toTimeString().slice(0, 8); }
5
+ function nowStamp() {
6
+ const d = new Date();
7
+ return `${d.toISOString().slice(0, 10)} ${d.toTimeString().slice(0, 8)}`;
8
+ }
9
+ /** MET 关键词表(顺序敏感,对照 _lookup_met 先后)。 */
10
+ const MET_RULES = [
11
+ { keys: ['哑铃', '杠铃', '史密斯', '弯举', '推举', '推肩', '平举', '深蹲', '卧推', '划船', '硬拉', '飞鸟'], met: 5.0 },
12
+ { keys: ['俯卧撑', '引体', '自重', '平板'], met: 3.8 },
13
+ { keys: ['跑步机'], met: 7.5 },
14
+ { keys: ['户外跑', '路跑'], met: 8.0 },
15
+ { keys: ['慢跑', '快跑', '冲刺'], met: 9.0 },
16
+ { keys: ['骑行', '自行车', '小黄车', '骑车'], met: 6.0 },
17
+ { keys: ['跳绳'], met: 12.0 },
18
+ { keys: ['椭圆机'], met: 5.5 },
19
+ { keys: ['游泳'], met: 7.0 },
20
+ { keys: ['hiit'], met: 8.5 },
21
+ { keys: ['八段锦', '太极', '瑜伽', '拉伸', '冥想'], met: 2.5 },
22
+ { keys: ['家务', '做饭', '洗衣', '打扫', '清洁'], met: 2.5 },
23
+ { keys: ['走路', '散步'], met: 3.0 },
24
+ { keys: ['通勤'], met: 2.5 },
25
+ { keys: ['爬楼', '楼梯'], met: 4.0 },
26
+ ];
27
+ export function lookupMet(exerciseType) {
28
+ if (!exerciseType)
29
+ return 3.0;
30
+ const et = exerciseType.toLowerCase();
31
+ for (const rule of MET_RULES) {
32
+ if (rule.keys.some((k) => et.includes(k.toLowerCase())))
33
+ return rule.met;
34
+ }
35
+ // 兜底“跑步”类(排除跑步机,已在上表先行命中)。
36
+ if (et.includes('跑'))
37
+ return 8.0;
38
+ return 3.0;
39
+ }
40
+ const STRENGTH_KEYS = ['哑铃', '杠铃', '史密斯', '弯举', '推举', '推肩', '平举', '前平举', '侧平举', '深蹲', '卧推', '划船', '硬拉', '飞鸟', '俯卧撑', '引体', '自重', '平板'];
41
+ const FLEX_KEYS = ['八段锦', '太极', '瑜伽', '拉伸', '冥想'];
42
+ const DAILY_KEYS = ['家务', '做饭', '洗衣', '打扫', '清洁', '通勤', '走路', '散步', '爬楼'];
43
+ export function inferCategory(exerciseType) {
44
+ if (!exerciseType)
45
+ return '有氧';
46
+ if (STRENGTH_KEYS.some((k) => exerciseType.includes(k)))
47
+ return '力量';
48
+ if (FLEX_KEYS.some((k) => exerciseType.includes(k)))
49
+ return '柔韧';
50
+ if (DAILY_KEYS.some((k) => exerciseType.includes(k)))
51
+ return '日常';
52
+ return '有氧';
53
+ }
54
+ export function estimateCaloriesMet(exerciseType, bodyWeight, durationMinutes, sets = 0) {
55
+ const met = lookupMet(exerciseType);
56
+ const category = inferCategory(exerciseType);
57
+ if (category === '有氧' || category === '柔韧' || category === '日常') {
58
+ if (!durationMinutes || durationMinutes <= 0)
59
+ return [0.0, met];
60
+ return [Math.round(met * bodyWeight * (durationMinutes / 60) * 10) / 10, met];
61
+ }
62
+ if (category === '力量') {
63
+ const s = sets <= 0 ? 1 : sets;
64
+ return [Math.round(met * bodyWeight * s * 0.05 * 10) / 10, met];
65
+ }
66
+ return [0.0, met];
67
+ }
68
+ export function estimateDifficultyMet(met) {
69
+ if (met === null || met === undefined || met <= 0)
70
+ return null;
71
+ if (met < 3)
72
+ return 'easy';
73
+ if (met < 6)
74
+ return 'normal';
75
+ return 'hard';
76
+ }
77
+ const HARD_WORDS = ['累死', '力竭', '极限', '干不动', '暴毙', '撑不住', '想死', '不行', '很累', '挺累', '暴汗', '喘', '气喘吁吁', '出汗多', '冲', '狠', 'hard', 'hiit'];
78
+ const EASY_WORDS = ['轻松', '没什么', '没感觉', '微微', '散步', 'easy', '很轻'];
79
+ const MID_WORDS = ['一般', '还行', '中等', '普通', '正常', '适中', '中等强度'];
80
+ /** 口语难度映射(老家原样口径:中等档返回 '中',非 'normal')。 */
81
+ export function parseUserDifficulty(userText) {
82
+ if (!userText)
83
+ return null;
84
+ const t = userText.toLowerCase();
85
+ if (HARD_WORDS.some((k) => t.includes(k.toLowerCase())))
86
+ return 'hard';
87
+ if (EASY_WORDS.some((k) => t.includes(k.toLowerCase())))
88
+ return 'easy';
89
+ if (MID_WORDS.some((k) => t.includes(k)))
90
+ return '中';
91
+ return null;
92
+ }
93
+ export function combinedCalories(userReported, estimated, warnAt = 0.5) {
94
+ if (userReported === null || userReported === undefined)
95
+ return [Math.round(estimated * 10) / 10, null, 0.0];
96
+ if (estimated <= 0)
97
+ return [Number(userReported), null, 0.0];
98
+ const deviation = Math.abs(Number(userReported) - estimated) / estimated;
99
+ const suffix = `你报 ${userReported}/AI ${Math.round(estimated * 10) / 10}/偏差 ${Math.trunc(deviation * 100)}%`;
100
+ if (deviation < 0.2)
101
+ return [Math.round(estimated * 10) / 10, suffix, deviation];
102
+ if (deviation < warnAt)
103
+ return [Math.round((Number(userReported) + estimated) / 2 * 10) / 10, `${suffix}/取中位`, deviation];
104
+ return [null, `${suffix}/需确认`, deviation];
105
+ }
106
+ export function estimateCaloriesFromTraining(totalVolumeKg) {
107
+ if (totalVolumeKg <= 0)
108
+ return 0.0;
109
+ return Math.round(totalVolumeKg * 0.08 * 10) / 10;
110
+ }
111
+ export function convertLoadKg(weightStr, unitStr) {
112
+ const w = parseFloat(String(weightStr));
113
+ if (!Number.isFinite(w))
114
+ return 0.0;
115
+ if (unitStr && String(unitStr).toLowerCase() === 'lbs')
116
+ return Math.round(w * 0.45359237 * 10) / 10;
117
+ return Math.round(w * 10) / 10;
118
+ }
119
+ export function resolveWindow(opts = {}) {
120
+ const now = opts.now ?? new Date();
121
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
122
+ const iso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
123
+ const addDays = (d, n) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + n);
124
+ const { window, days, fromDate, toDate } = opts;
125
+ if (window === 'today')
126
+ return [iso(today), iso(today)];
127
+ if (window === 'yesterday') {
128
+ const d = addDays(today, -1);
129
+ return [iso(d), iso(d)];
130
+ }
131
+ if (window === 'week') {
132
+ // 老家 weekday() 周一=0;JS getDay() 周日=0 → 换算。(JS+6)%7 即周一偏移。
133
+ const start = addDays(today, -((today.getDay() + 6) % 7));
134
+ return [iso(start), iso(today)];
135
+ }
136
+ if (window === 'last-week') {
137
+ const thisStart = addDays(today, -((today.getDay() + 6) % 7));
138
+ const end = addDays(thisStart, -1);
139
+ return [iso(addDays(end, -6)), iso(end)];
140
+ }
141
+ if (window === 'month')
142
+ return [iso(new Date(today.getFullYear(), today.getMonth(), 1)), iso(today)];
143
+ if (window === 'last-month') {
144
+ const first = new Date(today.getFullYear(), today.getMonth(), 1);
145
+ const end = addDays(first, -1);
146
+ return [iso(new Date(end.getFullYear(), end.getMonth(), 1)), iso(end)];
147
+ }
148
+ if (days)
149
+ return [iso(addDays(today, -(days - 1))), iso(today)];
150
+ if (fromDate)
151
+ return [fromDate, toDate ?? iso(today)];
152
+ return [iso(today), iso(today)];
153
+ }
154
+ export function parseTimeStr(timeStr) {
155
+ if (!timeStr)
156
+ return nowTime();
157
+ if (/^\d{2}:\d{2}:\d{2}$/.test(timeStr))
158
+ return timeStr;
159
+ const m2 = /^(\d{2}):(\d{2})$/.exec(timeStr);
160
+ if (m2)
161
+ return `${m2[1]}:${m2[2]}:00`;
162
+ return nowTime();
163
+ }
164
+ const LIVE_COLS = 'date, time, exercise_type, duration_minutes, calories_burned, note, reps, category, difficulty, distance_km, avg_heart_rate, set_index, load_kg, steps, max_heart_rate, is_backfill';
165
+ export function addRecord(db, input) {
166
+ const time = parseTimeStr(input.timeStr);
167
+ const info = db.prepare(`INSERT INTO exercise_log (${LIVE_COLS}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(input.date, time, input.exerciseType, input.minutes ?? null, input.caloriesBurned, input.note ?? '', input.reps ?? null, input.category ?? null, input.difficulty ?? null, input.distance ?? null, input.heartRate ?? null, input.setIndex ?? null, input.loadKg ?? null, input.steps ?? null, input.maxHeartRate ?? null, input.isBackfill ? 1 : 0);
168
+ const id = Number(info.lastInsertRowid);
169
+ return {
170
+ id,
171
+ record: {
172
+ id, date: input.date, time, exercise_type: input.exerciseType, duration_minutes: input.minutes ?? null,
173
+ calories_burned: input.caloriesBurned, note: input.note ?? '', reps: input.reps ?? null,
174
+ category: input.category ?? null, difficulty: input.difficulty ?? null, distance_km: input.distance ?? null,
175
+ avg_heart_rate: input.heartRate ?? null, max_heart_rate: input.maxHeartRate ?? null,
176
+ steps: input.steps ?? null, set_index: input.setIndex ?? null, load_kg: input.loadKg ?? null,
177
+ is_backfill: input.isBackfill ? 1 : 0,
178
+ },
179
+ };
180
+ }
181
+ const KNOWN_EX_COLS = new Set([
182
+ 'date', 'time', 'exercise_type', 'duration_minutes', 'calories_burned', 'note',
183
+ 'reps', 'category', 'difficulty', 'distance_km', 'avg_heart_rate', 'max_heart_rate',
184
+ 'steps', 'set_index', 'load_kg', 'is_backfill', 'is_deleted', 'xunji_localid', 'xunji_title',
185
+ ]);
186
+ export function updateRecord(db, recordId, fields) {
187
+ const id = Number(recordId);
188
+ if (!Number.isInteger(id))
189
+ throw new FetchError('记录 ID 必须是数字');
190
+ const old = db.prepare('SELECT * FROM exercise_log WHERE id = ?').get(id);
191
+ if (!old)
192
+ throw new FetchError(`记录 ID ${id} 不存在`);
193
+ const sets = [];
194
+ const vals = [];
195
+ for (const [col, val] of Object.entries(fields)) {
196
+ if (!KNOWN_EX_COLS.has(col))
197
+ throw new FetchError(`未知字段: ${col}`);
198
+ sets.push(`${col} = ?`);
199
+ vals.push(sql(val));
200
+ }
201
+ if (sets.length) {
202
+ db.prepare(`UPDATE exercise_log SET ${sets.join(', ')}, updated_at = ? WHERE id = ?`)
203
+ .run(...vals, nowStamp(), id);
204
+ }
205
+ const row = db.prepare('SELECT * FROM exercise_log WHERE id = ?').get(id);
206
+ return { old, new: row };
207
+ }
208
+ function softDeleteWhere(db, where, params) {
209
+ const info = db.prepare(`UPDATE exercise_log SET is_deleted = 1, updated_at = ? WHERE ${where} AND COALESCE(is_deleted, 0) = 0`).run(nowStamp(), ...params);
210
+ return Number(info.changes);
211
+ }
212
+ export function deleteRecord(db, recordId) {
213
+ const id = Number(recordId);
214
+ if (!Number.isInteger(id))
215
+ throw new FetchError('记录 ID 必须是数字');
216
+ const row = db.prepare('SELECT * FROM exercise_log WHERE id = ?').get(id);
217
+ if (!row)
218
+ throw new FetchError(`记录 ID ${id} 不存在`);
219
+ db.prepare('UPDATE exercise_log SET is_deleted = 1, updated_at = ? WHERE id = ?').run(nowStamp(), id);
220
+ return row;
221
+ }
222
+ export function deleteDay(db, date) {
223
+ return softDeleteWhere(db, 'date = ?', [date]);
224
+ }
225
+ export function deleteRange(db, fromDate, toDate) {
226
+ return softDeleteWhere(db, 'date BETWEEN ? AND ?', [fromDate, toDate]);
227
+ }
228
+ export function updateDay(db, date, fields) {
229
+ const ids = db.prepare('SELECT id FROM exercise_log WHERE date = ? AND COALESCE(is_deleted, 0) = 0').all(date)
230
+ .map((r) => r.id);
231
+ const pairs = ids.map((id) => updateRecord(db, id, fields));
232
+ return { matched: ids.length, pairs };
233
+ }
234
+ export function copyYesterday(db, targetDate) {
235
+ const target = targetDate ?? todayStr();
236
+ const y = new Date(target + 'T00:00:00');
237
+ y.setDate(y.getDate() - 1);
238
+ const src = `${y.getFullYear()}-${String(y.getMonth() + 1).padStart(2, '0')}-${String(y.getDate()).padStart(2, '0')}`;
239
+ const rows = db.prepare('SELECT * FROM exercise_log WHERE date = ? AND COALESCE(is_deleted, 0) = 0').all(src);
240
+ let copied = 0, skipped = 0;
241
+ const out = [];
242
+ for (const r of rows) {
243
+ const hit = db.prepare('SELECT id FROM exercise_log WHERE date = ? AND exercise_type = ? AND calories_burned = ? AND duration_minutes = ? AND COALESCE(is_deleted, 0) = 0 LIMIT 1').get(target, sql(r.exercise_type), sql(r.calories_burned), sql(r.duration_minutes));
244
+ if (hit) {
245
+ skipped++;
246
+ continue;
247
+ }
248
+ const { id } = addRecord(db, {
249
+ date: target, exerciseType: String(r.exercise_type), caloriesBurned: Number(r.calories_burned),
250
+ minutes: r.duration_minutes, timeStr: r.time, note: String(r.note ?? ''),
251
+ reps: r.reps, category: r.category, difficulty: r.difficulty,
252
+ distance: r.distance_km, heartRate: r.avg_heart_rate,
253
+ maxHeartRate: r.max_heart_rate, steps: r.steps,
254
+ setIndex: r.set_index, loadKg: r.load_kg,
255
+ });
256
+ copied++;
257
+ out.push(db.prepare('SELECT * FROM exercise_log WHERE id = ?').get(id));
258
+ }
259
+ return { copied, skipped, rows: out };
260
+ }
261
+ export function batchAdd(db, items) {
262
+ const ids = [];
263
+ for (const it of items)
264
+ ids.push(addRecord(db, it).id);
265
+ return { added: ids.length, ids };
266
+ }
267
+ export function listWindow(db, start, end) {
268
+ return db.prepare('SELECT * FROM exercise_log WHERE date BETWEEN ? AND ? AND COALESCE(is_deleted, 0) = 0 ORDER BY date, time').all(start, end);
269
+ }
270
+ //# sourceMappingURL=exercise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exercise.js","sourceRoot":"","sources":["../../src/fetch/exercise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** T4 #23 · goal_manager 取数+状态写(对照老家 scripts/goal_manager.py)。
2
+ *
3
+ * T3 范式:失败抛 FetchError,不 print(打印归 T11 CLI)。
4
+ * 一处有意偏离:老家无 daily_goal 行时 UPDATE 0 行后取 row['id'] 直接崩溃;
5
+ * TS 线先 ensureGoalRow(INSERT OR IGNORE 默认行),崩溃转显式可运行语义。
6
+ */
7
+ import type { DatabaseSync } from 'node:sqlite';
8
+ export interface PausedState {
9
+ paused: boolean;
10
+ pausedAt: string | null;
11
+ }
12
+ export interface PauseResult {
13
+ id: number;
14
+ updatedAt: string | null;
15
+ rowsAffected: number;
16
+ paused: true;
17
+ note: string;
18
+ restoreHint: string;
19
+ }
20
+ export interface ResumeResult {
21
+ id: number;
22
+ updatedAt: string | null;
23
+ rowsAffected: number;
24
+ resumeState: string;
25
+ resumedAt: string | null;
26
+ }
27
+ /** 单例行兜底(INSERT OR IGNORE,全默认列)。 */
28
+ export declare function ensureGoalRow(db: DatabaseSync): void;
29
+ export declare function getPausedState(db: DatabaseSync): PausedState;
30
+ export declare function pauseAllGoals(db: DatabaseSync): PauseResult;
31
+ export interface SetWeightGoalInput {
32
+ kg: unknown;
33
+ deadline?: unknown;
34
+ startKg?: unknown;
35
+ startDate?: unknown;
36
+ }
37
+ export interface SetWeightGoalResult {
38
+ weightGoal: number;
39
+ deadline: string | null;
40
+ startKg: number | null;
41
+ startDate: string | null;
42
+ updatedAt: string | null;
43
+ rowsAffected: number;
44
+ }
45
+ /** 定体重目标(对照老家 render_goal_weight --live:目标 kg 必填,截止/起点可选;ISO 日期校验)。 */
46
+ export declare function setWeightGoal(db: DatabaseSync, input: SetWeightGoalInput): SetWeightGoalResult;
47
+ export declare function resumeAllGoals(db: DatabaseSync): ResumeResult;
48
+ //# sourceMappingURL=goal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../src/fetch/goal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAEpD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAM5D;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAiB3D;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CAwB9F;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,YAAY,CAgB7D"}
@@ -0,0 +1,73 @@
1
+ import { FetchError } from './errors.js';
2
+ /** 单例行兜底(INSERT OR IGNORE,全默认列)。 */
3
+ export function ensureGoalRow(db) {
4
+ db.prepare('INSERT OR IGNORE INTO daily_goal (id) VALUES (1)').run();
5
+ }
6
+ export function getPausedState(db) {
7
+ const row = db.prepare('SELECT goal_paused, updated_at FROM daily_goal WHERE id = 1').get();
8
+ if (!row)
9
+ return { paused: false, pausedAt: null };
10
+ return { paused: row.goal_paused === 1, pausedAt: row.updated_at };
11
+ }
12
+ export function pauseAllGoals(db) {
13
+ ensureGoalRow(db);
14
+ const upd = db
15
+ .prepare('UPDATE daily_goal SET goal_paused = 1, updated_at = CURRENT_TIMESTAMP WHERE id = 1')
16
+ .run();
17
+ const row = db.prepare('SELECT id, updated_at FROM daily_goal WHERE id = 1').get();
18
+ if (!row)
19
+ throw new FetchError('pause 后 daily_goal#1 缺失');
20
+ return {
21
+ id: row.id,
22
+ updatedAt: row.updated_at,
23
+ rowsAffected: Number(upd.changes),
24
+ paused: true,
25
+ note: '记录照常,仅目标暂停(完成度显示不计入暂停期)',
26
+ restoreHint: '说「重启所有目标」即可恢复',
27
+ };
28
+ }
29
+ /** 定体重目标(对照老家 render_goal_weight --live:目标 kg 必填,截止/起点可选;ISO 日期校验)。 */
30
+ export function setWeightGoal(db, input) {
31
+ const kg = typeof input.kg === 'number' ? input.kg : Number(String(input.kg ?? '').trim());
32
+ if (!Number.isFinite(kg) || kg <= 0 || kg > 500)
33
+ throw new FetchError('体重目标非法:' + JSON.stringify(input.kg) + '(须 0..500 正数 kg)');
34
+ const iso = (v, field) => {
35
+ if (v === undefined || v === null || v === '')
36
+ return null;
37
+ const s = String(v);
38
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(s))
39
+ throw new FetchError(field + ' 非法(须 YYYY-MM-DD):' + s);
40
+ return s;
41
+ };
42
+ const deadline = iso(input.deadline, 'deadline');
43
+ const startDate = iso(input.startDate, 'startDate');
44
+ let startKg = null;
45
+ if (input.startKg !== undefined && input.startKg !== null && input.startKg !== '') {
46
+ startKg = typeof input.startKg === 'number' ? input.startKg : Number(String(input.startKg).trim());
47
+ if (!Number.isFinite(startKg) || startKg <= 0 || startKg > 500)
48
+ throw new FetchError('起点体重非法:' + JSON.stringify(input.startKg));
49
+ }
50
+ ensureGoalRow(db);
51
+ const upd = db
52
+ .prepare('UPDATE daily_goal SET weight_goal = ?, goal_deadline = ?, start_weight = ?, start_date = ?, updated_at = CURRENT_TIMESTAMP WHERE id = 1')
53
+ .run(kg, deadline, startKg, startDate);
54
+ const row = db.prepare('SELECT updated_at FROM daily_goal WHERE id = 1').get();
55
+ return { weightGoal: kg, deadline, startKg, startDate, updatedAt: row?.updated_at ?? null, rowsAffected: Number(upd.changes) };
56
+ }
57
+ export function resumeAllGoals(db) {
58
+ ensureGoalRow(db);
59
+ const upd = db
60
+ .prepare('UPDATE daily_goal SET goal_paused = 0, updated_at = CURRENT_TIMESTAMP WHERE id = 1')
61
+ .run();
62
+ const row = db.prepare('SELECT id, updated_at FROM daily_goal WHERE id = 1').get();
63
+ if (!row)
64
+ throw new FetchError('resume 后 daily_goal#1 缺失');
65
+ return {
66
+ id: row.id,
67
+ updatedAt: row.updated_at,
68
+ rowsAffected: Number(upd.changes),
69
+ resumeState: '正常(未暂停)',
70
+ resumedAt: row.updated_at,
71
+ };
72
+ }
73
+ //# sourceMappingURL=goal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal.js","sourceRoot":"","sources":["../../src/fetch/goal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /** T4 #23 · goal_history 取数(对照老家 scripts/goal_history.py)。
2
+ *
3
+ * 无独立历史表:food_log 按日聚合 vs daily_goal 单行目标,80%-120% 判定带。
4
+ * today 可注入(默认 UTC 日,与 T3 todayStr 同口径,便于单测钉死)。
5
+ */
6
+ import type { DatabaseSync } from 'node:sqlite';
7
+ export type DayStatus = '完成' | '未完成' | '无记录';
8
+ export interface DayGoalStatus {
9
+ date: string;
10
+ calorieActual: number;
11
+ calorieGoal: number | null;
12
+ pct: number | null;
13
+ status: DayStatus;
14
+ }
15
+ export interface GoalHistory {
16
+ goalHistory: DayGoalStatus[];
17
+ completedCount: number;
18
+ incompleteCount: number;
19
+ calorieGoal: number | null;
20
+ }
21
+ export declare function todayISO(): string;
22
+ export declare function shiftISODate(iso: string, deltaDays: number): string;
23
+ export declare function listCompletedGoals(db: DatabaseSync, days?: number, today?: string): GoalHistory;
24
+ //# sourceMappingURL=goalHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goalHistory.d.ts","sourceRoot":"","sources":["../../src/fetch/goalHistory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAID,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAInE;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,SAAK,EAAE,KAAK,GAAE,MAAmB,GAAG,WAAW,CAoCvG"}
@@ -0,0 +1,51 @@
1
+ import { FetchError } from './errors.js';
2
+ const round1 = (n) => Math.round(n * 10) / 10;
3
+ export function todayISO() {
4
+ return new Date().toISOString().slice(0, 10);
5
+ }
6
+ export function shiftISODate(iso, deltaDays) {
7
+ const t = Date.parse(iso + 'T12:00:00Z');
8
+ if (Number.isNaN(t))
9
+ throw new FetchError('日期非法: ' + iso);
10
+ return new Date(t + deltaDays * 86400000).toISOString().slice(0, 10);
11
+ }
12
+ export function listCompletedGoals(db, days = 30, today = todayISO()) {
13
+ if (!Number.isInteger(days) || days < 1)
14
+ throw new FetchError('days 须为正整数: ' + String(days));
15
+ const end = today;
16
+ const start = shiftISODate(today, -(days - 1));
17
+ const goal = db
18
+ .prepare('SELECT calorie_goal FROM daily_goal WHERE id = 1')
19
+ .get();
20
+ const calGoal = goal?.calorie_goal ?? null;
21
+ const rows = db
22
+ .prepare('SELECT date, COALESCE(SUM(calories), 0) AS cal FROM food_log WHERE date BETWEEN ? AND ? GROUP BY date')
23
+ .all(start, end);
24
+ const actual = new Map(rows.map((r) => [r.date, round1(r.cal)]));
25
+ const history = [];
26
+ let completed = 0;
27
+ let incomplete = 0;
28
+ for (let i = days - 1; i >= 0; i--) {
29
+ const d = shiftISODate(today, -i);
30
+ const cal = actual.get(d);
31
+ if (cal === undefined) {
32
+ history.push({ date: d, calorieActual: 0, calorieGoal: calGoal, pct: 0, status: '无记录' });
33
+ continue;
34
+ }
35
+ if (calGoal) {
36
+ const pct = round1((cal / calGoal) * 100);
37
+ const status = pct >= 80 && pct <= 120 ? '完成' : '未完成';
38
+ if (status === '完成')
39
+ completed += 1;
40
+ else
41
+ incomplete += 1;
42
+ history.push({ date: d, calorieActual: cal, calorieGoal: calGoal, pct, status });
43
+ }
44
+ else {
45
+ incomplete += 1;
46
+ history.push({ date: d, calorieActual: cal, calorieGoal: calGoal, pct: null, status: '未完成' });
47
+ }
48
+ }
49
+ return { goalHistory: history, completedCount: completed, incompleteCount: incomplete, calorieGoal: calGoal };
50
+ }
51
+ //# sourceMappingURL=goalHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goalHistory.js","sourceRoot":"","sources":["../../src/fetch/goalHistory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /** T6 #25 · 取数:近日每日摄入聚合 vs 目标(老家 calorie_history.py 同口径,纯取数不打印)。
2
+ * 目标值经 T4 getNutritionGoal 单源读取。
3
+ */
4
+ import type { DatabaseSync } from 'node:sqlite';
5
+ export interface DayIntake {
6
+ date: string;
7
+ calories: number;
8
+ protein: number;
9
+ carbs: number;
10
+ fat: number;
11
+ /** 剩余 = 目标 − 当日;目标未设时为 null */
12
+ remaining: number | null;
13
+ /** +N卡 / 达标 / 未设目标(老家同文案) */
14
+ status: string;
15
+ }
16
+ export interface CalorieHistory {
17
+ days: number;
18
+ goal: number | null;
19
+ rows: DayIntake[];
20
+ }
21
+ /** 最近 N 天每日摄入(food_log 按 date 聚合倒序);空库返回空 rows,调用方阻断提示,不返“正常空数据”。 */
22
+ export declare function getCalorieHistory(db: DatabaseSync, days?: number, now?: Date): CalorieHistory;
23
+ /** 本地体重序列(跨技能合并的上游输入之一;food/weight 双序列对齐的 weight 侧)。 */
24
+ export declare function weightSeries(db: DatabaseSync): {
25
+ date: string;
26
+ weight_kg: number;
27
+ }[];
28
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/fetch/history.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAMD,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,SAAI,EAAE,GAAG,OAAa,GAAG,cAAc,CAmB9F;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,EAAE,EAAE,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,CAKpF"}
@@ -0,0 +1,29 @@
1
+ import { getNutritionGoal } from './nutritionGoal.js';
2
+ function fmtDate(d) {
3
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
4
+ }
5
+ /** 最近 N 天每日摄入(food_log 按 date 聚合倒序);空库返回空 rows,调用方阻断提示,不返“正常空数据”。 */
6
+ export function getCalorieHistory(db, days = 7, now = new Date()) {
7
+ const start = new Date(now);
8
+ start.setDate(start.getDate() - days);
9
+ const rows = db
10
+ .prepare(`SELECT date, SUM(calories) AS calories, SUM(protein) AS protein, SUM(carbs) AS carbs, SUM(fat) AS fat
11
+ FROM food_log WHERE date >= ? GROUP BY date ORDER BY date DESC`)
12
+ .all(fmtDate(start));
13
+ const goal = getNutritionGoal(db)?.calorie_goal ?? null;
14
+ return {
15
+ days,
16
+ goal,
17
+ rows: rows.map((r) => {
18
+ if (goal === null)
19
+ return { ...r, remaining: null, status: '未设目标' };
20
+ const remaining = Math.round(goal - r.calories);
21
+ return { ...r, remaining, status: remaining !== 0 ? `${remaining >= 0 ? '+' : ''}${remaining}卡` : '达标' };
22
+ }),
23
+ };
24
+ }
25
+ /** 本地体重序列(跨技能合并的上游输入之一;food/weight 双序列对齐的 weight 侧)。 */
26
+ export function weightSeries(db) {
27
+ return db.prepare('SELECT date, weight_kg FROM weight_log ORDER BY date').all();
28
+ }
29
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/fetch/history.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAoBtD,SAAS,OAAO,CAAC,CAAO;IACtB,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACnH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,EAAgB,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC5E,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;sEACgE,CACjE;SACA,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAsF,CAAC;IAC5G,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,EAAE,YAAY,IAAI,IAAI,CAAC;IACxD,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YACpE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3G,CAAC,CAAC;KACH,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAC,EAAgB;IAC3C,OAAO,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,EAG1E,CAAC;AACN,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** 取数层 barrel:T3 饮食 / 体重 / 运动 / 身体 / envelope 结构段 + T6 导入 / 历史 / 跨技能只读。 */
2
+ export { FetchError } from './errors.js';
3
+ export * from './diet.js';
4
+ export * from './weight.js';
5
+ export * from './exercise.js';
6
+ export * from './body.js';
7
+ export { CALORIE_SKILL, calorieKey, fetchPayload, KEYS } from './shapes.js';
8
+ export type { FetchPayload } from './shapes.js';
9
+ export { REQUIRED_FIELDS, OPTIONAL_FIELDS, NUMERIC_FIELDS, validateRecord } from './validate.js';
10
+ export type { ValidationResult } from './validate.js';
11
+ export { readJsonl, dedupeKey, checkDuplicate, importProducts, validateFile, dedupeReport, exportBySource, } from './batch.js';
12
+ export type { DuplicatePolicy, ImportStats, ImportResult, ImportFailure, ImportOptions } from './batch.js';
13
+ export { getCalorieHistory, weightSeries } from './history.js';
14
+ export type { DayIntake, CalorieHistory } from './history.js';
15
+ export { readSkill, requireOk } from './cross-skill.js';
16
+ export type { SkillEnvelope, ReadSkillOptions } from './cross-skill.js';
17
+ export { getProfile, setProfile, setActivityLevel, updateProfile, normalizeActivityLevel, normalizeGender, PROFILE_UPDATABLE, ACTIVITY_ALIASES } from './profile.js';
18
+ export type { ProfileRow, SetProfileInput } from './profile.js';
19
+ export { DEFAULT_CATALOG_PATH, loadCatalog, suggestSimilar, verifyMovementName, verifyMany } from './xunji-catalog.js';
20
+ export type { VerifyResult } from './xunji-catalog.js';
21
+ export { collectPlanNames, auditPlanNames } from './audit.js';
22
+ export type { AuditStatus, AuditReport } from './audit.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fetch/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjG,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,SAAS,EACT,SAAS,EACT,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,sBAAsB,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrK,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvH,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}