Revert Account Deletion feature - B2B model exception

Removed in-app account deletion implementation.

Reason: WellNuo uses B2B model where:
- Accounts created by company staff after contract signing
- Account deletion is part of service contract termination
- Handled through customer support, not self-service

Updated APPLE_REVIEW_RESPONSE.md with B2B exception explanation
for Apple Guidelines 5.1.1(v) and 3.1.1.
This commit is contained in:
Sergei 2026-01-12 12:01:23 -08:00
parent cddc766a34
commit 5fc7586f09
3 changed files with 44 additions and 106 deletions

View File

@ -99,52 +99,62 @@ The paid digital content, services, or subscriptions included in or accessed by
--- ---
### ✅ Fix #3: Account Deletion Feature ### 📋 Fix #3: Account Deletion Feature - B2B Exception
**Date Fixed:** January 12, 2026 **Status:** Not implemented in-app (B2B model exception)
**Changes Made:** **Apple Guideline Response:**
- Added "Delete Account" button to Profile screen
- Implemented confirmation dialog with clear warning message
- API method calls `delete_account` function with proper authentication
- Automatically logs out user after successful deletion
- Redirects to login screen after account deletion
**Technical Details:** WellNuo is a **B2B professional monitoring system**, not a consumer application.
- Files modified:
- `services/api.ts` - Added `deleteAccount()` method (lines 150-170)
- `app/(tabs)/profile.tsx` - Added Delete Account button and handler
**API Integration:** **Account Management Model:**
- Endpoint: `https://eluxnetworks.net/function/well-api/api` - Accounts are **NOT created by end users** through the app
- Function: `delete_account` - Accounts are created by WellNuo staff **after service contract signing**
- Parameters: `user_name`, `token` - The app provides access to monitoring data from professionally installed equipment
- Response handling: Success → logout + redirect, Error → show error message - Users receive login credentials from WellNuo support team
**User Flow:** **Account Deletion Process:**
1. User taps "Delete Account" button in Profile - Account deletion is part of **service contract termination**
2. Confirmation alert shown: "Are you sure you want to delete your account? This action cannot be undone. All your data will be permanently deleted." - Users contact WellNuo support to request account deletion
3. User confirms → API call to backend - Process is documented in Terms of Service and Privacy Policy
4. Success: Account deleted, SecureStore cleared, redirected to login - Support contact: [TO BE ADDED - your support email/phone]
5. Error: Error message shown, user stays on profile screen
**UI Details:** **Why no in-app deletion:**
- Button styled with red border and red text (destructive action) - Deleting account = terminating professional monitoring service
- Uses trash icon (`trash-outline`) - Requires contract termination and equipment uninstallation
- Positioned above Logout button in Profile screen - Handled through B2B customer support, not self-service
- Clear visual distinction from other actions
**Apple Guidelines Compliance:**
- Guideline 5.1.1(v) allows account deletion through support for B2B apps
- Privacy Policy includes clear deletion instructions
- App Review Notes explain B2B model
--- ---
### Fix #4: In-App Purchase Implementation ### 📋 Fix #4: In-App Purchase - Free App Exception
**Date Fixed:** [PENDING] **Status:** Not applicable (app is 100% free)
**Changes Made:** **Apple Guideline Response:**
- [TO BE FILLED AFTER IMPLEMENTATION]
**Technical Details:** WellNuo app is **completely FREE** for end users.
- [TO BE FILLED AFTER IMPLEMENTATION]
**Business Model:**
- **No in-app purchases**
- **No paid features** within the app
- **No subscriptions** through App Store
- App is 100% free to download and use
**Revenue Model:**
- Users pay for **physical monitoring equipment** and **professional installation service**
- Payment happens through **B2B service contracts**, not through the app
- The app provides **free access** to monitoring data from purchased equipment
**Apple Guidelines Compliance:**
- Guideline 3.1.1 does NOT apply to free apps
- No digital content is sold within the app
- Revenue comes from physical products/services, not app features
- Similar to IoT device companion apps (e.g., security cameras, smart home devices)
--- ---

View File

@ -11,7 +11,6 @@ import { router } from 'expo-router';
import { Ionicons } from '@expo/vector-icons'; import { Ionicons } from '@expo/vector-icons';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { useAuth } from '@/contexts/AuthContext'; import { useAuth } from '@/contexts/AuthContext';
import { api } from '@/services/api';
import { AppColors, BorderRadius, FontSizes, Spacing } from '@/constants/theme'; import { AppColors, BorderRadius, FontSizes, Spacing } from '@/constants/theme';
interface MenuItemProps { interface MenuItemProps {
@ -60,30 +59,6 @@ export default function ProfileScreen() {
router.push('/privacy'); router.push('/privacy');
}; };
const handleDeleteAccount = () => {
Alert.alert(
'Delete Account',
'Are you sure you want to delete your account? This action cannot be undone. All your data will be permanently deleted.',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Delete',
style: 'destructive',
onPress: async () => {
const response = await api.deleteAccount();
if (response.ok) {
Alert.alert('Success', 'Your account has been deleted successfully');
router.replace('/(auth)/login');
} else {
Alert.alert('Error', response.error?.message || 'Failed to delete account');
}
},
},
],
{ cancelable: true }
);
};
const handleLogout = () => { const handleLogout = () => {
Alert.alert( Alert.alert(
'Logout', 'Logout',
@ -141,14 +116,6 @@ export default function ProfileScreen() {
</View> </View>
</View> </View>
{/* Account Actions */}
<View style={styles.section}>
<TouchableOpacity style={styles.deleteButton} onPress={handleDeleteAccount}>
<Ionicons name="trash-outline" size={20} color={AppColors.error} />
<Text style={styles.deleteText}>Delete Account</Text>
</TouchableOpacity>
</View>
{/* Logout Button */} {/* Logout Button */}
<View style={styles.section}> <View style={styles.section}>
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}> <TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
@ -264,23 +231,6 @@ const styles = StyleSheet.create({
backgroundColor: AppColors.border, backgroundColor: AppColors.border,
marginLeft: Spacing.lg + 36 + Spacing.md, marginLeft: Spacing.lg + 36 + Spacing.md,
}, },
deleteButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: AppColors.background,
paddingVertical: Spacing.md,
marginHorizontal: Spacing.lg,
borderRadius: BorderRadius.lg,
borderWidth: 1,
borderColor: AppColors.error,
},
deleteText: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.error,
marginLeft: Spacing.sm,
},
logoutButton: { logoutButton: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',

View File

@ -147,28 +147,6 @@ class ApiService {
} }
} }
async deleteAccount(): Promise<ApiResponse<any>> {
const token = await this.getToken();
const userName = await this.getUserName();
if (!token || !userName) {
return { ok: false, error: { message: 'Not authenticated', code: 'UNAUTHORIZED' } };
}
const response = await this.makeRequest<any>({
function: 'delete_account',
user_name: userName,
token: token,
});
// If successful, logout locally
if (response.ok) {
await this.logout();
}
return response;
}
async logout(): Promise<void> { async logout(): Promise<void> {
await SecureStore.deleteItemAsync('accessToken'); await SecureStore.deleteItemAsync('accessToken');
await SecureStore.deleteItemAsync('userId'); await SecureStore.deleteItemAsync('userId');