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
266 lines
11 KiB
Markdown
266 lines
11 KiB
Markdown
---
|
|
phase: 02-household-creation
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- lib/features/household/domain/models/household_models.dart
|
|
- lib/features/household/data/datasources/household_remote_datasource.dart
|
|
- lib/features/household/data/repositories/household_repository_impl.dart
|
|
- lib/features/household/domain/repositories/household_repository.dart
|
|
- lib/features/household/domain/entities/household_entity.dart
|
|
autonomous: true
|
|
|
|
must_haves:
|
|
truths:
|
|
- "Household data model supports creation, membership, and invite code functionality"
|
|
- "Repository interface defines household operations without implementation details"
|
|
- "Remote datasource handles Supabase household table operations"
|
|
- "Entity model separates business logic from data layer"
|
|
artifacts:
|
|
- path: "lib/features/household/domain/models/household_models.dart"
|
|
provides: "Household, HouseholdMember, InviteCode data models"
|
|
contains: "class Household", "class HouseholdMember", "class InviteCode"
|
|
- path: "lib/features/household/domain/repositories/household_repository.dart"
|
|
provides: "HouseholdRepository interface"
|
|
contains: "abstract class HouseholdRepository", "createHousehold", "joinHousehold", "generateInviteCode"
|
|
- path: "lib/features/household/data/repositories/household_repository_impl.dart"
|
|
provides: "Supabase implementation of household operations"
|
|
contains: "class HouseholdRepositoryImpl", "implements HouseholdRepository"
|
|
- path: "lib/features/household/data/datasources/household_remote_datasource.dart"
|
|
provides: "Supabase client wrapper for household operations"
|
|
contains: "class HouseholdRemoteDatasource", "SupabaseClient"
|
|
- path: "lib/features/household/domain/entities/household_entity.dart"
|
|
provides: "Business logic entities for household operations"
|
|
contains: "class HouseholdEntity", "class HouseholdMemberEntity"
|
|
key_links:
|
|
- from: "lib/features/household/data/repositories/household_repository_impl.dart"
|
|
to: "lib/features/household/data/datasources/household_remote_datasource.dart"
|
|
via: "constructor injection"
|
|
pattern: "HouseholdRemoteDatasource.*datasource"
|
|
- from: "lib/features/household/data/repositories/household_repository_impl.dart"
|
|
to: "lib/features/household/domain/models/household_models.dart"
|
|
via: "model mapping"
|
|
pattern: "Household.*from.*HouseholdModel"
|
|
---
|
|
|
|
<objective>
|
|
Create the foundation for household management with proper data models, repository pattern, and Supabase integration.
|
|
|
|
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.
|
|
</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
|
|
|
|
# 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
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Create Household Data Models</name>
|
|
<files>lib/features/household/domain/models/household_models.dart</files>
|
|
<action>
|
|
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.
|
|
</action>
|
|
<verify>flutter analyze lib/features/household/domain/models/household_models.dart passes</verify>
|
|
<done>Household data models compile with proper JSON serialization and validation</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Create Household Entity Models</name>
|
|
<files>lib/features/household/domain/entities/household_entity.dart</files>
|
|
<action>
|
|
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.
|
|
</action>
|
|
<verify>flutter analyze lib/features/household/domain/entities/household_entity.dart passes</verify>
|
|
<done>Household entities compile with business logic methods and proper separation from data models</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Create Household Repository Interface</name>
|
|
<files>lib/features/household/domain/repositories/household_repository.dart</files>
|
|
<action>
|
|
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.
|
|
</action>
|
|
<verify>flutter analyze lib/features/household/domain/repositories/household_repository.dart passes</verify>
|
|
<done>Household repository interface defines all required operations with proper typing</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Create Household Remote Datasource</name>
|
|
<files>lib/features/household/data/datasources/household_remote_datasource.dart</files>
|
|
<action>
|
|
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.
|
|
</action>
|
|
<verify>flutter analyze lib/features/household/data/datasources/household_remote_datasource.dart passes</verify>
|
|
<done>Household remote datasource provides low-level Supabase operations with proper error handling</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Create Household Repository Implementation</name>
|
|
<files>lib/features/household/data/repositories/household_repository_impl.dart</files>
|
|
<action>
|
|
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.
|
|
</action>
|
|
<verify>flutter analyze lib/features/household/data/repositories/household_repository_impl.dart passes</verify>
|
|
<done>Household repository implementation provides business logic and data mapping with validation</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
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
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
Household data layer is complete with models, repository interface, and Supabase implementation ready for UI integration and invite code generation.
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/02-household-creation/02-01-SUMMARY.md` with household data layer implementation summary
|
|
</output> |