2538 lines
46 KiB
Markdown
2538 lines
46 KiB
Markdown
# Privacy: Period Tracker — Product & Android Implementation Plan
|
||
|
||
```
|
||
Status: Current
|
||
Owner: _null
|
||
Last reviewed: 2026-08-18
|
||
Governs: the V1 product specification — scope, the prediction requirement, the privacy
|
||
promise, UX and copy, monetization, and the Android stack decision
|
||
Review trigger: Any change to V1 scope, to the privacy promise, to the monetization
|
||
model, or to the Kotlin/Compose/Room stack decision; any Google Play policy
|
||
change affecting a health app; any prediction behaviour that contradicts §11–§16
|
||
```
|
||
|
||
**Document purpose:** Product, design, privacy, monetization, and engineering handoff for **Codex / Claude**
|
||
**Platform:** Android / Google Play
|
||
**Technology decision verified:** August 18, 2026
|
||
**Working positioning:** **Your period. Better predicted.**
|
||
|
||
---
|
||
|
||
## 1. Executive Summary
|
||
|
||
Build a private, focused Android period tracker whose primary job is to:
|
||
|
||
1. Track confirmed period dates.
|
||
2. Learn each user's individual cycle pattern.
|
||
3. Predict the next period and a likely date window.
|
||
4. Estimate ovulation and the fertile window.
|
||
5. Improve future predictions whenever the user confirms a period or says **Not yet**.
|
||
6. Send helpful, discreet notifications without exposing sensitive information on the lock screen.
|
||
7. Keep the free product fully useful, supported by a small bottom banner ad.
|
||
8. Offer a simple one-time purchase to remove ads.
|
||
9. Make a clear privacy promise: **we will never sell the user's data.**
|
||
|
||
The application should intentionally avoid becoming an overloaded "women's health super-app." Prediction quality, privacy, speed, clarity, and trust are the product.
|
||
|
||
---
|
||
|
||
# 2. Product Vision
|
||
|
||
The main loop is:
|
||
|
||
> **Track → Learn → Predict → Remind → Learn Again**
|
||
|
||
The app should answer these questions immediately:
|
||
|
||
- When is my next period likely to start?
|
||
- What is the likely period window?
|
||
- What cycle day am I on?
|
||
- When is my estimated fertile window?
|
||
- When is estimated ovulation?
|
||
- How confident is the app in those estimates?
|
||
- Has the prediction engine become more accurate as it learns me?
|
||
|
||
The experience should feel as if the app knows the user's personal pattern rather than treating everyone as having a generic 28-day cycle.
|
||
|
||
---
|
||
|
||
# 3. Product Promise
|
||
|
||
## Primary marketing promise
|
||
|
||
> # Your period. Better predicted.
|
||
>
|
||
> A private period tracker that learns **your cycle**, not the average person's.
|
||
|
||
## Core technical promise
|
||
|
||
> Every confirmed cycle should make the model more knowledgeable about the individual user.
|
||
|
||
Once enough personal history exists, the app must not repeatedly fall back to a generic 28-day cycle or a fixed global average.
|
||
|
||
If a user consistently records:
|
||
|
||
```text
|
||
34
|
||
35
|
||
36
|
||
34
|
||
35
|
||
```
|
||
|
||
and the app continues to predict a 28- or 29-day cycle, that is a **core product defect**.
|
||
|
||
---
|
||
|
||
# 4. Privacy Promise
|
||
|
||
Privacy must be a visible product feature.
|
||
|
||
## User-facing promise
|
||
|
||
> # Your cycle belongs to you.
|
||
>
|
||
> **We will never sell your personal or health data.**
|
||
>
|
||
> We will never sell your period history, fertility information, ovulation estimates, cycle predictions, or personally identifiable information to advertisers, data brokers, or third parties.
|
||
|
||
This promise should appear:
|
||
|
||
- During onboarding.
|
||
- In Settings → Privacy & Security.
|
||
- On the public privacy page.
|
||
- In relevant store-listing copy where appropriate.
|
||
|
||
## Privacy principles
|
||
|
||
The company and app must:
|
||
|
||
- Never sell user data.
|
||
- Never sell menstrual or cycle data.
|
||
- Never sell fertility or ovulation data.
|
||
- Never sell prediction data.
|
||
- Never use menstrual/fertility information to target advertisements.
|
||
- Never send period dates or fertility state to the ad network.
|
||
- Never require an account to use core tracking.
|
||
- Store sensitive cycle history locally by default.
|
||
- Minimize collection of telemetry.
|
||
- Allow users to export their data.
|
||
- Allow users to permanently delete their data.
|
||
- Support biometric/PIN protection.
|
||
- Make lock-screen notification privacy configurable.
|
||
- Keep advertising code isolated from health-data code.
|
||
|
||
## Important wording distinction
|
||
|
||
The promise is:
|
||
|
||
> **We never sell your data.**
|
||
|
||
Do **not** promise:
|
||
|
||
> "No third party ever processes any data."
|
||
|
||
unless the implementation can truly guarantee that statement.
|
||
|
||
An advertising SDK, billing service, crash-reporting system, or app-store service may process limited technical information. The architecture must minimize this, disclose it accurately in Google Play's Data Safety section, and ensure that health data is never supplied to those systems.
|
||
|
||
---
|
||
|
||
# 5. Scope
|
||
|
||
## Primary features
|
||
|
||
The app's main features are:
|
||
|
||
1. **Period tracking**
|
||
2. **Period prediction**
|
||
3. **Ovulation estimation**
|
||
4. **Fertility-window estimation**
|
||
5. **Personalized learning**
|
||
6. **Prediction confidence**
|
||
7. **Discreet reminders**
|
||
8. **Calendar**
|
||
9. **Cycle insights/history**
|
||
10. **Prediction accuracy history**
|
||
|
||
## Explicitly out of V1
|
||
|
||
Do not build these into the first release:
|
||
|
||
- Social network
|
||
- Community/forum
|
||
- Pregnancy mode
|
||
- AI chatbot
|
||
- General wellness article feed
|
||
- Diet tracking
|
||
- Exercise tracking
|
||
- Horoscope/lunar features
|
||
- Shopping
|
||
- Partner account
|
||
- Sex diary
|
||
- Huge mood/symptom library
|
||
- Supplements
|
||
- Medical diagnosis
|
||
- Birth-control recommendations
|
||
|
||
These can distract from the product's primary value: accurate, private cycle prediction.
|
||
|
||
---
|
||
|
||
# 6. 2026 Android Technology Decision
|
||
|
||
## Required language: Kotlin
|
||
|
||
**Use Kotlin for the Android application.**
|
||
|
||
As of August 18, 2026, Google's Android documentation continues to describe Android development as **Kotlin-first** and explicitly recommends starting new Android apps with Kotlin.
|
||
|
||
Kotlin is the correct language choice for this project because it:
|
||
|
||
- Is Google's recommended language for new Android development.
|
||
- Has first-class support across modern Android documentation and tooling.
|
||
- Provides null safety and concise data modeling.
|
||
- Works naturally with coroutines and Flow.
|
||
- Is the primary language used with Jetpack Compose.
|
||
- Interoperates with Java when necessary.
|
||
|
||
### Version strategy
|
||
|
||
Use the **latest stable Kotlin 2.x release compatible with the selected Android Gradle Plugin and Compose BOM at implementation time**.
|
||
|
||
At the time this plan was verified (August 18, 2026), the official Kotlin documentation listed **Kotlin 2.4.10** as the latest stable release.
|
||
|
||
Do not pin the project to an old Kotlin version merely because this document names a current version. Before initial project creation, Codex/Claude should verify current stable versions in official Android/Kotlin documentation.
|
||
|
||
---
|
||
|
||
# 7. UI Technology: Jetpack Compose
|
||
|
||
**Use Jetpack Compose for all new UI.**
|
||
|
||
Google describes Jetpack Compose as Android's **recommended modern toolkit for building native UI** and Android is now explicitly Compose-first.
|
||
|
||
Do not build the project primarily with legacy XML layouts unless a specific library integration requires a View bridge.
|
||
|
||
Use:
|
||
|
||
- Jetpack Compose
|
||
- Material 3
|
||
- Compose Navigation / current official navigation solution
|
||
- Adaptive layouts where useful
|
||
- Compose previews for major components/screens
|
||
- Centralized design tokens
|
||
|
||
The app should be fully native Android.
|
||
|
||
---
|
||
|
||
# 8. Recommended Android Stack
|
||
|
||
Use current stable releases at implementation time rather than blindly pinning versions from this document.
|
||
|
||
## Core
|
||
|
||
```text
|
||
Language Kotlin
|
||
UI Jetpack Compose
|
||
Design system Material 3
|
||
Build scripts Gradle Kotlin DSL
|
||
Architecture Layered + unidirectional data flow
|
||
Async Kotlin Coroutines
|
||
Reactive state Kotlin Flow / StateFlow
|
||
Screen state ViewModel
|
||
Local structured data Room
|
||
Simple preferences DataStore
|
||
Background work WorkManager
|
||
Dependency injection Hilt (or current recommended equivalent)
|
||
Billing Google Play Billing
|
||
Ads Google Mobile Ads SDK or approved provider behind an abstraction
|
||
Tests JUnit + AndroidX/Compose test APIs
|
||
```
|
||
|
||
## Why Room
|
||
|
||
Cycle history, prediction snapshots, and confirmed period records are structured data that must survive app restarts and updates. Android's current documentation recommends **Room** for non-trivial structured local data.
|
||
|
||
## Why WorkManager
|
||
|
||
Use **WorkManager** for persistent background work that should survive app closure, such as maintaining/recalculating non-exact reminder work.
|
||
|
||
Do not request exact-alarm privileges unless a product requirement truly needs exact clock-time delivery. Menstrual reminders generally do not need alarm-clock-level precision.
|
||
|
||
## Architecture direction
|
||
|
||
Follow current Android architecture guidance:
|
||
|
||
```text
|
||
UI Layer
|
||
↓
|
||
Domain / Use Cases
|
||
↓
|
||
Repository / Data Layer
|
||
↓
|
||
Room / DataStore
|
||
```
|
||
|
||
Use a `ViewModel` for screen-level state and expose immutable `StateFlow`/UI state to Compose.
|
||
|
||
---
|
||
|
||
# 9. Suggested Project Structure
|
||
|
||
A clean starting structure:
|
||
|
||
```text
|
||
app/
|
||
core/
|
||
common/
|
||
database/
|
||
datastore/
|
||
designsystem/
|
||
notifications/
|
||
billing/
|
||
ads/
|
||
security/
|
||
feature/
|
||
onboarding/
|
||
today/
|
||
calendar/
|
||
insights/
|
||
settings/
|
||
domain/
|
||
cycle/
|
||
prediction/
|
||
fertility/
|
||
```
|
||
|
||
Alternative module boundaries are acceptable, but keep these concerns separate:
|
||
|
||
- Health/cycle data
|
||
- Prediction logic
|
||
- UI
|
||
- Ads
|
||
- Billing
|
||
- Notifications
|
||
- Security
|
||
|
||
The **ads module must not depend on the cycle database or prediction domain**.
|
||
|
||
---
|
||
|
||
# 10. Core Data Model
|
||
|
||
Suggested entities follow.
|
||
|
||
## `PeriodRecord`
|
||
|
||
```kotlin
|
||
data class PeriodRecord(
|
||
val id: Long,
|
||
val startDate: LocalDate,
|
||
val endDate: LocalDate?,
|
||
val createdAt: Instant,
|
||
val updatedAt: Instant,
|
||
val source: PeriodRecordSource,
|
||
val isConfirmed: Boolean
|
||
)
|
||
```
|
||
|
||
Suggested `source` values:
|
||
|
||
```text
|
||
MANUAL
|
||
NOTIFICATION_CONFIRMATION
|
||
HISTORICAL_ENTRY
|
||
EDITED
|
||
```
|
||
|
||
## `SpottingRecord`
|
||
|
||
```kotlin
|
||
data class SpottingRecord(
|
||
val id: Long,
|
||
val date: LocalDate,
|
||
val createdAt: Instant
|
||
)
|
||
```
|
||
|
||
Spotting must not automatically count as a confirmed period start.
|
||
|
||
## Derived `CycleRecord`
|
||
|
||
```kotlin
|
||
data class CycleRecord(
|
||
val previousPeriodStart: LocalDate,
|
||
val currentPeriodStart: LocalDate,
|
||
val cycleLengthDays: Int,
|
||
val periodDurationDays: Int?
|
||
)
|
||
```
|
||
|
||
## `PredictionRecord`
|
||
|
||
Store every prediction snapshot used for accuracy evaluation.
|
||
|
||
```kotlin
|
||
data class PredictionRecord(
|
||
val id: Long,
|
||
val generatedAt: Instant,
|
||
val basedOnLastConfirmedPeriodId: Long?,
|
||
val predictedStartDate: LocalDate,
|
||
val predictedWindowStart: LocalDate,
|
||
val predictedWindowEnd: LocalDate,
|
||
val estimatedOvulationDate: LocalDate?,
|
||
val fertileWindowStart: LocalDate?,
|
||
val fertileWindowEnd: LocalDate?,
|
||
val confidenceScore: Double,
|
||
val confidenceLabel: ConfidenceLabel,
|
||
val modelVersion: String,
|
||
val actualStartDate: LocalDate?,
|
||
val absoluteErrorDays: Int?
|
||
)
|
||
```
|
||
|
||
## `NotYetObservation`
|
||
|
||
This is important to the learning strategy.
|
||
|
||
```kotlin
|
||
data class NotYetObservation(
|
||
val id: Long,
|
||
val date: LocalDate,
|
||
val predictionId: Long?,
|
||
val createdAt: Instant
|
||
)
|
||
```
|
||
|
||
A "Not yet" response tells the model that the period had not started by that date.
|
||
|
||
## `UserPreferences`
|
||
|
||
```kotlin
|
||
data class UserPreferences(
|
||
val notificationPrivacy: NotificationPrivacy,
|
||
val reminderTime: LocalTime,
|
||
val periodReminderEnabled: Boolean,
|
||
val fertileWindowReminderEnabled: Boolean,
|
||
val ovulationReminderEnabled: Boolean,
|
||
val biometricLockEnabled: Boolean,
|
||
val theme: AppTheme,
|
||
val adsRemoved: Boolean
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
# 11. Prediction Engine — Product Requirement
|
||
|
||
The prediction engine is the application's core intellectual property.
|
||
|
||
Avoid a simplistic implementation such as:
|
||
|
||
```text
|
||
average_cycle = mean(all cycle lengths)
|
||
next_period = last_start + average_cycle
|
||
```
|
||
|
||
That can be a temporary baseline for a prototype, but it is not sufficient for the final core product.
|
||
|
||
The engine should:
|
||
|
||
- Personalize from the user's own history.
|
||
- Weight recent history.
|
||
- Remain robust to occasional outliers.
|
||
- Recognize possible missing entries.
|
||
- Maintain a prediction window rather than a false exact certainty.
|
||
- Track confidence.
|
||
- Use prediction error to monitor performance.
|
||
- Recalculate after confirmed period starts.
|
||
- Recalculate after edits.
|
||
- Recalculate after "Not yet."
|
||
- Be deterministic/testable for the same input data and model version.
|
||
|
||
---
|
||
|
||
# 12. Prediction Engine V1 — Practical Implementation
|
||
|
||
The first production version does not need a cloud-trained neural network.
|
||
|
||
A robust personalized statistical model can fulfill the product promise while remaining:
|
||
|
||
- Explainable.
|
||
- Private.
|
||
- Fast.
|
||
- Offline.
|
||
- Easy to test.
|
||
- Easy to version.
|
||
|
||
## Step 1 — Build cycle intervals
|
||
|
||
For confirmed start dates:
|
||
|
||
```text
|
||
Start 1 → Start 2 = Cycle 1
|
||
Start 2 → Start 3 = Cycle 2
|
||
Start 3 → Start 4 = Cycle 3
|
||
```
|
||
|
||
Example:
|
||
|
||
```text
|
||
29
|
||
28
|
||
30
|
||
29
|
||
29
|
||
28
|
||
30
|
||
```
|
||
|
||
## Step 2 — Validate but do not silently discard
|
||
|
||
Detect implausible or highly unusual intervals.
|
||
|
||
Do not silently delete unusual data.
|
||
|
||
Instead mark it for review or reduce its statistical influence until confirmed.
|
||
|
||
## Step 3 — Recency weighting
|
||
|
||
Recent confirmed cycles should generally count more than very old cycles.
|
||
|
||
A simple exponential decay can be used conceptually:
|
||
|
||
```text
|
||
weight(ageIndex) = decay ^ ageIndex
|
||
```
|
||
|
||
where the newest cycle receives weight `1.0`.
|
||
|
||
Tune with tests rather than guessing production values.
|
||
|
||
## Step 4 — Robust center
|
||
|
||
Use a robust personalized center such as:
|
||
|
||
- weighted median, or
|
||
- trimmed/Huber-style weighted mean
|
||
|
||
rather than a raw mean that can be thrown off by one extreme value.
|
||
|
||
## Step 5 — Variability
|
||
|
||
Estimate the user's variability using a robust statistic such as:
|
||
|
||
- Median Absolute Deviation (MAD), and/or
|
||
- recent prediction error.
|
||
|
||
Use variability to expand or contract the prediction window.
|
||
|
||
## Step 6 — Trend detection
|
||
|
||
If recent cycles consistently shift longer or shorter, allow the model to adapt gradually.
|
||
|
||
Do not overfit one cycle.
|
||
|
||
## Step 7 — Prediction output
|
||
|
||
Produce:
|
||
|
||
```text
|
||
mostLikelyStartDate
|
||
windowStart
|
||
windowEnd
|
||
confidenceScore
|
||
```
|
||
|
||
Internally, it is desirable to maintain a discrete probability distribution across likely start dates.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Aug 21 0.08
|
||
Aug 22 0.19
|
||
Aug 23 0.31
|
||
Aug 24 0.25
|
||
Aug 25 0.12
|
||
Aug 26 0.05
|
||
```
|
||
|
||
The normal interface should not show percentages unless later usability research supports it.
|
||
|
||
---
|
||
|
||
# 13. Learning From "Not Yet"
|
||
|
||
This is a signature interaction.
|
||
|
||
Suppose today's prediction says:
|
||
|
||
```text
|
||
Most likely: Aug 22
|
||
Expected: Aug 21–24
|
||
```
|
||
|
||
The user is asked:
|
||
|
||
> Did your period start?
|
||
|
||
They choose:
|
||
|
||
> **Not yet**
|
||
|
||
Create a `NotYetObservation`.
|
||
|
||
The new forecast should be conditioned on the knowledge that the period did not begin on or before the confirmed non-start date.
|
||
|
||
Possible new UI:
|
||
|
||
```text
|
||
Updated forecast
|
||
|
||
Most likely
|
||
Aug 23
|
||
|
||
Expected
|
||
Aug 23–25
|
||
```
|
||
|
||
Do not merely move a fixed prediction by +1 day without updating confidence and the remaining probability distribution.
|
||
|
||
Repeated "Not yet" observations should progressively update the forecast.
|
||
|
||
---
|
||
|
||
# 14. Missing-Period / Outlier Detection
|
||
|
||
Example history:
|
||
|
||
```text
|
||
29
|
||
28
|
||
30
|
||
29
|
||
61
|
||
29
|
||
```
|
||
|
||
A 61-day interval may represent:
|
||
|
||
- A true long cycle.
|
||
- A forgotten period entry.
|
||
- An incorrect date.
|
||
|
||
The app should ask:
|
||
|
||
> ## Quick check
|
||
>
|
||
> There's a larger gap than usual in your history.
|
||
>
|
||
> Did you forget to record a period?
|
||
|
||
Actions:
|
||
|
||
- **Add missing period**
|
||
- **No, this is correct**
|
||
|
||
If the user confirms the long interval, keep it and let the model learn from it with appropriate uncertainty.
|
||
|
||
Never secretly modify health history.
|
||
|
||
---
|
||
|
||
# 15. Prediction Confidence
|
||
|
||
User-facing labels:
|
||
|
||
- Low
|
||
- Medium
|
||
- High
|
||
|
||
Confidence should reflect:
|
||
|
||
- Number of confirmed cycles.
|
||
- Variability of those cycles.
|
||
- Recency of data.
|
||
- Missing or questionable gaps.
|
||
- Stability of recent pattern.
|
||
- Historical prediction accuracy.
|
||
- Number of "Not yet" observations.
|
||
- Whether the model is extrapolating beyond its normal range.
|
||
|
||
Example stable history:
|
||
|
||
```text
|
||
28
|
||
29
|
||
28
|
||
29
|
||
28
|
||
29
|
||
```
|
||
|
||
could produce:
|
||
|
||
```text
|
||
Most likely: Aug 23
|
||
Expected: Aug 22–24
|
||
Confidence: High
|
||
```
|
||
|
||
Example variable history:
|
||
|
||
```text
|
||
25
|
||
33
|
||
28
|
||
37
|
||
26
|
||
32
|
||
```
|
||
|
||
could produce:
|
||
|
||
```text
|
||
Most likely: Aug 24
|
||
Expected: Aug 20–29
|
||
Confidence: Low
|
||
```
|
||
|
||
Do not assign "High" purely because the user has entered a large number of cycles.
|
||
|
||
---
|
||
|
||
# 16. Prediction Accuracy
|
||
|
||
Store prediction snapshots before the outcome is known.
|
||
|
||
When a period is later confirmed:
|
||
|
||
```text
|
||
Prediction: Aug 22
|
||
Actual: Aug 24
|
||
Error: 2 days
|
||
```
|
||
|
||
Track:
|
||
|
||
- Last prediction error.
|
||
- Mean absolute error.
|
||
- Median absolute error.
|
||
- Percentage within ±1 day.
|
||
- Percentage within ±2 days.
|
||
- Accuracy trend over time.
|
||
|
||
## User-facing example
|
||
|
||
> ## Your predictions are getting better
|
||
>
|
||
> Last prediction: **1 day early**
|
||
>
|
||
> Average error: **1.1 days**
|
||
>
|
||
> **5 of your last 6 predictions were within one day.**
|
||
|
||
This is a powerful trust and retention feature.
|
||
|
||
---
|
||
|
||
# 17. Ovulation Estimation
|
||
|
||
Ovulation must be presented as an **estimate**, not a known event.
|
||
|
||
Use language such as:
|
||
|
||
> Estimated ovulation
|
||
|
||
Avoid:
|
||
|
||
> You are ovulating today.
|
||
|
||
For a calendar-only V1, estimate ovulation relative to the predicted next period and the user's available cycle history.
|
||
|
||
Do not imply that a fixed "day 14" rule is biologically exact.
|
||
|
||
The algorithm should support a configurable/estimated luteal-phase assumption initially, with uncertainty reflected in the UI.
|
||
|
||
Future optional data can improve estimates:
|
||
|
||
- LH/ovulation test results.
|
||
- Basal body temperature.
|
||
- Cervical mucus.
|
||
|
||
These are not required for V1.
|
||
|
||
---
|
||
|
||
# 18. Fertile Window
|
||
|
||
Present:
|
||
|
||
- Estimated fertile-window start.
|
||
- Estimated fertile-window end.
|
||
- Estimated ovulation date.
|
||
- Today's fertility estimate.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Estimated fertile window
|
||
Aug 8–13
|
||
|
||
Estimated ovulation
|
||
Aug 12
|
||
```
|
||
|
||
Possible daily labels:
|
||
|
||
- Lower likelihood
|
||
- Higher likelihood
|
||
- Estimated fertile window
|
||
|
||
Avoid "safe" or "unsafe" labels.
|
||
|
||
## Required safety copy
|
||
|
||
Display near fertility features and in About:
|
||
|
||
> Fertility and ovulation dates are estimates based on cycle history and are not intended to be used as contraception or as a medical diagnosis.
|
||
|
||
---
|
||
|
||
# 19. Onboarding
|
||
|
||
Keep onboarding short and valuable.
|
||
|
||
## Screen 1 — Welcome
|
||
|
||
```text
|
||
Know what's coming.
|
||
|
||
Track your period and get predictions
|
||
that learn your cycle.
|
||
|
||
[ Get Started ]
|
||
```
|
||
|
||
## Screen 2 — Last Period
|
||
|
||
```text
|
||
When did your last period start?
|
||
|
||
[ Date selector ]
|
||
|
||
[ Continue ]
|
||
```
|
||
|
||
## Screen 3 — Period End
|
||
|
||
```text
|
||
When did it end?
|
||
|
||
[ Date selector ]
|
||
|
||
[ Still going ]
|
||
[ I'm not sure ]
|
||
```
|
||
|
||
## Screen 4 — Previous History
|
||
|
||
```text
|
||
Remember any earlier periods?
|
||
|
||
Adding previous dates helps us learn
|
||
your cycle faster.
|
||
|
||
[ Add Previous Period ]
|
||
[ Skip ]
|
||
```
|
||
|
||
Allow multiple periods to be entered quickly.
|
||
|
||
## Screen 5 — Privacy Promise
|
||
|
||
```text
|
||
Your cycle belongs to you.
|
||
|
||
We will never sell your personal
|
||
or health data.
|
||
|
||
Your period history and fertility information
|
||
are private. We don't sell them to advertisers,
|
||
data brokers, or third parties.
|
||
|
||
[ Continue ]
|
||
```
|
||
|
||
## Screen 6 — Notification Privacy
|
||
|
||
```text
|
||
How should reminders appear?
|
||
|
||
○ Discreet
|
||
"Quick check-in"
|
||
|
||
○ Maximum privacy
|
||
"Reminder"
|
||
|
||
○ Direct
|
||
"Your period may start soon"
|
||
|
||
[ Continue ]
|
||
```
|
||
|
||
Default to **Discreet**.
|
||
|
||
## Screen 7 — First Forecast
|
||
|
||
Provide value immediately:
|
||
|
||
```text
|
||
Your first forecast
|
||
|
||
Next period
|
||
August 31
|
||
|
||
Expected window
|
||
Aug 29 – Sep 2
|
||
|
||
Estimated ovulation
|
||
Aug 17
|
||
|
||
Estimated fertile window
|
||
Aug 12–18
|
||
|
||
Prediction confidence
|
||
Medium
|
||
|
||
[ Go to Today ]
|
||
```
|
||
|
||
Do not force account registration before showing the forecast.
|
||
|
||
---
|
||
|
||
# 20. Main Navigation
|
||
|
||
Use four primary tabs:
|
||
|
||
```text
|
||
Today
|
||
Calendar
|
||
Insights
|
||
Settings
|
||
```
|
||
|
||
Bottom navigation should be reachable with one hand.
|
||
|
||
---
|
||
|
||
# 21. Today Screen
|
||
|
||
The Today screen is the hero screen.
|
||
|
||
The next-period forecast should dominate visually.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Today
|
||
|
||
Cycle Day 25
|
||
|
||
PERIOD LIKELY IN
|
||
|
||
4
|
||
|
||
DAYS
|
||
|
||
Most likely
|
||
August 22
|
||
|
||
Expected window
|
||
Aug 21–24
|
||
|
||
Confidence
|
||
●●● High
|
||
|
||
[ Started Period ]
|
||
|
||
────────────────
|
||
|
||
Fertility today
|
||
Lower likelihood
|
||
|
||
Estimated ovulation
|
||
Aug 8
|
||
|
||
────────────────
|
||
|
||
[ small bottom ad ]
|
||
```
|
||
|
||
Do not fill the screen with articles, upsells, or unrelated health cards.
|
||
|
||
---
|
||
|
||
# 22. Dynamic Today States
|
||
|
||
The Today screen should change according to the user's cycle state.
|
||
|
||
## During period
|
||
|
||
```text
|
||
Period
|
||
|
||
DAY 3
|
||
|
||
Started
|
||
August 18
|
||
|
||
Typical duration
|
||
4–5 days
|
||
|
||
[ Still Going ]
|
||
[ Period Ended ]
|
||
```
|
||
|
||
## Between period and fertile window
|
||
|
||
```text
|
||
Cycle Day 8
|
||
|
||
Next period likely in
|
||
21 days
|
||
|
||
Estimated fertile window in
|
||
5 days
|
||
```
|
||
|
||
## During estimated fertile window
|
||
|
||
```text
|
||
Estimated Fertile Window
|
||
|
||
Estimated ovulation
|
||
In 2 days
|
||
|
||
Next period
|
||
About 16 days
|
||
```
|
||
|
||
## Period approaching
|
||
|
||
```text
|
||
Period likely in
|
||
|
||
3 DAYS
|
||
|
||
Most likely
|
||
August 22
|
||
|
||
Expected
|
||
Aug 21–24
|
||
|
||
[ Started Early? ]
|
||
```
|
||
|
||
## Predicted day
|
||
|
||
```text
|
||
Your period may start today.
|
||
|
||
[ Started ]
|
||
[ Not Yet ]
|
||
```
|
||
|
||
## Beyond original prediction
|
||
|
||
Avoid alarming language such as:
|
||
|
||
> Your period is late!
|
||
|
||
Prefer:
|
||
|
||
```text
|
||
Not yet?
|
||
|
||
Original forecast
|
||
August 22
|
||
|
||
Updated forecast
|
||
August 23–26
|
||
|
||
[ Started Period ]
|
||
[ Not Yet ]
|
||
```
|
||
|
||
---
|
||
|
||
# 23. Period Logging
|
||
|
||
Logging should take one or two taps.
|
||
|
||
Tap:
|
||
|
||
> **Started Period**
|
||
|
||
Then:
|
||
|
||
```text
|
||
Started today?
|
||
|
||
[ Yes — Today ]
|
||
[ Choose Another Date ]
|
||
```
|
||
|
||
After confirmation:
|
||
|
||
```text
|
||
Logged ✓
|
||
|
||
Your predictions have been updated.
|
||
```
|
||
|
||
Return directly to Today.
|
||
|
||
Do not force symptoms, mood, notes, or a survey.
|
||
|
||
---
|
||
|
||
# 24. Period End
|
||
|
||
While a period is active:
|
||
|
||
```text
|
||
Is your period over?
|
||
|
||
[ Ended Today ]
|
||
[ Choose Date ]
|
||
[ Still Going ]
|
||
```
|
||
|
||
On confirmation:
|
||
|
||
```text
|
||
Updated ✓
|
||
```
|
||
|
||
Store duration when enough information is known.
|
||
|
||
---
|
||
|
||
# 25. Spotting
|
||
|
||
Support:
|
||
|
||
- Period
|
||
- Spotting
|
||
|
||
Spotting should not automatically reset the cycle.
|
||
|
||
If an extremely short period entry is recorded, the app can gently ask:
|
||
|
||
```text
|
||
Was this your period or spotting?
|
||
|
||
[ Period ]
|
||
[ Spotting ]
|
||
```
|
||
|
||
Do not over-question the user.
|
||
|
||
---
|
||
|
||
# 26. Calendar
|
||
|
||
Clearly distinguish:
|
||
|
||
- Confirmed period
|
||
- Predicted period
|
||
- Estimated fertile window
|
||
- Estimated ovulation
|
||
|
||
## Visual states
|
||
|
||
### Confirmed period
|
||
Solid marker/fill.
|
||
|
||
### Predicted period
|
||
Dotted/outlined/translucent marker.
|
||
|
||
### Fertile window
|
||
Separate soft pattern/outline.
|
||
|
||
### Estimated ovulation
|
||
Small unique symbol.
|
||
|
||
Do not rely solely on color; include differences in shape/pattern for accessibility.
|
||
|
||
Never make predicted and confirmed days visually identical.
|
||
|
||
---
|
||
|
||
# 27. Insights
|
||
|
||
The purpose of Insights is:
|
||
|
||
> Show the user what the app has learned.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Your Cycle
|
||
|
||
Average cycle
|
||
29.1 days
|
||
|
||
Typical range
|
||
28–30 days
|
||
|
||
Average period
|
||
4.7 days
|
||
```
|
||
|
||
## Recent cycles
|
||
|
||
```text
|
||
29 days
|
||
28 days
|
||
30 days
|
||
29 days
|
||
29 days
|
||
```
|
||
|
||
## Prediction accuracy
|
||
|
||
```text
|
||
Last prediction
|
||
1 day early
|
||
|
||
Average error
|
||
1.2 days
|
||
|
||
Last 6 predictions
|
||
5 of 6 within ±1 day
|
||
```
|
||
|
||
## Learning state
|
||
|
||
Possible copy:
|
||
|
||
- Learning your cycle
|
||
- Getting to know your pattern
|
||
- Personalized to your cycle
|
||
|
||
Do not overstate accuracy.
|
||
|
||
---
|
||
|
||
# 28. Notifications
|
||
|
||
Notifications are a key product feature.
|
||
|
||
They must be useful without exposing menstrual information unintentionally.
|
||
|
||
## Mode 1 — Discreet — Default
|
||
|
||
Lock screen:
|
||
|
||
```text
|
||
Quick check-in
|
||
|
||
Something may be coming up.
|
||
```
|
||
|
||
Inside app:
|
||
|
||
```text
|
||
Your period is likely in about 2 days.
|
||
```
|
||
|
||
## Mode 2 — Maximum Privacy
|
||
|
||
Lock screen:
|
||
|
||
```text
|
||
Reminder
|
||
```
|
||
|
||
No health information.
|
||
|
||
## Mode 3 — Direct
|
||
|
||
Lock screen:
|
||
|
||
```text
|
||
Your period may start in 2 days.
|
||
```
|
||
|
||
The user must explicitly choose Direct.
|
||
|
||
---
|
||
|
||
# 29. Notification Types
|
||
|
||
Independent toggles:
|
||
|
||
- Period approaching
|
||
- Period expected today
|
||
- "Did it start?"
|
||
- Period-end check-in
|
||
- Fertile window approaching
|
||
- Estimated ovulation
|
||
|
||
Reminder time:
|
||
|
||
- Morning
|
||
- Afternoon
|
||
- Evening
|
||
- Custom time
|
||
|
||
---
|
||
|
||
# 30. Notification Flow
|
||
|
||
Example expected start: **August 22**
|
||
|
||
## August 19
|
||
|
||
Lock-screen discreet text:
|
||
|
||
```text
|
||
A heads-up for later this week.
|
||
```
|
||
|
||
Inside:
|
||
|
||
```text
|
||
Your period is likely in approximately 3 days.
|
||
```
|
||
|
||
## August 22
|
||
|
||
```text
|
||
Quick check-in
|
||
```
|
||
|
||
Inside:
|
||
|
||
```text
|
||
Did your period start?
|
||
|
||
[ Started ]
|
||
[ Not Yet ]
|
||
```
|
||
|
||
## August 23
|
||
|
||
If still no confirmation:
|
||
|
||
```text
|
||
Checking in
|
||
```
|
||
|
||
Inside:
|
||
|
||
```text
|
||
Did your period start?
|
||
|
||
[ Yes, Today ]
|
||
[ Yes, Yesterday ]
|
||
[ Choose Date ]
|
||
[ Not Yet ]
|
||
```
|
||
|
||
## Repeated no response / "Not yet"
|
||
|
||
Do not nag forever.
|
||
|
||
Eventually:
|
||
|
||
```text
|
||
We'll stop checking for now.
|
||
Log your period whenever it begins.
|
||
```
|
||
|
||
The internal prediction may continue updating.
|
||
|
||
---
|
||
|
||
# 31. Android Notification Implementation
|
||
|
||
Use Android notification channels and current platform privacy APIs.
|
||
|
||
Requirements:
|
||
|
||
- Request notification permission at an appropriate moment, not blindly on first launch.
|
||
- Provide a dedicated reminder notification channel.
|
||
- Keep public lock-screen content generic in Discreet mode.
|
||
- Use private/secret visibility behavior where supported and appropriate.
|
||
- Never include sensitive cycle data in notification analytics payloads.
|
||
- Deep-link the notification to the relevant in-app check-in screen.
|
||
- If the user taps "Started" from an action, require sensible device/security handling before exposing details.
|
||
- Re-schedule reminders after period confirmation or forecast changes.
|
||
|
||
Use WorkManager for persistent/inexact reminder work. Avoid exact-alarm permissions unless truly necessary.
|
||
|
||
---
|
||
|
||
# 32. Incognito Launcher Experience
|
||
|
||
Provide an optional neutral launcher appearance.
|
||
|
||
Possible neutral names:
|
||
|
||
- Calendar
|
||
- Day
|
||
- My Days
|
||
|
||
Possible neutral icon:
|
||
|
||
- Abstract ring
|
||
- Soft geometric calendar
|
||
- Simple dot/circle motif
|
||
|
||
Do not use obviously menstrual imagery for the incognito option.
|
||
|
||
This privacy feature should be free.
|
||
|
||
---
|
||
|
||
# 33. Monetization
|
||
|
||
## Free version
|
||
|
||
The free version includes the complete core tracker:
|
||
|
||
- Period tracking
|
||
- Personalized period predictions
|
||
- Ovulation estimate
|
||
- Fertile window
|
||
- Calendar
|
||
- Insights
|
||
- Notifications
|
||
- Discreet mode
|
||
- Prediction confidence
|
||
- Prediction accuracy
|
||
|
||
Prediction quality must not be reduced for free users.
|
||
|
||
## Ads
|
||
|
||
Use a small bottom banner on suitable screens.
|
||
|
||
Suitable:
|
||
|
||
- Today
|
||
- Calendar
|
||
- Insights
|
||
|
||
Do not show ads:
|
||
|
||
- In onboarding
|
||
- In notifications
|
||
- In critical period-start confirmation
|
||
- In period-end confirmation
|
||
- Over controls
|
||
- Between health workflow steps
|
||
- As forced full-screen interstitials immediately after logging
|
||
- As rewarded video required to view a prediction
|
||
|
||
## Paid option
|
||
|
||
Offer:
|
||
|
||
> # Remove Ads Forever
|
||
|
||
Prefer a simple one-time Google Play purchase for launch.
|
||
|
||
Tentative pricing band:
|
||
|
||
```text
|
||
$4.99–$9.99 USD one time
|
||
```
|
||
|
||
Do market/pricing validation before final release.
|
||
|
||
Do not make prediction accuracy a paid feature.
|
||
|
||
---
|
||
|
||
# 34. Advertising Privacy Architecture
|
||
|
||
This requirement is non-negotiable.
|
||
|
||
> The advertising subsystem must never receive menstrual dates, cycle length, period duration, fertility status, ovulation estimates, prediction confidence, prediction history, spotting records, or any other health-derived attribute.
|
||
|
||
## Technical rules
|
||
|
||
- Place ad code behind an `AdProvider` abstraction.
|
||
- Do not pass health-data properties into ad request extras.
|
||
- Do not use cycle state for ad targeting.
|
||
- Prefer non-personalized/contextual advertising.
|
||
- Use consent tooling appropriate to the user's region.
|
||
- Do not initialize the ads provider for users who have purchased Remove Ads, where practical.
|
||
- Never log health-data values into ad callbacks.
|
||
- Audit SDK data collection before each release.
|
||
- Keep ad SDK versions current and review Play Data Safety implications.
|
||
|
||
The company promises **never to sell user data**.
|
||
|
||
---
|
||
|
||
# 35. Billing
|
||
|
||
Use Google Play Billing with the current stable billing library at implementation time.
|
||
|
||
Product concept:
|
||
|
||
```text
|
||
remove_ads_forever
|
||
```
|
||
|
||
Requirements:
|
||
|
||
- Non-consumable one-time purchase.
|
||
- Restore purchase.
|
||
- Handle reinstall/device changes through Google Play entitlement.
|
||
- Reflect entitlement in local state.
|
||
- Ads disappear immediately after purchase.
|
||
- Prediction and health features remain unchanged.
|
||
|
||
Do not store sensitive cycle data in billing metadata.
|
||
|
||
---
|
||
|
||
# 36. Settings
|
||
|
||
## Cycle
|
||
|
||
- Period History
|
||
- Edit Records
|
||
- Prediction Settings
|
||
- Fertility Estimates
|
||
|
||
## Notifications
|
||
|
||
- Period Reminders
|
||
- Fertile Window Reminders
|
||
- Ovulation Reminder
|
||
- Reminder Time
|
||
- Notification Privacy
|
||
|
||
## Privacy & Security
|
||
|
||
- Biometric Lock
|
||
- PIN Lock
|
||
- Export My Data
|
||
- Delete My Data
|
||
- Privacy Promise
|
||
- Privacy Policy
|
||
|
||
## Appearance
|
||
|
||
- Light
|
||
- Dark
|
||
- System
|
||
- Launcher Icon / Incognito Mode
|
||
|
||
## Premium
|
||
|
||
- Remove Ads Forever
|
||
- Restore Purchase
|
||
|
||
## About
|
||
|
||
- How Predictions Work
|
||
- Fertility Disclaimer
|
||
- Privacy Policy
|
||
- Terms
|
||
- Contact Support
|
||
- App Version
|
||
|
||
---
|
||
|
||
# 37. Look and Feel
|
||
|
||
The app should feel:
|
||
|
||
- Calm
|
||
- Private
|
||
- Intelligent
|
||
- Friendly
|
||
- Clean
|
||
- Modern
|
||
- Soft
|
||
- Trustworthy
|
||
- Mature
|
||
- Fast
|
||
- Uncluttered
|
||
|
||
It should **not** feel:
|
||
|
||
- Clinical
|
||
- Childish
|
||
- Loud
|
||
- Sexualized
|
||
- Overly stereotypically feminine
|
||
- Gamified
|
||
- Like a social network
|
||
- Like a fertility clinic
|
||
- Like an advertising platform
|
||
|
||
The target is a polished modern utility app with warmth.
|
||
|
||
---
|
||
|
||
# 38. Visual Design Direction
|
||
|
||
Use:
|
||
|
||
- Generous whitespace
|
||
- Rounded cards
|
||
- Large numerical typography
|
||
- Strong hierarchy
|
||
- Large touch targets
|
||
- Minimal borders
|
||
- Subtle elevation
|
||
- Simple icons
|
||
- Soft transitions
|
||
- Accessible contrast
|
||
|
||
The prediction number is the visual hero.
|
||
|
||
Example:
|
||
|
||
```text
|
||
PERIOD LIKELY IN
|
||
|
||
4
|
||
|
||
DAYS
|
||
```
|
||
|
||
The number should command attention before secondary details.
|
||
|
||
---
|
||
|
||
# 39. Color Direction
|
||
|
||
Avoid bright stereotypical pink as the entire identity.
|
||
|
||
Suggested family:
|
||
|
||
```text
|
||
Deep Plum
|
||
Muted Berry
|
||
Soft Lavender
|
||
Warm Cream
|
||
Off White
|
||
Charcoal
|
||
Muted Sage / Teal
|
||
```
|
||
|
||
## Period state
|
||
|
||
Use a sophisticated berry/plum/red tone.
|
||
|
||
Avoid graphic blood-red.
|
||
|
||
## Fertile window
|
||
|
||
Use a distinct subtle accent such as:
|
||
|
||
- muted teal
|
||
- sage
|
||
- subdued blue-green
|
||
|
||
Avoid bright green that could communicate "safe."
|
||
|
||
## Background
|
||
|
||
Light mode:
|
||
|
||
- warm off-white
|
||
- soft neutral surface
|
||
|
||
Dark mode:
|
||
|
||
- deep charcoal
|
||
- slightly lighter cards
|
||
|
||
Use Material 3 color roles and centralized theme tokens.
|
||
|
||
Do not hard-code random colors throughout Composables.
|
||
|
||
---
|
||
|
||
# 40. Typography
|
||
|
||
Use a clean Android-friendly sans-serif.
|
||
|
||
Prefer system/Material typography unless branding later requires a licensed custom font.
|
||
|
||
Hierarchy:
|
||
|
||
```text
|
||
Hero number Very large / bold
|
||
Screen title Large / semibold
|
||
Card title Medium / semibold
|
||
Body Regular
|
||
Secondary metadata Smaller / medium
|
||
```
|
||
|
||
Avoid decorative fonts.
|
||
|
||
---
|
||
|
||
# 41. Motion
|
||
|
||
Animations should be restrained.
|
||
|
||
Good:
|
||
|
||
- Soft card fade/slide.
|
||
- Number transition.
|
||
- Calendar selection transition.
|
||
- Prediction-update transition.
|
||
- Small confirmation check animation.
|
||
|
||
Avoid:
|
||
|
||
- Confetti.
|
||
- Constant bouncing.
|
||
- Flashy gradients.
|
||
- Reward-style gamification.
|
||
- Anything that trivializes sensitive health events.
|
||
|
||
Respect reduced-motion preferences where available.
|
||
|
||
---
|
||
|
||
# 42. Artwork Requirements for Codex / Claude
|
||
|
||
The app should rely primarily on UI design rather than expensive illustration.
|
||
|
||
Artwork needed:
|
||
|
||
## 1. Primary app icon
|
||
|
||
Concept:
|
||
|
||
- Abstract circular cycle.
|
||
- One small offset dot representing progression through a cycle.
|
||
- Modern, simple, recognizable at small size.
|
||
|
||
Avoid:
|
||
|
||
- Blood drops
|
||
- Tampons
|
||
- Pads
|
||
- Uterus imagery
|
||
- Gender symbols
|
||
- Anatomical reproductive graphics
|
||
|
||
## 2. Incognito app icon
|
||
|
||
Neutral geometric/calendar design.
|
||
|
||
It should not identify the product as a period tracker.
|
||
|
||
## 3. Onboarding artwork
|
||
|
||
Create 2–3 subtle vector illustrations.
|
||
|
||
Concept:
|
||
|
||
- Overlapping circular forms.
|
||
- Phases/cycle progression.
|
||
- Soft abstract curves.
|
||
|
||
No anatomy.
|
||
|
||
## 4. Empty state
|
||
|
||
For:
|
||
|
||
```text
|
||
No periods logged yet
|
||
```
|
||
|
||
Use a small abstract calendar/cycle illustration.
|
||
|
||
## 5. Learning state
|
||
|
||
For:
|
||
|
||
```text
|
||
Learning your cycle
|
||
```
|
||
|
||
Use abstract points/circles gradually converging into a pattern.
|
||
|
||
## 6. Privacy artwork
|
||
|
||
Minimal shield/lock motif for the privacy promise.
|
||
|
||
## 7. Calendar markers
|
||
|
||
Vector/state assets or Compose-drawn indicators for:
|
||
|
||
- Confirmed period
|
||
- Predicted period
|
||
- Fertile window
|
||
- Estimated ovulation
|
||
|
||
They must remain distinguishable without color.
|
||
|
||
## Asset implementation preference
|
||
|
||
Prefer:
|
||
|
||
- Material Symbols where appropriate.
|
||
- Android VectorDrawable.
|
||
- Compose vector paths.
|
||
- SVG assets converted into Android-friendly vector resources.
|
||
|
||
Avoid unnecessary raster imagery.
|
||
|
||
If custom artwork cannot be produced immediately, Codex/Claude should create polished placeholder vector assets and keep them behind replaceable resource names.
|
||
|
||
---
|
||
|
||
# 43. Accessibility
|
||
|
||
Support:
|
||
|
||
- TalkBack
|
||
- Dynamic/scalable text
|
||
- Large touch targets
|
||
- High contrast
|
||
- Dark mode
|
||
- Non-color-only state indicators
|
||
- Content descriptions
|
||
- Semantic labels for charts/markers
|
||
- Logical focus order
|
||
- Reduced-motion considerations
|
||
|
||
Calendar state must not depend only on color.
|
||
|
||
Example:
|
||
|
||
```text
|
||
Confirmed period = solid circle
|
||
Predicted period = dotted circle
|
||
Fertile window = outline/ring
|
||
Ovulation = small star/dot marker
|
||
```
|
||
|
||
---
|
||
|
||
# 44. Local-First Data Architecture
|
||
|
||
The app should work without an account and without a network connection for core functionality.
|
||
|
||
Core cycle data remains local.
|
||
|
||
Suggested flow:
|
||
|
||
```text
|
||
Compose UI
|
||
↓
|
||
ViewModel
|
||
↓
|
||
Use Case / Prediction Engine
|
||
↓
|
||
Repository
|
||
↓
|
||
Room
|
||
```
|
||
|
||
The prediction engine should work entirely offline.
|
||
|
||
No remote server should be necessary to calculate a period prediction.
|
||
|
||
---
|
||
|
||
# 45. Security
|
||
|
||
Requirements:
|
||
|
||
- Use app-private storage.
|
||
- Avoid writing health history to shared external storage.
|
||
- Use Android Keystore-backed secrets where needed.
|
||
- Support biometric/PIN gating.
|
||
- Do not expose sensitive information in logs.
|
||
- Disable verbose logging in release builds.
|
||
- Do not include raw cycle dates in crash reports.
|
||
- Review backups carefully before allowing health database files into platform backup.
|
||
- Prefer encrypted backup/export formats if backup is added later.
|
||
- Make Delete My Data clear and irreversible after confirmation.
|
||
|
||
## Debug logging rule
|
||
|
||
Never write:
|
||
|
||
```text
|
||
User period started: 2026-08-18
|
||
Predicted ovulation: 2026-09-02
|
||
```
|
||
|
||
to production logs.
|
||
|
||
Use non-sensitive event names:
|
||
|
||
```text
|
||
period_record_created
|
||
prediction_recalculated
|
||
```
|
||
|
||
without health values.
|
||
|
||
---
|
||
|
||
# 46. Analytics
|
||
|
||
Analytics are optional, not required for core V1.
|
||
|
||
If analytics are used:
|
||
|
||
Collect only product-level events that do not expose health data.
|
||
|
||
Acceptable examples:
|
||
|
||
```text
|
||
onboarding_completed
|
||
calendar_opened
|
||
period_log_button_tapped
|
||
remove_ads_screen_opened
|
||
purchase_completed
|
||
notification_permission_result
|
||
```
|
||
|
||
Avoid:
|
||
|
||
```text
|
||
cycle_length=31
|
||
period_date=...
|
||
fertility_status=high
|
||
ovulation_date=...
|
||
prediction_error=...
|
||
```
|
||
|
||
unless the analytics system is explicitly designed for private local-only metrics.
|
||
|
||
Prediction accuracy can be calculated on-device.
|
||
|
||
---
|
||
|
||
# 47. Google Play / Health Compliance
|
||
|
||
This app is a health-related application and should be treated accordingly.
|
||
|
||
Before release:
|
||
|
||
- Complete Google Play's Health Apps declaration as applicable.
|
||
- Complete the Data Safety section accurately.
|
||
- Publish a privacy policy.
|
||
- Review every SDK's data collection.
|
||
- Ensure the store listing does not make misleading medical claims.
|
||
- Clearly state that fertility/ovulation values are estimates.
|
||
- Do not market the app as a contraceptive unless it separately meets all applicable legal/regulatory requirements.
|
||
- Do not imply diagnosis.
|
||
- Confirm the latest Google Play target API requirements at release time.
|
||
- Use the latest stable Android SDK supported by the current Play requirements.
|
||
|
||
Do not guess compliance details; verify current Play policy immediately before submission.
|
||
|
||
---
|
||
|
||
# 48. Performance Expectations
|
||
|
||
The app should feel instantaneous.
|
||
|
||
Goals:
|
||
|
||
- Today screen renders immediately from local data.
|
||
- Logging a period appears instant.
|
||
- Prediction recalculation happens locally and quickly.
|
||
- No network dependency for cycle prediction.
|
||
- Ads load asynchronously and never block content.
|
||
- If an ad fails, content remains perfectly laid out.
|
||
- Avoid layout jumps when the banner ad loads.
|
||
- Reserve fixed banner space where appropriate.
|
||
|
||
---
|
||
|
||
# 49. Offline Behavior
|
||
|
||
Core app should work 100% offline for:
|
||
|
||
- Period logging
|
||
- Editing
|
||
- Prediction
|
||
- Ovulation estimate
|
||
- Fertility estimate
|
||
- Calendar
|
||
- Insights
|
||
- Notification scheduling
|
||
- App lock
|
||
|
||
Network may be required for:
|
||
|
||
- Ads
|
||
- Billing verification
|
||
- Optional future cloud backup
|
||
|
||
If offline:
|
||
|
||
- Hide/collapse failed ad gracefully.
|
||
- Do not show errors that interrupt tracking.
|
||
|
||
---
|
||
|
||
# 50. Testing Strategy
|
||
|
||
## Unit tests — highest priority
|
||
|
||
Prediction logic must be heavily unit tested.
|
||
|
||
Test:
|
||
|
||
- Single-cycle fallback.
|
||
- Stable 28-day cycles.
|
||
- Stable 35-day cycles.
|
||
- Alternating cycles.
|
||
- Gradually lengthening cycles.
|
||
- Gradually shortening cycles.
|
||
- One extreme outlier.
|
||
- Missing-period gap.
|
||
- Edited historical record.
|
||
- "Not yet" responses.
|
||
- Period starts earlier than predicted.
|
||
- Period starts later than predicted.
|
||
- No history.
|
||
- Duplicate/invalid entries.
|
||
- Time zone / midnight edge cases.
|
||
- Leap years.
|
||
- DST transitions.
|
||
|
||
## Database tests
|
||
|
||
Test:
|
||
|
||
- Insert/edit/delete.
|
||
- Room migrations.
|
||
- Prediction snapshot integrity.
|
||
- Permanent deletion.
|
||
|
||
## UI tests
|
||
|
||
Test core paths:
|
||
|
||
- Onboarding.
|
||
- Log period today.
|
||
- Log historical period.
|
||
- Not Yet.
|
||
- End period.
|
||
- Calendar.
|
||
- Change notification privacy.
|
||
- Remove Ads entitlement.
|
||
|
||
## Notification tests
|
||
|
||
Test all privacy modes.
|
||
|
||
Ensure public lock-screen text never includes private menstrual details when Discreet or Maximum Privacy is selected.
|
||
|
||
---
|
||
|
||
# 51. Prediction Acceptance Tests
|
||
|
||
Examples that should be automated.
|
||
|
||
## Stable longer-cycle user
|
||
|
||
Input:
|
||
|
||
```text
|
||
35
|
||
35
|
||
34
|
||
36
|
||
35
|
||
```
|
||
|
||
Expected:
|
||
|
||
- Forecast should remain near 35 days.
|
||
- It must not revert toward 28 days.
|
||
- Confidence should be relatively high.
|
||
- Window should be reasonably tight.
|
||
|
||
## Variable user
|
||
|
||
Input:
|
||
|
||
```text
|
||
25
|
||
34
|
||
29
|
||
37
|
||
26
|
||
32
|
||
```
|
||
|
||
Expected:
|
||
|
||
- Window should be wider.
|
||
- Confidence should be lower.
|
||
- UI should not assert one exact date as certain.
|
||
|
||
## Outlier
|
||
|
||
Input:
|
||
|
||
```text
|
||
29
|
||
29
|
||
28
|
||
30
|
||
45
|
||
29
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 45-day observation must not dominate the forecast.
|
||
- App may suggest checking for a missing record.
|
||
- If user confirms it, preserve it.
|
||
|
||
## Not yet
|
||
|
||
Forecast:
|
||
|
||
```text
|
||
Aug 22–24
|
||
```
|
||
|
||
Observation:
|
||
|
||
```text
|
||
Aug 22 = Not Yet
|
||
```
|
||
|
||
Expected:
|
||
|
||
- Aug 22 can no longer remain a future start candidate.
|
||
- Forecast and confidence recalculate.
|
||
|
||
---
|
||
|
||
# 52. MVP Build Phases
|
||
|
||
## Phase 1 — Foundation
|
||
|
||
Implement:
|
||
|
||
- Kotlin/Compose project.
|
||
- Material 3 theme.
|
||
- Room database.
|
||
- DataStore.
|
||
- Repository layer.
|
||
- Core navigation.
|
||
- Period record CRUD.
|
||
- Basic tests.
|
||
|
||
## Phase 2 — Prediction Engine
|
||
|
||
Implement:
|
||
|
||
- Cycle generation.
|
||
- Robust personalized forecast.
|
||
- Window.
|
||
- Confidence.
|
||
- Prediction snapshots.
|
||
- Recalculation.
|
||
|
||
## Phase 3 — Core UX
|
||
|
||
Implement:
|
||
|
||
- Onboarding.
|
||
- Today screen.
|
||
- Period start/end.
|
||
- Calendar.
|
||
- Insights.
|
||
|
||
## Phase 4 — Fertility
|
||
|
||
Implement:
|
||
|
||
- Estimated ovulation.
|
||
- Estimated fertile window.
|
||
- Disclaimer.
|
||
- Calendar markings.
|
||
|
||
## Phase 5 — Notifications
|
||
|
||
Implement:
|
||
|
||
- Period approaching.
|
||
- Predicted-day check-in.
|
||
- Not Yet.
|
||
- Period end.
|
||
- Fertility/ovulation toggles.
|
||
- Discreet privacy modes.
|
||
|
||
## Phase 6 — Privacy & Security
|
||
|
||
Implement:
|
||
|
||
- PIN/biometrics.
|
||
- Delete data.
|
||
- Export.
|
||
- Privacy promise.
|
||
- Secure logging rules.
|
||
|
||
## Phase 7 — Monetization
|
||
|
||
Implement:
|
||
|
||
- Bottom banner ad.
|
||
- Ad privacy isolation.
|
||
- Non-personalized/contextual setup.
|
||
- Google Play Billing.
|
||
- Remove Ads Forever.
|
||
- Restore purchase.
|
||
|
||
## Phase 8 — Polish
|
||
|
||
Implement:
|
||
|
||
- Dark mode.
|
||
- Accessibility.
|
||
- Animations.
|
||
- Incognito launcher option.
|
||
- Performance.
|
||
- Final artwork.
|
||
- Store assets.
|
||
|
||
---
|
||
|
||
# 53. Definition of Done for V1
|
||
|
||
V1 is ready when a user can:
|
||
|
||
1. Install the app.
|
||
2. Enter their last period.
|
||
3. Optionally enter prior periods.
|
||
4. Immediately see a period forecast.
|
||
5. See estimated ovulation/fertile window.
|
||
6. Log a new period in one or two taps.
|
||
7. Say "Not yet" and receive an updated forecast.
|
||
8. View calendar history.
|
||
9. See what the app has learned.
|
||
10. Receive discreet reminders.
|
||
11. Use the core tracker offline.
|
||
12. Use the app without an account.
|
||
13. Understand the privacy promise.
|
||
14. Remove ads through a one-time purchase.
|
||
15. Delete/export their data.
|
||
16. Use the UI accessibly in light/dark mode.
|
||
|
||
---
|
||
|
||
# 54. Non-Negotiable Product Rules
|
||
|
||
Codex/Claude should treat these as hard requirements.
|
||
|
||
## Rule 1 — Prediction is core
|
||
|
||
Do not spend engineering effort on non-core wellness features before prediction quality is strong.
|
||
|
||
## Rule 2 — Personalized means personalized
|
||
|
||
The system must learn the user's actual cycle history.
|
||
|
||
## Rule 3 — Never sell user data
|
||
|
||
The company will never sell personal or health data.
|
||
|
||
## Rule 4 — Health data never targets ads
|
||
|
||
No period/fertility information may be passed to advertising systems.
|
||
|
||
## Rule 5 — Free users receive full prediction quality
|
||
|
||
Do not make the core model worse for users who do not pay.
|
||
|
||
## Rule 6 — Ads never interrupt health actions
|
||
|
||
No interstitial after period logging.
|
||
|
||
## Rule 7 — Notifications respect privacy
|
||
|
||
Discreet mode is the default.
|
||
|
||
## Rule 8 — Predictions are estimates
|
||
|
||
Use ranges/confidence rather than false certainty.
|
||
|
||
## Rule 9 — Fertility estimates are not contraception
|
||
|
||
Never imply otherwise.
|
||
|
||
## Rule 10 — The user owns their history
|
||
|
||
Users can edit, export, and delete it.
|
||
|
||
---
|
||
|
||
# 55. Suggested Initial Branding Direction
|
||
|
||
Working name can be chosen later.
|
||
|
||
The identity should communicate:
|
||
|
||
- Rhythm
|
||
- Time
|
||
- Personal pattern
|
||
- Calmness
|
||
- Privacy
|
||
- Confidence
|
||
|
||
Avoid naming that sounds:
|
||
|
||
- Medical/diagnostic
|
||
- Infantile
|
||
- Overtly sexual
|
||
- Pregnancy-only
|
||
|
||
Potential tagline:
|
||
|
||
> **Your period. Better predicted.**
|
||
|
||
Secondary:
|
||
|
||
> **Learns your cycle. Keeps it private.**
|
||
|
||
Privacy line:
|
||
|
||
> **Your cycle belongs to you. We never sell your data.**
|
||
|
||
---
|
||
|
||
# 56. Suggested First-Run Copy
|
||
|
||
## Welcome
|
||
|
||
```text
|
||
Know what's coming.
|
||
|
||
A private period tracker that learns
|
||
your cycle and improves over time.
|
||
|
||
[ Get Started ]
|
||
```
|
||
|
||
## Privacy
|
||
|
||
```text
|
||
Your cycle belongs to you.
|
||
|
||
We will never sell your personal
|
||
or health data.
|
||
|
||
[ Continue ]
|
||
```
|
||
|
||
## First forecast
|
||
|
||
```text
|
||
Your first forecast
|
||
|
||
Period likely
|
||
Aug 31
|
||
|
||
Expected
|
||
Aug 29 – Sep 2
|
||
|
||
Estimated fertile window
|
||
Aug 12–18
|
||
|
||
Confidence
|
||
Medium
|
||
```
|
||
|
||
---
|
||
|
||
# 57. Codex / Claude Implementation Instructions
|
||
|
||
When this document is given to a coding agent:
|
||
|
||
1. Build **native Android**.
|
||
2. Use **Kotlin**, not Java as the primary language.
|
||
3. Use **Jetpack Compose**, not XML as the primary UI system.
|
||
4. Use **Material 3**.
|
||
5. Use **Room** for structured local health/cycle data.
|
||
6. Use **DataStore** for lightweight settings.
|
||
7. Use **Kotlin Coroutines + Flow/StateFlow**.
|
||
8. Use **ViewModel** for screen-level state.
|
||
9. Use **WorkManager** for persistent reminder/background work where appropriate.
|
||
10. Keep the prediction engine in a separate pure-Kotlin domain module/class set so it can be unit tested without Android.
|
||
11. Keep ad code isolated from cycle data.
|
||
12. Never place sensitive dates in logs or analytics.
|
||
13. Use current stable dependencies at implementation time.
|
||
14. Add automated tests before layering on extra features.
|
||
15. Optimize the first release around period prediction accuracy and one-tap logging.
|
||
16. Do not invent medical certainty.
|
||
17. Do not build features explicitly marked out of V1 unless requested.
|
||
|
||
---
|
||
|
||
# 58. Recommended First Coding Milestone
|
||
|
||
The first useful vertical slice should be:
|
||
|
||
```text
|
||
Launch
|
||
↓
|
||
Onboarding: enter 3 period starts
|
||
↓
|
||
Store in Room
|
||
↓
|
||
PredictionEngine calculates next period/window
|
||
↓
|
||
Today screen displays it
|
||
↓
|
||
User presses Started Period
|
||
↓
|
||
New record stored
|
||
↓
|
||
Prediction recalculates
|
||
↓
|
||
Updated Today screen appears
|
||
```
|
||
|
||
Do this before ads, premium, artwork, or complex settings.
|
||
|
||
Once this loop is correct and well-tested, add fertility estimates and notifications.
|
||
|
||
---
|
||
|
||
# 59. Future Enhancements — After V1
|
||
|
||
Only consider these after strong retention/accuracy:
|
||
|
||
- Optional encrypted cloud backup.
|
||
- Device-to-device restore.
|
||
- Optional LH test logging.
|
||
- Optional basal body temperature.
|
||
- More advanced adaptive luteal-phase model.
|
||
- Local ML model if it demonstrably beats the robust statistical engine.
|
||
- Wear OS companion.
|
||
- Home-screen widget.
|
||
- Export to PDF/CSV.
|
||
- Doctor-friendly cycle-history report.
|
||
- Anonymous, opt-in research program only with separate explicit consent.
|
||
|
||
None of these should compromise the privacy promise.
|
||
|
||
---
|
||
|
||
# 60. Product Success Metrics
|
||
|
||
Primary:
|
||
|
||
- Mean absolute next-period prediction error.
|
||
- % predictions within ±1 day.
|
||
- % predictions within ±2 days.
|
||
- Prediction accuracy improvement after 3/6/12 cycles.
|
||
- Successful period logging completion rate.
|
||
- Reminder → confirmation rate.
|
||
- "Not yet" usefulness/reforecast accuracy.
|
||
|
||
Secondary:
|
||
|
||
- 30/90-day retention.
|
||
- Crash-free sessions.
|
||
- Notification opt-in.
|
||
- Remove-ads conversion.
|
||
- Calendar/Insights usage.
|
||
|
||
Avoid optimizing for:
|
||
|
||
- Time spent in app.
|
||
- Number of ads viewed.
|
||
- Content-feed engagement.
|
||
|
||
A great period tracker should often help the user in seconds.
|
||
|
||
---
|
||
|
||
# 61. Official Technical References — Verified August 18, 2026
|
||
|
||
These are primary sources for the 2026 Android technology decisions.
|
||
|
||
## Kotlin
|
||
|
||
Android Developers — Android's Kotlin-first approach
|
||
https://developer.android.com/kotlin/first
|
||
|
||
Android Developers — Kotlin overview
|
||
https://developer.android.com/kotlin/overview
|
||
|
||
Kotlin Documentation
|
||
https://kotlinlang.org/docs/home.html
|
||
|
||
## Jetpack Compose
|
||
|
||
Android Developers — Jetpack Compose
|
||
https://developer.android.com/compose
|
||
|
||
Android Developers — Android is Compose-first
|
||
https://developer.android.com/develop/ui/compose/first
|
||
|
||
## Architecture
|
||
|
||
Android Developers — Recommendations for Android architecture
|
||
https://developer.android.com/topic/architecture/recommendations
|
||
|
||
## Room
|
||
|
||
Android Developers — Save data in a local database using Room
|
||
https://developer.android.com/training/data-storage/room
|
||
|
||
## Background Work
|
||
|
||
Android Developers — Task scheduling / WorkManager
|
||
https://developer.android.com/develop/background-work/background-tasks/persistent
|
||
|
||
## Google Play Health / Data
|
||
|
||
Google Play Console Help — Health app categories and additional information
|
||
https://support.google.com/googleplay/android-developer/answer/13996367
|
||
|
||
Google Play Console Help — Data Safety
|
||
https://support.google.com/googleplay/android-developer/answer/10787469
|
||
|
||
---
|
||
|
||
# 62. Final Product Statement
|
||
|
||
The finished product should be easy to explain:
|
||
|
||
> **A private period tracker that learns your cycle, predicts your next period, estimates ovulation and your fertile window, and discreetly lets you know what's coming.**
|
||
>
|
||
> **We will never sell your data.**
|
||
>
|
||
> Free users get the same prediction quality as everyone else. A small bottom ad supports the free app, and a simple one-time purchase removes ads forever.
|
||
|
||
The product wins by doing one important job exceptionally well:
|
||
|
||
# **Learn the user and predict their cycle better over time.**
|