Add generate-share-package endpoint for residence sharing

- Add POST /api/residences/:id/generate-share-package/ endpoint
- Add SharePackageResponse DTO with share code and metadata
- Add GenerateSharePackage service method to create one-time share codes
- Update JoinWithCode to deactivate share code after successful use

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-06 18:55:48 -06:00
parent 83384db014
commit 3b9e37d12b
5 changed files with 90 additions and 1 deletions

View File

@@ -337,6 +337,48 @@ func (s *ResidenceService) GenerateShareCode(residenceID, userID uint, expiresIn
}, nil
}
// GenerateSharePackage generates a share code and returns package metadata for .casera file
func (s *ResidenceService) GenerateSharePackage(residenceID, userID uint, expiresInHours int) (*responses.SharePackageResponse, error) {
// Check ownership (only owners can share residences)
isOwner, err := s.residenceRepo.IsOwner(residenceID, userID)
if err != nil {
return nil, err
}
if !isOwner {
return nil, ErrNotResidenceOwner
}
// Get residence details for the package
residence, err := s.residenceRepo.FindByID(residenceID)
if err != nil {
return nil, err
}
// Get the user who's sharing
user, err := s.userRepo.FindByID(userID)
if err != nil {
return nil, err
}
// Default to 24 hours if not specified
if expiresInHours <= 0 {
expiresInHours = 24
}
// Generate the share code
shareCode, err := s.residenceRepo.CreateShareCode(residenceID, userID, time.Duration(expiresInHours)*time.Hour)
if err != nil {
return nil, err
}
return &responses.SharePackageResponse{
ShareCode: shareCode.Code,
ResidenceName: residence.Name,
SharedBy: user.Email,
ExpiresAt: shareCode.ExpiresAt,
}, nil
}
// JoinWithCode allows a user to join a residence using a share code
func (s *ResidenceService) JoinWithCode(code string, userID uint) (*responses.JoinResidenceResponse, error) {
// Find the share code
@@ -362,6 +404,12 @@ func (s *ResidenceService) JoinWithCode(code string, userID uint) (*responses.Jo
return nil, err
}
// Mark share code as used (one-time use)
if err := s.residenceRepo.DeactivateShareCode(shareCode.ID); err != nil {
// Log the error but don't fail the join - the user has already been added
// The code will just be usable by others until it expires
}
// Get the residence with full details
residence, err := s.residenceRepo.FindByID(shareCode.ResidenceID)
if err != nil {