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
11 KiB
Purpose: Establish clean architecture patterns for household operations that support multi-tenant isolation and real-time sync requirements. Output: Complete data layer with models, repository interface, and Supabase datasource ready for household operations.
<execution_context>
@/.opencode/get-shit-done/workflows/execute-plan.md
@/.opencode/get-shit-done/templates/summary.md
</execution_context>
Phase 1 Architecture References
@lib/features/authentication/data/repositories/auth_repository_impl.dart @lib/features/authentication/domain/repositories/auth_repository.dart @lib/features/authentication/domain/models/user_models.dart @lib/features/authentication/domain/entities/user_entity.dart
Create Household Data Models lib/features/household/domain/models/household_models.dart Create household data models following auth model patterns:1. HouseholdModel with:
- id (UUID)
- name (String, required)
- createdAt (DateTime)
- updatedAt (DateTime)
- createdBy (UUID, references user)
2. HouseholdMemberModel with:
- id (UUID)
- householdId (UUID)
- userId (UUID)
- role (enum: owner, editor, viewer)
- joinedAt (DateTime)
3. InviteCodeModel with:
- id (UUID)
- householdId (UUID)
- code (String, 8 chars, unique)
- createdAt (DateTime)
- expiresAt (DateTime, 30 days from creation)
- createdBy (UUID)
- usedBy (UUID?, nullable)
- usedAt (DateTime?, nullable)
Include fromJson/toJson methods, copyWith methods, and proper null safety.
Reference auth model patterns for consistency.
flutter analyze lib/features/household/domain/models/household_models.dart passes
Household data models compile with proper JSON serialization and validation
Create Household Entity Models
lib/features/household/domain/entities/household_entity.dart
Create entity models separating business logic from data persistence:
1. HouseholdEntity with:
- Core properties (same as model but without JSON methods)
- List<HouseholdMemberEntity> members
- InviteCode? currentInvite (if user is owner)
- bool isCurrentUserOwner
2. HouseholdMemberEntity with:
- id, householdId, userId, role, joinedAt
- User? user (optional populated user data)
- bool isCurrentUser
Include business logic methods:
- canInviteMembers() (owner/editor only)
- canRemoveMember() (owner only, can't remove self if last owner)
- getRoleDisplayName()
Follow auth entity patterns for consistency.
flutter analyze lib/features/household/domain/entities/household_entity.dart passes
Household entities compile with business logic methods and proper separation from data models
Create Household Repository Interface
lib/features/household/domain/repositories/household_repository.dart
Create abstract repository defining household operations:
abstract class HouseholdRepository {
Future<HouseholdEntity> createHousehold(String name, String userId);
Future<List<HouseholdEntity>> getUserHouseholds(String userId);
Future<HouseholdEntity?> getHouseholdById(String householdId);
Future<InviteCodeModel> generateInviteCode(String householdId, String createdBy);
Future<HouseholdEntity> joinHousehold(String inviteCode, String userId);
Future<void> leaveHousehold(String householdId, String userId);
Future<void> removeMember(String householdId, String memberUserId);
Future<void> updateMemberRole(String householdId, String memberUserId, HouseholdRole role);
Future<List<HouseholdMemberEntity>> getHouseholdMembers(String householdId);
Future<InviteCodeModel?> getActiveInviteCode(String householdId);
Future<void> revokeInviteCode(String inviteCodeId);
}
Include Household enum:
enum HouseholdRole { owner, editor, viewer }
Follow auth repository interface patterns.
flutter analyze lib/features/household/domain/repositories/household_repository.dart passes
Household repository interface defines all required operations with proper typing
Create Household Remote Datasource
lib/features/household/data/datasources/household_remote_datasource.dart
Create Supabase datasource implementing low-level data operations:
class HouseholdRemoteDatasource {
final SupabaseClient client;
HouseholdRemoteDatasource(this.client);
// Core CRUD operations
Future<Map<String, dynamic>> createHousehold(Map<String, dynamic> data);
Future<List<Map<String, dynamic>>> getUserHouseholds(String userId);
Future<Map<String, dynamic>?> getHouseholdById(String householdId);
Future<Map<String, dynamic>> generateInviteCode(Map<String, dynamic> data);
Future<Map<String, dynamic>> joinHousehold(String inviteCode, String userId);
Future<void> leaveHousehold(String householdId, String userId);
// Member operations
Future<List<Map<String, dynamic>>> getHouseholdMembers(String householdId);
Future<void> removeMember(String householdId, String memberUserId);
Future<void> updateMemberRole(String householdId, String memberUserId, String role);
// Invite operations
Future<Map<String, dynamic>?> getActiveInviteCode(String householdId);
Future<void> revokeInviteCode(String inviteCodeId);
}
Use Supabase table operations: .from('households'), .from('household_members'), .from('invite_codes').
Include error handling for Supabase exceptions.
flutter analyze lib/features/household/data/datasources/household_remote_datasource.dart passes
Household remote datasource provides low-level Supabase operations with proper error handling
Create Household Repository Implementation
lib/features/household/data/repositories/household_repository_impl.dart
Create repository implementation using datasource and models:
class HouseholdRepositoryImpl implements HouseholdRepository {
final HouseholdRemoteDatasource datasource;
HouseholdRepositoryImpl(this.datasource);
@override
Future<HouseholdEntity> createHousehold(String name, String userId) async {
// Create household record
// Add owner as member
// Return populated entity
}
@override
Future<InviteCodeModel> generateInviteCode(String householdId, String createdBy) async {
// Generate 8-character unique code
// Check for collisions
// Set expiry to 30 days
// Revoke any existing codes
}
@override
Future<HouseholdEntity> joinHousehold(String inviteCode, String userId) async {
// Validate invite code
// Check expiry
// Add member with 'editor' role
// Mark invite as used
// Return household entity
}
// Implement all other interface methods...
}
Include invite code generation logic (8 chars, alphanumeric, collision checking).
Handle business rules (only owners can generate invites, can't leave if last owner, etc.).
Map between models and entities with proper validation.
flutter analyze lib/features/household/data/repositories/household_repository_impl.dart passes
Household repository implementation provides business logic and data mapping with validation
1. All models compile with proper JSON serialization and null safety
2. Repository interface defines all required operations from SHARE-01 through SHARE-05
3. Remote datasource uses Supabase client for household table operations
4. Repository implementation includes business rules for invite codes and member management
5. Data layer follows clean architecture with proper separation of concerns
<success_criteria> Household data layer is complete with models, repository interface, and Supabase implementation ready for UI integration and invite code generation. </success_criteria>
After completion, create `.planning/phases/02-household-creation/02-01-SUMMARY.md` with household data layer implementation summary