5.1.2: Достижение цели Fitbit для задачи без подзадачи
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m20s

This commit is contained in:
poignatov
2026-02-09 17:40:29 +03:00
parent 9cfb988960
commit 76049b3da5
4 changed files with 60 additions and 6 deletions

View File

@@ -11125,12 +11125,22 @@ func (a *App) syncFitbitData(userID int, date time.Time) error {
if err := a.saveFitbitSubtaskDraft(userID, int(stepsGoalTaskID.Int64), int(stepsGoalSubtaskID.Int64), goalReached); err != nil {
log.Printf("Error saving steps goal subtask draft: %v", err)
}
} else if stepsGoalTaskID.Valid {
goalReached := steps >= goalSteps
if err := a.setFitbitTaskDraftAutoComplete(userID, int(stepsGoalTaskID.Int64), goalReached); err != nil {
log.Printf("Error setting steps goal task draft auto_complete: %v", err)
}
}
if floorsGoalTaskID.Valid && floorsGoalSubtaskID.Valid {
goalReached := floors >= goalFloors
if err := a.saveFitbitSubtaskDraft(userID, int(floorsGoalTaskID.Int64), int(floorsGoalSubtaskID.Int64), goalReached); err != nil {
log.Printf("Error saving floors goal subtask draft: %v", err)
}
} else if floorsGoalTaskID.Valid {
goalReached := floors >= goalFloors
if err := a.setFitbitTaskDraftAutoComplete(userID, int(floorsGoalTaskID.Int64), goalReached); err != nil {
log.Printf("Error setting floors goal task draft auto_complete: %v", err)
}
}
log.Printf("Fitbit data synced for user_id=%d, date=%s: steps=%d, floors=%d, goalSteps=%d, goalFloors=%d",
@@ -11248,6 +11258,50 @@ func (a *App) saveFitbitSubtaskDraft(userID int, taskID int, subtaskID int, chec
return nil
}
// setFitbitTaskDraftAutoComplete создаёт или обновляет драфт задачи, выставляя только флаг «Выполнить в конце дня».
// Используется для достижения цели по шагам/этажам, когда выбрана задача без подзадачи.
func (a *App) setFitbitTaskDraftAutoComplete(userID int, taskID int, autoComplete bool) error {
var exists bool
err := a.DB.QueryRow(`
SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)
`, taskID, userID).Scan(&exists)
if err != nil || !exists {
return fmt.Errorf("task %d not found or not owned by user", taskID)
}
var draftID int
err = a.DB.QueryRow("SELECT id FROM task_drafts WHERE task_id = $1", taskID).Scan(&draftID)
if err == sql.ErrNoRows {
if !autoComplete {
return nil
}
_, err = a.DB.Exec(`
INSERT INTO task_drafts (task_id, user_id, auto_complete, created_at, updated_at)
VALUES ($1, $2, TRUE, NOW(), NOW())
`, taskID, userID)
if err != nil {
return fmt.Errorf("failed to create draft: %w", err)
}
log.Printf("Fitbit: created task draft for task_id=%d, auto_complete=true", taskID)
return nil
}
if err != nil {
return fmt.Errorf("failed to get draft: %w", err)
}
_, err = a.DB.Exec(`
UPDATE task_drafts SET auto_complete = $1, updated_at = NOW() WHERE id = $2
`, autoComplete, draftID)
if err != nil {
return fmt.Errorf("failed to update draft: %w", err)
}
if !autoComplete {
_, _ = a.DB.Exec("DELETE FROM task_draft_subtasks WHERE task_draft_id = $1", draftID)
}
log.Printf("Fitbit: set task draft auto_complete for task_id=%d to %v", taskID, autoComplete)
return nil
}
// fitbitSyncHandler выполняет ручную синхронизацию данных Fitbit
func (a *App) fitbitSyncHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {