Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
42 changes: 42 additions & 0 deletions homeflow/Throne_Biodesign_Consent_Extract.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
STANFORD UNIVERSITY
Research Consent Form – Minimal Risk Medical Human Subject Research

Protocol Title: Home Uroflow Bladder Outlet Study
Protocol Director (PI): Ryan Sun, MD
IRB Number: IRB# -----

STUDY OVERVIEW
You are invited to participate in a research study on benign prostatic hyperplasia (BPH) and lower urinary tract symptoms. This study is being conducted at Stanford University to evaluate whether relief of bladder outlet obstruction can improve objective quality of life and activity measures using wearable devices and home uroflow measurement.

PURPOSE OF THE STUDY
The purpose of this research is to determine whether improvement in bladder outlet obstruction is associated with measurable improvements in daily activity, sleep, and urinary flow patterns. The results may help improve diagnosis and guide treatment of lower urinary tract symptoms.

STUDY PROCEDURES
If you choose to participate, you will be asked to take part in the following:
- Registration and setup, including study screening, consent, initial surveys, and mobile application setup (approximately 30 minutes).
- Use of a wearable device (such as a smartwatch) that you already own. You will be asked to wear the device daily and allow data collected by the device to be shared with the study team through a Stanford-designed research application.
- Installation and use of a smart toilet–based uroflow measurement device (Throne One) attached to your home toilet. You will be asked to record as many voids as possible during a one-week period.
- Completion of survey questionnaires collecting demographic information, medical history, and urinary symptoms, including follow-up surveys at 1 and 12 weeks after surgery.
- Sharing of medical information from your medical record and from other health systems through Apple Health and related integrations, with your permission.

RISKS AND DISCOMFORTS
The risks associated with this study include the time required to download, set up, and use the mobile applications and devices. There is a very small risk of inadvertent disclosure of private health information related to your voiding or wearable data. Although safeguards are in place, there is a small risk of data security breaches.

BENEFITS
You may not receive any direct benefit from participating in this study. The potential benefit is contributing to research that may improve understanding of voiding dysfunction and help develop better diagnostic and treatment tools for future patients.

PRIVACY AND DATA PROTECTION
Your data will be handled securely and used only for research purposes. Identifiable information may be removed, and de-identified data may be used for future research studies or shared with other investigators without additional consent. All reasonable efforts will be made to protect your privacy.

COMPENSATION
You will receive $100 for successful completion of the study.

VOLUNTARY PARTICIPATION
Your participation in this study is voluntary. You may choose not to participate or to withdraw from the study at any time without penalty or loss of benefits to which you are otherwise entitled. Your decision will not affect your medical care.

CONTACT INFORMATION
If you have questions, concerns, or complaints about this research study, you may contact the Protocol Director:
Ryan Sun, MD
Phone: 713-677-1764

You may also contact the Stanford Institutional Review Board (IRB) for independent information about your rights as a research participant.
1 change: 0 additions & 1 deletion homeflow/app/(onboarding)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export default function OnboardingLayout() {
name="baseline-survey"
options={{
animation: 'slide_from_bottom',
presentation: 'formSheet',
}}
/>
<Stack.Screen
Expand Down
16 changes: 12 additions & 4 deletions homeflow/app/(onboarding)/baseline-survey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
calculateIPSSScore,
getIPSSSeverityDescription,
} from '@/lib/questionnaires/ipss-questionnaire';
import { OnboardingProgressBar, ContinueButton } from '@/components/onboarding';
import { OnboardingProgressBar, ContinueButton, DevToolBar } from '@/components/onboarding';
import { IconSymbol } from '@/components/ui/icon-symbol';

export default function BaselineSurveyScreen() {
Expand Down Expand Up @@ -100,6 +100,12 @@ export default function BaselineSurveyScreen() {
}
};

// Dev-only handler that bypasses the survey
const handleDevContinue = async () => {
await OnboardingService.goToStep(OnboardingStep.COMPLETE);
router.replace('/(onboarding)/complete' as Href);
};

