package usecase import ( "context" "encoding/json" "time" "haixun-backend/internal/library/placement" missionentity "haixun-backend/internal/model/copy_mission/domain/entity" "haixun-backend/internal/model/threads_account/domain/entity" ) type AccountSummary struct { ID string DisplayName string Username string ThreadsUserID string PersonaID string BrowserConnected bool ApiConnected bool APITokenExpiresAt int64 Status string CreateAt int64 UpdateAt int64 } type TokenRefreshCandidate struct { AccountID string TenantID string OwnerUID string ExpiresAt int64 } type ConnectionPrefs struct { SearchViaApi bool SearchSourceMode string PublishViaApi bool DevMode bool ScrapeReplies bool RepliesPerPost int PublishHeaded bool PlaywrightDebug bool } type ConnectionData struct { AccountID string AccountName string Username string BrowserConnected bool ApiConnected bool Prefs ConnectionPrefs } type CreateRequest struct { TenantID string OwnerUID string DisplayName string Activate bool } type UpdateAccountRequest struct { TenantID string OwnerUID string AccountID string DisplayName *string PersonaID *string } type UpdateConnectionRequest struct { TenantID string OwnerUID string AccountID string Prefs ConnectionPrefsPatch } type ImportBrowserSessionRequest struct { TenantID string OwnerUID string AccountID string StorageState string } type ImportBrowserSessionResult struct { AccountID string Username string Synced bool Valid bool Message string UpdateAt int64 } type SecretsData struct { AccountID string APIAccessToken string APITokenExpiresAt int64 UpdateAt int64 } type BrowserSessionData struct { AccountID string StorageState string UpdateAt int64 } type AiSettings struct { AccountID string Provider string Model string ResearchProvider string ResearchModel string ApiKeys map[string]string ApiKeysConfigured map[string]bool } type AiSettingsPatch struct { Provider *string Model *string ResearchProvider *string ResearchModel *string ApiKeys map[string]string } // WorkerAiCredential carries raw provider settings for internal workers (never expose to clients). type WorkerAiCredential struct { Provider string Model string APIKey string } type ThreadsPublishCredential struct { AccountID string ThreadsUserID string AccessToken string } type ConnectionPrefsPatch struct { SearchViaApi *bool SearchSourceMode *string PublishViaApi *bool DevMode *bool ScrapeReplies *bool RepliesPerPost *int PublishHeaded *bool PlaywrightDebug *bool } type ListResult struct { List []AccountSummary ActiveAccountID string } type OAuthStartResult struct { AuthorizeURL string State string AccountID string } type OAuthCallbackResult struct { AccountID string Username string ThreadsUserID string RedirectURL string } type OAuthDebugLogEntry struct { At int64 Level string Stage string AccountID string Message string } type APISmokeTestItem struct { Scope string Name string Status string // ok, error, skip, manual Message string Count int } type APIPlaygroundRequest struct { Action string Query string Username string MediaID string ReplyID string ReplyToID string Text string LocationQuery string Limit int Hide bool SearchType string } type APIPlaygroundResult struct { Action string Ok bool Message string Data json.RawMessage } type PostMetricCapability struct { Scope string Name string Metrics []string Trackable bool Note string } type InsightMetricItem struct { Name string Value int } type AccountInsightsBlock struct { Status string Message string Metrics []InsightMetricItem } type PostPerformanceItem struct { MediaID string Text string Permalink string Timestamp string LikeCount int ReplyCount int RepostCount int QuoteCount int Views int Shares int InsightsStatus string InsightsMessage string } type PostPerformanceResult struct { AccountID string Username string ThreadsUserID string FetchedAt int64 Capabilities []PostMetricCapability AccountInsights AccountInsightsBlock Posts []PostPerformanceItem } type UpsertKnownAccountsFromScanRequest struct { TenantID string OwnerUID string AccountID string MissionID string PersonaID string SelectedTags []string SimilarAccounts []missionentity.SimilarAccount } type UseCase interface { List(ctx context.Context, tenantID, ownerUID string) (*ListResult, error) Create(ctx context.Context, req CreateRequest) (*AccountSummary, error) Get(ctx context.Context, tenantID, ownerUID, accountID string) (*AccountSummary, error) Update(ctx context.Context, req UpdateAccountRequest) (*AccountSummary, error) Activate(ctx context.Context, tenantID, ownerUID, accountID string) error Delete(ctx context.Context, tenantID, ownerUID, accountID string) error GetConnection(ctx context.Context, tenantID, ownerUID, accountID string) (*ConnectionData, error) UpdateConnection(ctx context.Context, req UpdateConnectionRequest) (*ConnectionData, error) ImportBrowserSession(ctx context.Context, req ImportBrowserSessionRequest) (*ImportBrowserSessionResult, error) GetBrowserSession(ctx context.Context, tenantID, ownerUID, accountID string) (*BrowserSessionData, error) GetAiSettings(ctx context.Context, tenantID, ownerUID, accountID string) (*AiSettings, error) UpdateAiSettings(ctx context.Context, tenantID, ownerUID, accountID string, patch AiSettingsPatch) (*AiSettings, error) ResolveAiProviderAPIKey(ctx context.Context, tenantID, ownerUID, accountID, provider, overrideKey string) (string, error) ResolveWorkerAiCredential(ctx context.Context, tenantID, ownerUID, accountID string) (*WorkerAiCredential, error) ResolveMemberAiCredential(ctx context.Context, tenantID, ownerUID string) (*WorkerAiCredential, error) ResolveMemberResearchAiCredential(ctx context.Context, tenantID, ownerUID string) (*WorkerAiCredential, error) ResolveMemberPlacementContext(ctx context.Context, tenantID, ownerUID string, research placement.ResearchSettings) (placement.MemberContext, error) ResolveMemberThreadsPublishCredential(ctx context.Context, tenantID, ownerUID string) (*ThreadsPublishCredential, error) SaveAPIAccessToken(ctx context.Context, accountID, accessToken string, expiresAt int64) (*SecretsData, error) StartThreadsOAuth(ctx context.Context, tenantID, ownerUID, accountID string) (*OAuthStartResult, error) CompleteThreadsOAuthCallback(ctx context.Context, code, state string) (*OAuthCallbackResult, error) DisconnectThreadsAPI(ctx context.Context, tenantID, ownerUID, accountID string) (*AccountSummary, error) ListOAuthDebugLogs(limit int) []OAuthDebugLogEntry RecordOAuthDebug(level, stage, accountID, message string) RunAPISmokeTest(ctx context.Context, tenantID, ownerUID, accountID string) ([]APISmokeTestItem, error) RunAPIPlayground(ctx context.Context, tenantID, ownerUID, accountID string, req APIPlaygroundRequest) (*APIPlaygroundResult, error) ListPostPerformance(ctx context.Context, tenantID, ownerUID, accountID string, limit int) (*PostPerformanceResult, error) ResolveAccountAPIAccessToken(ctx context.Context, tenantID, ownerUID, accountID string) (string, error) RefreshAccountAPIAccessToken(ctx context.Context, tenantID, ownerUID, accountID string) (*SecretsData, error) ListTokenRefreshCandidates(ctx context.Context, leadTime time.Duration) ([]TokenRefreshCandidate, error) ResolveMemberCapabilities(ctx context.Context, tenantID, ownerUID string, research placement.ResearchSettings) (placement.MemberCapabilities, error) GetKnownAccounts(ctx context.Context, tenantID, ownerUID, accountID string) (map[string]entity.KnownAccountProfile, error) UpsertKnownAccountsFromScan(ctx context.Context, req UpsertKnownAccountsFromScanRequest) error }