docs(02): create phase 2 household creation plans
Phase 2: Household Creation & Invites - 6 plans in 4 waves covering SHARE-01 through SHARE-05 - Data models, repository pattern, and Supabase integration - Database schema with RLS policies for multi-tenant isolation - State management with Riverpod and business logic use cases - Complete UI components for household management - Navigation integration with authentication flow Ready for execution: /gsd:execute-phase 2
This commit is contained in:
676
.planning/phases/02-household-creation/02-06-PLAN.md
Normal file
676
.planning/phases/02-household-creation/02-06-PLAN.md
Normal file
@@ -0,0 +1,676 @@
|
||||
---
|
||||
phase: 02-household-creation
|
||||
plan: 06
|
||||
type: execute
|
||||
wave: 4
|
||||
depends_on: [02-05, 02-03]
|
||||
files_modified:
|
||||
- lib/core/router/app_router.dart
|
||||
- lib/features/home/presentation/pages/home_page.dart
|
||||
- lib/providers/auth_provider.dart
|
||||
- lib/main.dart
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Navigation system integrates household selection into app flow"
|
||||
- "Auth state changes automatically load user households"
|
||||
- "Home page displays current household context with navigation to household management"
|
||||
- "Routing handles all household states (no household, single household, multiple households)"
|
||||
- "Real-time household updates reflect across the app"
|
||||
artifacts:
|
||||
- path: "lib/core/router/app_router.dart"
|
||||
provides: "Household-aware navigation routes"
|
||||
contains: "HouseholdListRoute", "CreateHouseholdRoute", "JoinHouseholdRoute"
|
||||
- path: "lib/features/home/presentation/pages/home_page.dart"
|
||||
provides: "Home page with household context"
|
||||
contains: "current household display", "switch household action"
|
||||
- path: "lib/providers/auth_provider.dart"
|
||||
provides: "Auth state with household integration"
|
||||
contains: "household loading on auth change"
|
||||
key_links:
|
||||
- from: "lib/core/router/app_router.dart"
|
||||
to: "lib/features/household/presentation/pages/household_list_page.dart"
|
||||
via: "route definition"
|
||||
pattern: "HouseholdListRoute.*HouseholdListPage"
|
||||
- from: "lib/providers/auth_provider.dart"
|
||||
to: "lib/features/household/providers/household_provider.dart"
|
||||
via: "state synchronization"
|
||||
pattern: "ref.read.*householdProvider.*loadUserHouseholds"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Integrate household functionality into app navigation and authentication flow for seamless user experience.
|
||||
|
||||
Purpose: Connect household management with existing app architecture so users naturally transition from authentication to household setup and inventory management.
|
||||
Output: Fully integrated household system with navigation, auth integration, and state management ready for production.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.opencode/get-shit-done/workflows/execute-plan.md
|
||||
@~/.opencode/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
|
||||
# Navigation and Auth References
|
||||
@lib/core/router/app_router.dart
|
||||
@lib/features/home/presentation/pages/home_page.dart
|
||||
@lib/providers/auth_provider.dart
|
||||
@lib/main.dart
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Update Router with Household Routes</name>
|
||||
<files>lib/core/router/app_router.dart</files>
|
||||
<action>
|
||||
Add household routes to existing router structure:
|
||||
|
||||
1. Import household pages:
|
||||
```dart
|
||||
import '../features/household/presentation/pages/household_list_page.dart';
|
||||
import '../features/household/presentation/pages/create_household_page.dart';
|
||||
import '../features/household/presentation/pages/join_household_page.dart';
|
||||
import '../features/household/providers/household_provider.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
import '../features/household/domain/entities/household_entity.dart';
|
||||
```
|
||||
|
||||
2. Add household route definitions:
|
||||
```dart
|
||||
// Household routes
|
||||
static const householdList = '/households';
|
||||
static const createHousehold = '/households/create';
|
||||
static const joinHousehold = '/households/join';
|
||||
```
|
||||
|
||||
3. Update router with household routes:
|
||||
```dart
|
||||
GoRouter router({required String initialLocation}) {
|
||||
return GoRouter(
|
||||
initialLocation: initialLocation,
|
||||
redirect: (context, state) {
|
||||
final auth = ref.read(authProvider);
|
||||
|
||||
// Handle unauthenticated users
|
||||
if (auth.user == null) {
|
||||
final isAuthRoute = state.location.startsWith('/auth') ||
|
||||
state.location == '/';
|
||||
if (!isAuthRoute) {
|
||||
return '/auth/login';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Authenticated user flow
|
||||
final user = auth.user!;
|
||||
|
||||
// Check if user has households
|
||||
final householdsAsync = ref.read(householdProvider);
|
||||
final households = householdsAsync.maybeWhen(
|
||||
data: (households) => households,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
// If households not loaded yet, don't redirect
|
||||
if (households == null) return null;
|
||||
|
||||
// If no households, go to household list to create/join
|
||||
if (households.isEmpty) {
|
||||
final isHouseholdRoute = state.location.startsWith('/households');
|
||||
if (!isHouseholdRoute) {
|
||||
return HouseholdListRoute.householdList;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Has households - check if current household is set
|
||||
final currentHousehold = ref.read(currentHouseholdProvider);
|
||||
if (currentHousehold == null) {
|
||||
// Auto-select first household
|
||||
ref.read(currentHouseholdProvider.notifier).state = households.first;
|
||||
}
|
||||
|
||||
// Handle specific redirects
|
||||
if (state.location == '/' || state.location == '/auth/login') {
|
||||
return HomePage.route;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
routes: [
|
||||
// Existing auth routes...
|
||||
|
||||
// Household routes
|
||||
GoRoute(
|
||||
path: HouseholdListRoute.householdList,
|
||||
name: 'household-list',
|
||||
builder: (context, state) => const HouseholdListPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: HouseholdListRoute.createHousehold,
|
||||
name: 'create-household',
|
||||
builder: (context, state) => const CreateHouseholdPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: HouseholdListRoute.joinHousehold,
|
||||
name: 'join-household',
|
||||
builder: (context, state) => const JoinHouseholdPage(),
|
||||
),
|
||||
|
||||
// Home route (existing)
|
||||
GoRoute(
|
||||
path: HomePage.route,
|
||||
name: 'home',
|
||||
builder: (context, state) => const HomePage(),
|
||||
),
|
||||
],
|
||||
errorBuilder: (context, state) => Scaffold(
|
||||
body: Center(
|
||||
child: Text('Page not found: ${state.location}'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
4. Add household navigation helpers:
|
||||
```dart
|
||||
class HouseholdListRoute {
|
||||
static const householdList = '/households';
|
||||
static const createHousehold = '/households/create';
|
||||
static const joinHousehold = '/households/join';
|
||||
|
||||
static void goToList(BuildContext context) {
|
||||
GoRouter.of(context).push(householdList);
|
||||
}
|
||||
|
||||
static void goToCreate(BuildContext context) {
|
||||
GoRouter.of(context).push(createHousehold);
|
||||
}
|
||||
|
||||
static void goToJoin(BuildContext context) {
|
||||
GoRouter.of(context).push(joinHousehold);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Update auth redirect logic to handle household selection.
|
||||
Include proper route guards for authenticated users with no households.
|
||||
</action>
|
||||
<verify>flutter analyze lib/core/router/app_router.dart passes</verify>
|
||||
<done>Router includes household routes with proper authentication and household state guards</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Update Auth Provider with Household Integration</name>
|
||||
<files>lib/providers/auth_provider.dart</files>
|
||||
<action>
|
||||
Add household loading to auth state changes:
|
||||
|
||||
1. Import household provider:
|
||||
```dart
|
||||
import '../features/household/providers/household_provider.dart';
|
||||
import '../features/household/providers/household_provider.dart' as household;
|
||||
```
|
||||
|
||||
2. Add household loading to auth state changes:
|
||||
```dart
|
||||
class AuthProvider extends StateNotifier<AsyncValue<AuthState>> {
|
||||
final AuthRepository _repository;
|
||||
|
||||
AuthProvider(this._repository) : super(const AsyncValue.loading()) {
|
||||
_initialize();
|
||||
}
|
||||
|
||||
Future<void> _initialize() async {
|
||||
state = const AsyncValue.loading();
|
||||
try {
|
||||
final currentUser = _repository.currentUser;
|
||||
if (currentUser == null) {
|
||||
state = const AsyncValue.data(AuthState.unauthenticated());
|
||||
return;
|
||||
}
|
||||
|
||||
// User is authenticated, get their session
|
||||
final session = await _repository.getCurrentSession();
|
||||
if (session == null) {
|
||||
state = const AsyncValue.data(AuthState.unauthenticated());
|
||||
return;
|
||||
}
|
||||
|
||||
state = AsyncValue.data(AuthState.authenticated(currentUser));
|
||||
|
||||
// Load user households after successful auth
|
||||
_loadUserHouseholds(currentUser.id);
|
||||
|
||||
} catch (e, stack) {
|
||||
state = AsyncValue.error(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> signIn(String email, String password) async {
|
||||
state = const AsyncValue.loading();
|
||||
try {
|
||||
final user = await _repository.signIn(email, password);
|
||||
state = AsyncValue.data(AuthState.authenticated(user));
|
||||
|
||||
// Load households after successful sign in
|
||||
_loadUserHouseholds(user.id);
|
||||
|
||||
} catch (e, stack) {
|
||||
state = AsyncValue.error(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> signUp(String email, String password) async {
|
||||
state = const AsyncValue.loading();
|
||||
try {
|
||||
final user = await _repository.signUp(email, password);
|
||||
state = AsyncValue.data(AuthState.authenticated(user));
|
||||
|
||||
// Load households after successful sign up
|
||||
_loadUserHouseholds(user.id);
|
||||
|
||||
} catch (e, stack) {
|
||||
state = AsyncValue.error(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> signOut() async {
|
||||
try {
|
||||
await _repository.signOut();
|
||||
state = const AsyncValue.data(AuthState.unauthenticated());
|
||||
|
||||
// Clear household state
|
||||
household.clearHouseholds();
|
||||
ref.read(currentHouseholdProvider.notifier).state = null;
|
||||
|
||||
} catch (e, stack) {
|
||||
state = AsyncValue.error(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadUserHouseholds(String userId) async {
|
||||
try {
|
||||
// This will trigger the household provider to load
|
||||
final container = ProviderScope.containerOf(context!);
|
||||
final householdNotifier = container.read(household.householdProvider.notifier);
|
||||
await householdNotifier.loadUserHouseholds(userId);
|
||||
} catch (e) {
|
||||
// Household loading failure shouldn't break auth flow
|
||||
// The household provider will handle its own error states
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Update auth state to include household info:
|
||||
```dart
|
||||
class AuthState {
|
||||
final User? user;
|
||||
final bool isAuthenticated;
|
||||
final bool hasHouseholds;
|
||||
|
||||
const AuthState({
|
||||
this.user,
|
||||
required this.isAuthenticated,
|
||||
this.hasHouseholds = false,
|
||||
});
|
||||
|
||||
factory AuthState.unauthenticated() => const AuthState(
|
||||
isAuthenticated: false,
|
||||
);
|
||||
|
||||
factory AuthState.authenticated(User user, {bool hasHouseholds = false}) => AuthState(
|
||||
user: user,
|
||||
isAuthenticated: true,
|
||||
hasHouseholds: hasHouseholds,
|
||||
);
|
||||
|
||||
AuthState copyWith({
|
||||
User? user,
|
||||
bool? isAuthenticated,
|
||||
bool? hasHouseholds,
|
||||
}) {
|
||||
return AuthState(
|
||||
user: user ?? this.user,
|
||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||
hasHouseholds: hasHouseholds ?? this.hasHouseholds,
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ensure household state is synchronized with authentication changes.
|
||||
Include proper cleanup on sign out.
|
||||
</action>
|
||||
<verify>flutter analyze lib/providers/auth_provider.dart passes</verify>
|
||||
<done>Auth provider integrates household loading with authentication state changes</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Update Home Page with Household Context</name>
|
||||
<files>lib/features/home/presentation/pages/home_page.dart</files>
|
||||
<action>
|
||||
Add household context and navigation to home page:
|
||||
|
||||
1. Add imports:
|
||||
```dart
|
||||
import '../../household/providers/household_provider.dart';
|
||||
import '../../household/presentation/pages/household_list_page.dart';
|
||||
import '../widgets/household_switcher.dart'; // We'll create this widget
|
||||
```
|
||||
|
||||
2. Add household context to home page:
|
||||
```dart
|
||||
class HomePage extends ConsumerWidget {
|
||||
const HomePage({Key? key}) : super(key: key);
|
||||
|
||||
static const String route = '/home';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final user = ref.watch(authProvider).user;
|
||||
final currentHousehold = ref.watch(currentHouseholdProvider);
|
||||
final householdsAsync = ref.watch(householdProvider);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
children: [
|
||||
if (currentHousehold != null) ...[
|
||||
CircleAvatar(
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
radius: 16,
|
||||
child: Text(
|
||||
currentHousehold.name.isNotEmpty
|
||||
? currentHousehold.name[0].toUpperCase()
|
||||
: 'H',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
currentHousehold.name,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
Text(
|
||||
'${currentHousehold.members.length} members',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _showHouseholdSwitcher(context),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
tooltip: 'Switch Household',
|
||||
),
|
||||
] else ...[
|
||||
const Text('Sage'),
|
||||
],
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
if (user != null)
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'households':
|
||||
HouseholdListRoute.goToList(context);
|
||||
break;
|
||||
case 'logout':
|
||||
_showLogoutConfirmation(context);
|
||||
break;
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
const PopupMenuItem(
|
||||
value: 'households',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.home),
|
||||
SizedBox(width: 8),
|
||||
Text('Manage Households'),
|
||||
],
|
||||
),
|
||||
),
|
||||
const PopupMenuItem(
|
||||
value: 'logout',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.logout),
|
||||
SizedBox(width: 8),
|
||||
Text('Log Out'),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: householdsAsync.when(
|
||||
loading: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (error, stack) => Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.error,
|
||||
size: 64,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Failed to load households',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
error.toString(),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pushNamed('/households'),
|
||||
child: const Text('Manage Households'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
data: (households) {
|
||||
if (households.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.home_outlined,
|
||||
size: 96,
|
||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.3),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'No Household Selected',
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Create or join a household to start managing your inventory',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => HouseholdListRoute.goToList(context),
|
||||
icon: const Icon(Icons.home),
|
||||
label: const Text('Manage Households'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (currentHousehold == null) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
// Normal home page content with inventory
|
||||
return _buildInventoryContent(context, ref, currentHousehold);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInventoryContent(BuildContext context, WidgetRef ref, HouseholdEntity household) {
|
||||
// This would be the normal inventory/home content
|
||||
// For now, show placeholder
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.inventory_2_outlined,
|
||||
size: 96,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'Welcome to ${household.name}!',
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Your inventory will appear here once you start adding items',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
const Text(
|
||||
'Phase 3 will bring barcode scanning and item management',
|
||||
style: TextStyle(fontStyle: FontStyle.italic),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showHouseholdSwitcher(BuildContext context) {
|
||||
// This would show a bottom sheet or dialog to switch households
|
||||
// For now, navigate to household list
|
||||
HouseholdListRoute.goToList(context);
|
||||
}
|
||||
|
||||
void _showLogoutConfirmation(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Log Out'),
|
||||
content: const Text('Are you sure you want to log out?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
ref.read(authProvider.notifier).signOut();
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
child: const Text('Log Out'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Add household context display and switching functionality.
|
||||
Include proper loading and error states.
|
||||
Add navigation to household management.
|
||||
</action>
|
||||
<verify>flutter analyze lib/features/home/presentation/pages/home_page.dart passes</verify>
|
||||
<done>Home page includes household context with navigation to household management</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Update Main Provider Registration</name>
|
||||
<files>lib/main.dart</files>
|
||||
<action>
|
||||
Register household providers in main.dart:
|
||||
|
||||
1. Add household provider imports:
|
||||
```dart
|
||||
import 'features/household/providers/household_provider.dart';
|
||||
```
|
||||
|
||||
2. Add household providers to ProviderScope overrides:
|
||||
```dart
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
// Auth providers (existing)
|
||||
authRepositoryProvider.overrideWithValue(AuthRepositoryImpl(client)),
|
||||
authProvider.overrideWithValue(AuthProvider(authRepository)),
|
||||
|
||||
// Household providers
|
||||
householdRemoteDatasourceProvider.overrideWithValue(HouseholdRemoteDatasource(client)),
|
||||
householdRepositoryProvider.overrideWithValue(HouseholdRepositoryImpl(householdRemoteDatasource)),
|
||||
],
|
||||
child: MyApp(),
|
||||
)
|
||||
```
|
||||
|
||||
Ensure all household providers are properly initialized with dependencies.
|
||||
</action>
|
||||
<verify>flutter analyze lib/main.dart passes</verify>
|
||||
<done>Main app includes household provider registration with proper dependencies</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
1. Router includes household routes with proper authentication and household state guards
|
||||
2. Auth provider integrates household loading with authentication state changes
|
||||
3. Home page displays current household context with navigation to household management
|
||||
4. Household state is properly initialized and synchronized across the app
|
||||
5. Navigation flow handles all household states seamlessly
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
Household functionality is fully integrated into app navigation and authentication flow with seamless user experience ready for production.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/02-household-creation/02-06-SUMMARY.md` with integration completion summary
|
||||
</output>
|
||||
Reference in New Issue
Block a user