const getSeverityColor = () => {
if (!score) return colors.icon;
switch (score.severity) {
Expand Down Expand Up @@ -190,6 +196,8 @@ export default function BaselineSurveyScreen() {
loading={isSubmitting}
/>
</View>

<DevToolBar currentStep={OnboardingStep.BASELINE_SURVEY} onContinue={handleDevContinue} />
</SafeAreaView>
);
}
Expand All @@ -207,18 +215,18 @@ export default function BaselineSurveyScreen() {
</Text>
</View>

{/* TEMPORARY: QuestionnaireForm has its own ScrollView - no dev button here */}
{/* Use "Reset Onboarding" on home screen to test this flow again */}
<View style={styles.formContainer}>
<QuestionnaireForm
questionnaire={IPSS_QUESTIONNAIRE}
onResult={handleSubmit}
submitButtonText="Submit Survey"
// Fix for scroll issue: Ensure keyboard doesn't cover input and content scrolls past footer
keyboardVerticalOffset={100}
keyboardVerticalOffset={100}
scrollContentStyle={{ paddingBottom: 120 }}
/>
</View>

<DevToolBar currentStep={OnboardingStep.BASELINE_SURVEY} onContinue={handleDevContinue} />
</SafeAreaView>
);
}
Expand Down
128 changes: 58 additions & 70 deletions homeflow/app/(onboarding)/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
StyleSheet,
useColorScheme,
Animated,
Keyboard,
TouchableWithoutFeedback,
} from 'react-native';
import { useRouter, Href } from 'expo-router';
import { SafeAreaView } from 'react-native-safe-area-context';
Expand All @@ -20,7 +22,7 @@ import { ChatView, ChatProvider } from '@spezivibe/chat';
import { Colors, StanfordColors, Spacing } from '@/constants/theme';
import { OnboardingStep, STUDY_INFO } from '@/lib/constants';
import { OnboardingService } from '@/lib/services/onboarding-service';
import { OnboardingProgressBar, ContinueButton } from '@/components/onboarding';
import { OnboardingProgressBar, ContinueButton, DevToolBar } from '@/components/onboarding';
import { IconSymbol } from '@/components/ui/icon-symbol';

