sojorn/go-backend/internal/models/user.go
Patrick Britton 38653f5854 Sojorn Backend Finalization & Cleanup - Complete Migration from Supabase
##  Phase 1: Critical Feature Completion (Beacon Voting)
- Add VouchBeacon, ReportBeacon, RemoveBeaconVote methods to PostRepository
- Implement beacon voting HTTP handlers with confidence score calculations
- Register new beacon routes: /beacons/:id/vouch, /beacons/:id/report, /beacons/:id/vouch (DELETE)
- Auto-flag beacons at 5+ reports, confidence scoring (0.5 base + 0.1 per vouch)

##  Phase 2: Feed Logic & Post Distribution Integrity
- Verify unified feed logic supports all content types (Standard, Quips, Beacons)
- Ensure proper distribution: Profile Feed + Main/Home Feed for followers
- Beacon Map integration for location-based content
- Video content filtering for Quips feed

##  Phase 3: The Notification System
- Create comprehensive NotificationService with FCM integration
- Add CreateNotification method to NotificationRepository
- Implement smart deep linking: beacon_map, quip_feed, main_feed
- Trigger notifications for beacon interactions and cross-post comments
- Push notification logic with proper content type detection

##  Phase 4: The Great Supabase Purge
- Delete function_proxy.go and remove /functions/:name route
- Remove SupabaseURL, SupabaseKey from config.go
- Remove SupabaseID field from User model
- Clean all Supabase imports and dependencies
- Sanitize codebase of legacy Supabase references

##  Phase 5: Flutter Frontend Integration
- Implement vouchBeacon(), reportBeacon(), removeBeaconVote() in ApiService
- Replace TODO delay in video_comments_sheet.dart with actual publishComment call
- Fix compilation errors (named parameters, orphaned child properties)
- Complete frontend integration with Go API endpoints

##  Additional Improvements
- Fix compilation errors in threaded_comment_widget.dart (orphaned child property)
- Update video_comments_sheet.dart to use proper named parameters
- Comprehensive error handling and validation
- Production-ready notification system with deep linking

##  Migration Status: 100% Complete
- Backend: Fully migrated from Supabase to custom Go/Gin API
- Frontend: Integrated with new Go endpoints
- Notifications: Complete FCM integration with smart routing
- Database: Clean of all Supabase dependencies
- Features: All functionality preserved and enhanced

Ready for VPS deployment and production testing!
2026-01-30 09:24:31 -06:00

101 lines
4.3 KiB
Go

package models
import (
"time"
"github.com/google/uuid"
)
type UserStatus string
const (
UserStatusPending UserStatus = "pending"
UserStatusActive UserStatus = "active"
UserStatusDeactivated UserStatus = "deactivated"
)
type User struct {
ID uuid.UUID `json:"id" db:"id"`
Email string `json:"email" db:"email"`
PasswordHash string `json:"-" db:"encrypted_password"`
Status UserStatus `json:"status" db:"status"`
MFAEnabled bool `json:"mfa_enabled" db:"mfa_enabled"`
LastLogin *time.Time `json:"last_login" db:"last_login"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty" db:"deleted_at"`
}
type Profile struct {
ID uuid.UUID `json:"id" db:"id"`
Handle *string `json:"handle" db:"handle"`
DisplayName *string `json:"display_name" db:"display_name"`
Bio *string `json:"bio" db:"bio"`
AvatarURL *string `json:"avatar_url" db:"avatar_url"`
CoverURL *string `json:"cover_url" db:"cover_url"`
IsOfficial *bool `json:"is_official" db:"is_official"`
IsPrivate *bool `json:"is_private" db:"is_private"`
BeaconEnabled bool `json:"beacon_enabled" db:"beacon_enabled"`
Location *string `json:"location" db:"location"`
Website *string `json:"website" db:"website"`
Interests []string `json:"interests" db:"interests"`
OriginCountry *string `json:"origin_country" db:"origin_country"`
Strikes int `json:"strikes" db:"strikes"`
IdentityKey *string `json:"identity_key" db:"identity_key"`
RegistrationID *int `json:"registration_id" db:"registration_id"`
EncryptedPrivateKey *string `json:"encrypted_private_key" db:"encrypted_private_key"`
HasCompletedOnboarding bool `json:"has_completed_onboarding" db:"has_completed_onboarding"`
Role string `json:"role" db:"role"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
type Follow struct {
FollowerID uuid.UUID `json:"follower_id" db:"follower_id"`
FollowingID uuid.UUID `json:"following_id" db:"following_id"`
Status string `json:"status" db:"status"` // pending, accepted
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
type TrustState struct {
UserID uuid.UUID `json:"user_id" db:"user_id"`
HarmonyScore int `json:"harmony_score" db:"harmony_score"`
Tier string `json:"tier" db:"tier"` // new, trusted, established
PostsToday int `json:"posts_today" db:"posts_today"`
LastPostAt *time.Time `json:"last_post_at" db:"last_post_at"`
LastHarmonyCalcAt *time.Time `json:"last_harmony_calc_at" db:"last_harmony_calc_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
type AuthToken struct {
Token string `json:"token" db:"token"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Type string `json:"type" db:"type"`
ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
type MFASecret struct {
UserID uuid.UUID `json:"user_id" db:"user_id"`
Secret string `json:"-" db:"secret"`
RecoveryCodes []string `json:"-" db:"recovery_codes"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
type WebAuthnCredential struct {
ID []byte `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
PublicKey []byte `json:"public_key" db:"public_key"`
AttestationType string `json:"attestation_type" db:"attestation_type"`
AAGUID *uuid.UUID `json:"aaguid,omitempty" db:"aaguid"`
SignCount uint32 `json:"sign_count" db:"sign_count"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
LastUsedAt time.Time `json:"last_used_at" db:"last_used_at"`
}
type OneTimePrekey struct {
KeyID int `json:"key_id" db:"key_id"`
PublicKey string `json:"public_key" db:"public_key"`
}