add habit goal-period difficulty and habit formation research notes

Ground the 21-day habit myth in actual research (Lally et al. 2010) and let
users pick a target period (21/66/254 days or unlimited) matching that
study's easy/median/hard automaticity timelines when creating a habit,
with progress shown on the habits list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 10:12:17 +09:00
co-authored by Claude Sonnet 5
parent 55918d56d1
commit d212451fe0
15 changed files with 355 additions and 9 deletions
+9 -2
View File
@@ -9,12 +9,12 @@ from pydantic import ValidationError
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.habit import HabitStatus, HabitType
from app.models.habit import HabitDifficulty, HabitStatus, HabitType
from app.models.user import User
from app.schemas.habit import HabitCreate, HabitUpdate
from app.security import get_current_user_optional
from app.services import habit_service, log_service
from app.template_utils import heatmap_opacity, is_milestone_streak, weekday_label
from app.template_utils import difficulty_label, goal_progress, heatmap_opacity, is_milestone_streak, weekday_label
router = APIRouter()
@@ -22,6 +22,9 @@ templates = Jinja2Templates(directory="app/templates")
templates.env.globals["weekday_label"] = weekday_label
templates.env.globals["heatmap_opacity"] = heatmap_opacity
templates.env.globals["is_milestone_streak"] = is_milestone_streak
templates.env.globals["difficulty_label"] = difficulty_label
templates.env.globals["goal_progress"] = goal_progress
templates.env.globals["habit_difficulties"] = list(HabitDifficulty)
def _current_user_or_redirect(request: Request, db: Session) -> User | RedirectResponse:
@@ -155,6 +158,7 @@ def create_habit_page(
name: str = Form(""),
habit_type: str = Form(...),
weekdays_mask: int = Form(...),
difficulty: str = Form(HabitDifficulty.MEDIUM.value),
condition_text: str | None = Form(None),
reminder_time: str | None = Form(None),
db: Session = Depends(get_db),
@@ -169,6 +173,7 @@ def create_habit_page(
name=name,
habit_type=HabitType(habit_type),
weekdays_mask=weekdays_mask,
difficulty=HabitDifficulty(difficulty),
condition_text=condition_text,
reminder_time=parsed_time,
)
@@ -190,6 +195,7 @@ def edit_habit_page(
habit_id: int,
name: str = Form(""),
weekdays_mask: int = Form(...),
difficulty: str = Form(HabitDifficulty.MEDIUM.value),
condition_text: str | None = Form(None),
reminder_time: str | None = Form(None),
db: Session = Depends(get_db),
@@ -208,6 +214,7 @@ def edit_habit_page(
name=name,
habit_type=habit.habit_type,
weekdays_mask=weekdays_mask,
difficulty=HabitDifficulty(difficulty),
condition_text=condition_text,
reminder_time=parsed_time,
)