Enhance smoking tracking API with new features and improvements
- Added a new API endpoint `GET /api/v1/smoke/home` to consolidate core modules for the home dashboard, reducing the need for multiple requests. - Updated the `smoke` routes to include the new home endpoint and improved user profile management with the addition of a `quit_date` field. - Enhanced the algorithm for calculating daily targets and next smoke suggestions, ensuring accurate future time handling and user-specific recommendations. - Improved API documentation to reflect new endpoints, response formats, and detailed field descriptions for better clarity and usability. - Refactored user authentication handling in various handlers to streamline the process and ensure consistent error responses.
This commit is contained in:
+18
-17
@@ -71,6 +71,11 @@ if suggested_time in [sleep_time, wake_up_time]:
|
||||
└── 否 → 返回建议时间
|
||||
```
|
||||
|
||||
### 2.7 过期/未来记录兜底
|
||||
|
||||
- 如果用户补录了“未来时间”的抽烟记录,为了避免前端出现负倒计时,服务端会把 `last_smoke_at` 限制在当前 `as_of` 时刻以内。
|
||||
- 当 `plan_date` 是“今天”且 `last_smoke_at + interval` 早于当前时间时,会根据已过去的分钟数计算需要补齐的间隔,向前跳跃若干次直到结果落在未来。这样首页和 `GET /next_smoke_time` 都能返回一个“未来的下一次建议时间”,不会出现提示已经过期的时间点。
|
||||
- 如果 `plan_date` 是将来日期(例如明天的日程),仍然按照指定日期的起床时间作为 `not_before_at`,不会使用上述补齐逻辑。
|
||||
---
|
||||
|
||||
## 3. AI 增强算法
|
||||
@@ -177,26 +182,22 @@ function calculateStage(startDate) {
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 每日目标计算
|
||||
### 4.3 每日目标计算(线性递减)
|
||||
|
||||
以 onboarding 完成日期为起点,到 `quit_date` 线性递减到 0:
|
||||
|
||||
```javascript
|
||||
// utils/target.js
|
||||
function calculateDailyTarget(baseline, stage, dayInStage) {
|
||||
if (stage === 1) {
|
||||
return baseline
|
||||
}
|
||||
|
||||
if (stage === 2) {
|
||||
const reduction = (dayInStage / 14) * 0.5
|
||||
return Math.max(Math.round(baseline * (1 - reduction)), 1)
|
||||
}
|
||||
|
||||
if (stage === 3) {
|
||||
const targetRate = 0.25 - (dayInStage / 9) * 0.25
|
||||
return Math.max(Math.round(baseline * targetRate), 0)
|
||||
}
|
||||
|
||||
return baseline
|
||||
function calculateDailyTarget(baseline, startDate, quitDate, today) {
|
||||
if (!baseline || !startDate || !quitDate) return baseline
|
||||
if (today >= quitDate) return 0
|
||||
|
||||
const totalDays = daysBetween(startDate, quitDate)
|
||||
if (totalDays <= 0) return baseline
|
||||
|
||||
const remainingDays = daysBetween(today, quitDate)
|
||||
const target = Math.round(baseline * (remainingDays / totalDays))
|
||||
return remainingDays > 0 ? Math.max(target, 1) : 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user