Feature: Next Period Prediction
Module: periods (formerly cycles)
Priority: High (MVP Essential)
Summary: This feature calculates and displays the predicted start date of the user's next menstrual period based on their logged historical data. It will also show the average cycle length and provide a simple indicator of the prediction's confidence, as outlined in the Product Requirements Document.
- As a user, I want to see an estimate of when my next period will start so I can be prepared.
- As a new user, I want to understand that the app needs a few periods of data before it can make accurate predictions.
- As a user with irregular cycles, I want to know if the prediction is less likely to be accurate so I can manage my expectations.
The prediction for the next period's start date will be calculated using a simple average of the user's past cycle lengths.
- Collect Historical Data: Fetch all completed periods from the
periodstable in IndexedDB. A completed period is one that has both astartDateand anendDate. - Calculate Cycle Lengths: A single "cycle length" is the number of days from the
startDateof one period to the day before thestartDateof the next consecutive period. - Calculate Average Cycle Length: Sum the lengths of all available past cycles and divide by the number of cycles. The result should be rounded to the nearest whole number.
- Predict Next Start Date: The predicted start date is calculated by adding the
average cycle length(in days) to thestartDateof the most recent logged period.
Formula:
predictedStartDate = lastPeriod.startDate + averageCycleLengthInDays
- A minimum of two completed periods is required to calculate the first average cycle length and make a prediction.
- A "completed period" is defined as a record in the
periodstable with a non-nullstartDateandendDate.
- Insufficient Data: If fewer than two completed periods are available, the UI should not display a prediction. Instead, it should show a message guiding the user to log more periods.
- Example Message: "Log at least two full periods to see your next period prediction."
- Ongoing Period: The current, ongoing period (where
endDateisnull) is not used in the average length calculation, but itsstartDateis the baseline for predicting the next period.
A simple confidence level will be displayed based on the amount of data available.
- Low Confidence: 2-3 completed periods logged.
- Medium Confidence: 4-6 completed periods logged.
- High Confidence: 7+ completed periods logged.
This is a proxy for confidence, as it doesn't account for variance in cycle length. More complex variance-based indicators are deferred to a post-MVP phase.
- The prediction will be displayed prominently on the main dashboard/home screen.
- A
DaisyUI Cardcomponent will be used to contain the prediction information. - The card will display:
- Predicted Date: The primary piece of information (e.g., "Around June 25th").
- Countdown: A relative time until the predicted date (e.g., "In 10 days").
- Average Cycle Length: "Based on an average cycle of 28 days."
- Confidence Indicator: A simple text label (e.g., "Confidence: Medium").
+----------------------------------------+
| |
| Your Next Period is Predicted |
| Around... |
| |
| June 25th, 2024 |
| (In 10 days) |
| |
| ------------------------------------ |
| Avg. Cycle: 28 days | Confidence: Med|
| |
+----------------------------------------++----------------------------------------+
| |
| Ready for Your First Prediction? |
| |
| Log at least two full periods to |
| unlock your next period prediction. |
| |
| [ Log a Past Period ] button |
| |
+----------------------------------------+Prerequisite: Data Model Refactoring
Before implementing the prediction logic, the core data model needs a semantic update to avoid confusion. The term "Cycle" should refer to the calculated duration between periods, not the logged period itself.
- Rename DB Table: In Dexie schema (
lib/db.ts), rename thecyclestable toperiods. - Update Foreign Key: Rename the
cycleIdforeign key in theperiodDaystable toperiodId. - Update Module Name: Rename the feature module directory from
src/modules/cyclestosrc/modules/periods. - Update Hooks & Types: Rename all related types and hooks (e.g.,
Cycle->Period,useAllCycles->useAllPeriods). This is a project-wide find-and-replace task.
Implementation Steps
-
Analytics Hook (
usePredictionAnalytics):- Create a new hook within
src/modules/periods/hooks/. - This hook will use the refactored
useAllPeriodshook to fetch all period data from Dexie via TanStack Query. - It will be responsible for memoizing the calculation of cycle lengths, average cycle length, and the predicted next start date.
- It should return a clean API for the UI, such as:
{ predictedStartDate: Date | null; averageCycleLength: number | null; confidenceLevel: 'low' | 'medium' | 'high' | null; isLoading: boolean; error: Error | null; hasSufficientData: boolean; }
- Create a new hook within
-
Calculation Logic (
calculatePeriodAnalytics):- Create a pure utility function in a new
src/modules/periods/utils.tsfile. - This function will take an array of
Periodobjects (the refactored type) as input. - It will perform the logic described in section 3.1 and return the calculated analytics. The
usePredictionAnalyticshook will call this function.
- Create a pure utility function in a new
-
UI Component (
PredictionCard.tsx):- Create a new component in
src/modules/periods/components/. - This component will call the
usePredictionAnalyticshook. - It will conditionally render either the prediction card or the "insufficient data" message based on the
hasSufficientDataflag from the hook. - It will handle the formatting of dates and display of the confidence level.
- Create a new component in
- When the app has fewer than two completed periods logged, a message is shown prompting the user to log more data.
- No prediction date is displayed when there is insufficient data.
- When two or more completed periods are logged, the prediction card is displayed.
- The average cycle length is calculated correctly as the mean of all completed cycle lengths.
- The predicted start date is calculated correctly by adding the average cycle length to the start date of the most recent period.
- The confidence level correctly reflects the number of logged periods (Low: 2-3, Medium: 4-6, High: 7+).
- The UI component correctly displays all required information: predicted date, countdown, average length, and confidence.
- The calculations are updated automatically when a new period is completed or an existing period is modified/deleted.