/**
Expand Down Expand Up @@ -66,10 +68,10 @@ const SYSTEM_PROMPT = `You are a friendly research assistant helping to screen a
## Phase 1: Eligibility (Required Criteria)
Check these naturally (don't read a checklist):
1. Has iPhone with iOS 15+ (required)
2. Has Apple Watch (required)
3. Has BPH diagnosis OR experiencing urinary symptoms like frequent urination, weak stream, nighttime urination (required)
4. Considering or scheduled for bladder outlet surgery like TURP, HoLEP, GreenLight laser, UroLift, Rezum, Aquablation (required)
5. Willing to use Throne uroflow device at home (optional - explain it's a portable urine flow meter)
2. Has BPH or lower urinary tract symptoms suspected to be caused by BPH - such as frequent urination, weak stream, nighttime urination (required)
3. Planning to undergo a bladder outlet procedure such as TURP, HoLEP, GreenLight laser, UroLift, Rezum, Aquablation (required)

Note: Apple Watch and Throne uroflow devices will be provided to participants - do NOT ask about these.

## Phase 2: Medical History (if eligible)

Expand Down Expand Up @@ -131,14 +133,14 @@ When ineligible: [INELIGIBLE]
When ALL medical history sections are complete: [HISTORY_COMPLETE]

## Conversation Flow Example
1. Start with eligibility (devices, diagnosis, surgery plans)
1. Start with eligibility (iPhone, BPH diagnosis/symptoms, surgery plans)
2. Transition after eligible: "Great news! You're eligible for the study. [ELIGIBLE] Now I need to collect some medical history. We'll automatically get things like your age and weight from Apple Health, but I need to ask you about medications, conditions, and a few other things..."
3. Work through sections in order: Demographics → Medications → Surgeries → Labs → Conditions → Clinical data → Planned surgery
4. Before finishing, summarize: "Let me confirm what I have..." then list key points
5. End with: "I have everything I need. [HISTORY_COMPLETE] You can tap Continue to proceed."

## Start the Conversation
"Hi! I'm here to help you join the HomeFlow study. This is a research study that tracks urinary symptoms before and after prostate surgery. Let me ask a few quick questions to make sure this study is right for you.
"Hi! I'm here to help you join the HomeFlow study. This is a research study that tracks urinary symptoms before and after bladder outlet surgery. Let me ask a few quick questions to make sure this study is right for you.

First - are you using an iPhone with iOS 15 or later?"`;

Expand Down Expand Up @@ -203,10 +205,8 @@ export default function OnboardingChatScreen() {
await OnboardingService.updateData({
eligibility: {
hasIPhone: true,
hasAppleWatch: true,
hasBPHDiagnosis: true,
consideringSurgery: true,
willingToUseThrone: true,
isEligible: true,
},
});
Expand Down Expand Up @@ -247,75 +247,63 @@ export default function OnboardingChatScreen() {
</Text>
<ContinueButton title="Continue (Demo)" onPress={handleContinue} style={{ marginTop: Spacing.lg }} />
</View>

<DevToolBar currentStep={OnboardingStep.CHAT} onContinue={handleContinue} />
</SafeAreaView>
);
}

return (
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} edges={['top']}>
<View style={styles.header}>
<OnboardingProgressBar currentStep={OnboardingStep.CHAT} />
<View style={styles.phaseIndicator}>
<View
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} edges={['top']}>
<View style={styles.header}>
<OnboardingProgressBar currentStep={OnboardingStep.CHAT} />
<View style={styles.phaseIndicator}>
<View
style={[
styles.phaseDot,
{ backgroundColor: phase === 'complete' ? '#34C759' : StanfordColors.cardinal },
]}
/>
<Text style={[styles.phaseText, { color: colors.icon }]}>{getPhaseText()}</Text>
</View>
</View>

<ChatView
provider={provider}
systemPrompt={SYSTEM_PROMPT}
placeholder="Type your response..."
onResponse={checkForMarkers}
emptyState={
<View style={styles.emptyState}>
<IconSymbol name="message.fill" size={48} color={colors.icon} />
<Text style={[styles.emptyStateText, { color: colors.icon }]}>
Starting conversation...
</Text>
</View>
}
/>

{canContinue && (
<Animated.View
style={[
styles.phaseDot,
{ backgroundColor: phase === 'complete' ? '#34C759' : StanfordColors.cardinal },
styles.continueContainer,
{
backgroundColor: colors.background,
opacity: buttonOpacity,
},
]}
/>
<Text style={[styles.phaseText, { color: colors.icon }]}>{getPhaseText()}</Text>
</View>
</View>

<ChatView
provider={provider}
systemPrompt={SYSTEM_PROMPT}
placeholder="Type your response..."
onResponse={checkForMarkers}
emptyState={
<View style={styles.emptyState}>
<IconSymbol name="message.fill" size={48} color={colors.icon} />
<Text style={[styles.emptyStateText, { color: colors.icon }]}>
Starting conversation...
>
<Text style={[styles.continueHint, { color: colors.icon }]}>
Great! You&apos;re ready for the next step.
</Text>
</View>
}
/>

{canContinue && (
<Animated.View
style={[
styles.continueContainer,
{
backgroundColor: colors.background,
opacity: buttonOpacity,
},
]}
>
<Text style={[styles.continueHint, { color: colors.icon }]}>
Great! You&apos;re ready for the next step.
</Text>
<ContinueButton title="Continue to Consent" onPress={handleContinue} />
</Animated.View>
)}

{/* TEMPORARY: Development-only continue button to test other screens */}
{/* TODO: Remove this once eligibility questions are properly set up */}
{!canContinue && (
<View
style={[
styles.continueContainer,
{
backgroundColor: colors.background,
},
]}
>
<Text style={[styles.continueHint, { color: colors.icon }]}>
⚠️ Temporary: Skip eligibility for testing
</Text>
<ContinueButton title="Continue (Dev Only)" onPress={handleContinue} />
</View>
)}
</SafeAreaView>
<ContinueButton title="Continue to Consent" onPress={handleContinue} />
</Animated.View>
)}

<DevToolBar currentStep={OnboardingStep.CHAT} onContinue={handleContinue} />
</SafeAreaView>
</TouchableWithoutFeedback>
);
}

Expand Down
6 changes: 4 additions & 2 deletions homeflow/app/(onboarding)/complete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import {
import { useRouter } from 'expo-router';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Colors, StanfordColors, Spacing } from '@/constants/theme';
import { STUDY_INFO } from '@/lib/constants';
import { STUDY_INFO, OnboardingStep } from '@/lib/constants';
import { OnboardingService } from '@/lib/services/onboarding-service';
import { ContinueButton } from '@/components/onboarding';
import { ContinueButton, DevToolBar } from '@/components/onboarding';
import { IconSymbol } from '@/components/ui/icon-symbol';

export default function CompleteScreen() {
Expand Down Expand Up @@ -189,6 +189,8 @@ export default function CompleteScreen() {
<ContinueButton title="Get Started" onPress={handleContinue} />
</Animated.View>
)}

<DevToolBar currentStep={OnboardingStep.COMPLETE} onContinue={handleContinue} />
</SafeAreaView>
);
}
Expand Down
Loading
Loading