@umituz/web-firebase 1.0.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +555 -0
  2. package/dist/application/index.d.mts +273 -0
  3. package/dist/application/index.d.ts +273 -0
  4. package/dist/application/index.js +490 -0
  5. package/dist/application/index.mjs +19 -0
  6. package/dist/chunk-34DL2QWQ.mjs +87 -0
  7. package/dist/chunk-4FP2ELQ5.mjs +96 -0
  8. package/dist/chunk-7TX3OU3O.mjs +721 -0
  9. package/dist/chunk-I6WGBPFB.mjs +439 -0
  10. package/dist/chunk-RZ4QR6TB.mjs +96 -0
  11. package/dist/chunk-U2XI4MGO.mjs +397 -0
  12. package/dist/domain/index.d.mts +325 -0
  13. package/dist/domain/index.d.ts +325 -0
  14. package/dist/domain/index.js +662 -0
  15. package/dist/domain/index.mjs +36 -0
  16. package/dist/file.repository.interface-v5vHgVsZ.d.mts +241 -0
  17. package/dist/file.repository.interface-v5vHgVsZ.d.ts +241 -0
  18. package/dist/firebase.entity-xvfEPjXZ.d.mts +15 -0
  19. package/dist/firebase.entity-xvfEPjXZ.d.ts +15 -0
  20. package/dist/index.d.mts +14 -96
  21. package/dist/index.d.ts +14 -96
  22. package/dist/index.js +1717 -78
  23. package/dist/index.mjs +88 -175
  24. package/dist/infrastructure/index.d.mts +170 -0
  25. package/dist/infrastructure/index.d.ts +170 -0
  26. package/dist/infrastructure/index.js +856 -0
  27. package/dist/infrastructure/index.mjs +46 -0
  28. package/dist/presentation/index.d.mts +25 -0
  29. package/dist/presentation/index.d.ts +25 -0
  30. package/dist/presentation/index.js +105 -0
  31. package/dist/presentation/index.mjs +6 -0
  32. package/dist/user.repository.interface-DS74TsJ5.d.mts +298 -0
  33. package/dist/user.repository.interface-DS74TsJ5.d.ts +298 -0
  34. package/package.json +37 -11
  35. package/src/application/dto/auth.dto.ts +69 -0
  36. package/src/application/dto/index.ts +7 -0
  37. package/src/application/dto/user.dto.ts +64 -0
  38. package/src/application/index.ts +7 -0
  39. package/src/application/use-cases/auth/reset-password.use-case.ts +66 -0
  40. package/src/application/use-cases/auth/sign-in-with-google.use-case.ts +86 -0
  41. package/src/application/use-cases/auth/sign-in.use-case.ts +77 -0
  42. package/src/application/use-cases/auth/sign-out.use-case.ts +22 -0
  43. package/src/application/use-cases/auth/sign-up.use-case.ts +99 -0
  44. package/src/application/use-cases/index.ts +12 -0
  45. package/src/application/use-cases/user/delete-account.use-case.ts +77 -0
  46. package/src/application/use-cases/user/update-profile.use-case.ts +98 -0
  47. package/src/domain/entities/file.entity.ts +151 -0
  48. package/src/domain/entities/timestamp.entity.ts +116 -0
  49. package/src/domain/entities/user.entity.ts +193 -0
  50. package/src/domain/errors/auth.errors.ts +115 -0
  51. package/src/domain/errors/repository.errors.ts +121 -0
  52. package/src/domain/index.ts +25 -2
  53. package/src/domain/interfaces/auth.repository.interface.ts +83 -0
  54. package/src/domain/interfaces/file.repository.interface.ts +143 -0
  55. package/src/domain/interfaces/user.repository.interface.ts +75 -0
  56. package/src/domain/value-objects/email.vo.ts +105 -0
  57. package/src/domain/value-objects/file-path.vo.ts +184 -0
  58. package/src/domain/value-objects/user-id.vo.ts +87 -0
  59. package/src/index.ts +19 -4
  60. package/src/infrastructure/firebase/auth.adapter.ts +220 -0
  61. package/src/infrastructure/firebase/client.ts +141 -0
  62. package/src/infrastructure/firebase/firestore.adapter.ts +190 -0
  63. package/src/infrastructure/firebase/storage.adapter.ts +323 -0
  64. package/src/infrastructure/index.ts +10 -5
  65. package/src/infrastructure/utils/storage.util.ts +3 -3
  66. package/src/presentation/hooks/useAuth.ts +153 -0
  67. package/src/presentation/hooks/useFirestore.ts +125 -0
  68. package/src/presentation/hooks/useStorage.ts +141 -0
  69. package/src/presentation/providers/FirebaseProvider.tsx +40 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * User Domain Entities
3
+ * @description Core user-related entities following DDD principles
4
+ * Migrated from: /Users/umituz/Desktop/github/umituz/apps/web/app-growth-factory/src/domains/firebase/types/index.ts
5
+ */
6
+
7
+ /**
8
+ * User Profile Value Object
9
+ * Immutable user profile data
10
+ */
11
+ export interface UserProfile {
12
+ readonly id: string
13
+ readonly email: string
14
+ readonly displayName: string
15
+ readonly photoURL?: string
16
+ readonly phoneNumber?: string
17
+ readonly createdAt: number
18
+ readonly updatedAt: number
19
+ readonly lastLoginAt: number
20
+ readonly emailVerified: boolean
21
+ }
22
+
23
+ /**
24
+ * User Notifications Settings
25
+ */
26
+ export interface UserNotifications {
27
+ email: boolean
28
+ push: boolean
29
+ marketing: boolean
30
+ security: boolean
31
+ weeklyDigest: boolean
32
+ }
33
+
34
+ /**
35
+ * User Privacy Settings
36
+ */
37
+ export interface UserPrivacy {
38
+ profileVisibility: 'public' | 'private'
39
+ showEmail: boolean
40
+ showPhone: boolean
41
+ dataSharing: boolean
42
+ }
43
+
44
+ /**
45
+ * User Settings Value Object
46
+ */
47
+ export interface UserSettings {
48
+ theme: 'light' | 'dark' | 'system'
49
+ language: string
50
+ timezone: string
51
+ currency: string
52
+ notifications: UserNotifications
53
+ privacy: UserPrivacy
54
+ }
55
+
56
+ /**
57
+ * User Subscription Value Object
58
+ */
59
+ export interface UserSubscription {
60
+ plan: 'free' | 'standard' | 'professional' | 'business'
61
+ status: 'active' | 'inactive' | 'canceled' | 'past_due'
62
+ polarCustomerId?: string
63
+ polarSubscriptionId?: string
64
+ currentPeriodStart?: number
65
+ currentPeriodEnd?: number
66
+ cancelAtPeriodEnd: boolean
67
+ readonly createdAt: number
68
+ readonly updatedAt: number
69
+ }
70
+
71
+ /**
72
+ * Account Metrics Value Object
73
+ */
74
+ export interface AccountMetrics {
75
+ followers: number
76
+ following: number
77
+ posts: number
78
+ engagement: number
79
+ lastSyncedAt: number
80
+ }
81
+
82
+ /**
83
+ * User Connected Account Entity
84
+ */
85
+ export interface UserConnectedAccount {
86
+ platform:
87
+ | 'twitter'
88
+ | 'facebook'
89
+ | 'instagram'
90
+ | 'linkedin'
91
+ | 'tiktok'
92
+ | 'youtube'
93
+ | 'pinterest'
94
+ | 'reddit'
95
+ | 'threads'
96
+ | 'discord'
97
+ | 'telegram'
98
+ | 'mastodon'
99
+ | 'medium'
100
+ connected: boolean
101
+ readonly connectedAt: number
102
+ username?: string
103
+ profileId?: string
104
+ accessToken?: string
105
+ refreshToken?: string
106
+ tokenExpiresAt?: number
107
+ metrics?: AccountMetrics
108
+ }
109
+
110
+ /**
111
+ * User Content Entity
112
+ */
113
+ export interface UserContent {
114
+ readonly id: string
115
+ type: 'post' | 'article' | 'video' | 'image' | 'story' | 'reel'
116
+ title: string
117
+ content: string
118
+ platforms: string[]
119
+ status: 'draft' | 'scheduled' | 'published' | 'failed'
120
+ scheduledFor?: number
121
+ publishedAt?: number
122
+ readonly createdAt: number
123
+ readonly updatedAt: number
124
+ mediaUrls?: string[]
125
+ metadata?: Record<string, unknown>
126
+ }
127
+
128
+ /**
129
+ * Platform Breakdown for Analytics
130
+ */
131
+ export interface PlatformBreakdown {
132
+ [platform: string]: {
133
+ posts: number
134
+ engagement: number
135
+ reach: number
136
+ }
137
+ }
138
+
139
+ /**
140
+ * User Analytics Value Object
141
+ */
142
+ export interface UserAnalytics {
143
+ totalPosts: number
144
+ totalEngagement: number
145
+ totalReach: number
146
+ topPerformingPosts: string[] // content IDs
147
+ platformBreakdown: PlatformBreakdown
148
+ lastCalculatedAt: number
149
+ }
150
+
151
+ /**
152
+ * User Credits Value Object
153
+ */
154
+ export interface UserCredits {
155
+ standard: number
156
+ professional: number
157
+ total: number
158
+ resetAt: number
159
+ lastResetAt: number
160
+ }
161
+
162
+ /**
163
+ * User Aggregate Root
164
+ * Main user document containing all user-related data
165
+ * This is the aggregate root for the User domain
166
+ */
167
+ export interface User {
168
+ readonly profile: UserProfile
169
+ settings: UserSettings
170
+ subscription: UserSubscription
171
+ connectedAccounts: UserConnectedAccount[]
172
+ content: UserContent[]
173
+ analytics: UserAnalytics
174
+ credits: UserCredits
175
+ }
176
+
177
+ /**
178
+ * Collection Constants
179
+ */
180
+ export const USER_COLLECTIONS = {
181
+ USERS: 'users',
182
+ CONTENT: 'content',
183
+ ANALYTICS: 'analytics',
184
+ CONNECTED_ACCOUNTS: 'connectedAccounts',
185
+ } as const
186
+
187
+ export const USER_SUBCOLLECTIONS = {
188
+ CONTENT: 'content',
189
+ ANALYTICS: 'analytics',
190
+ SCHEDULED: 'scheduled',
191
+ PUBLISHED: 'published',
192
+ DRAFTS: 'drafts',
193
+ } as const
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Domain Errors for Authentication
3
+ * @description Custom error types for authentication-related failures
4
+ */
5
+
6
+ export class AuthError extends Error {
7
+ constructor(
8
+ message: string,
9
+ public code: AuthErrorCode,
10
+ public originalError?: unknown
11
+ ) {
12
+ super(message)
13
+ this.name = 'AuthError'
14
+ }
15
+ }
16
+
17
+ export enum AuthErrorCode {
18
+ // Auth Errors
19
+ USER_NOT_FOUND = 'USER_NOT_FOUND',
20
+ USER_ALREADY_EXISTS = 'USER_ALREADY_EXISTS',
21
+ INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',
22
+ WEAK_PASSWORD = 'WEAK_PASSWORD',
23
+ EMAIL_NOT_VERIFIED = 'EMAIL_NOT_VERIFIED',
24
+
25
+ // Session Errors
26
+ SESSION_EXPIRED = 'SESSION_EXPIRED',
27
+ UNAUTHENTICATED = 'UNAUTHENTICATED',
28
+ TOO_MANY_REQUESTS = 'TOO_MANY_REQUESTS',
29
+
30
+ // Provider Errors
31
+ OAUTH_ERROR = 'OAUTH_ERROR',
32
+ OAUTH_CANCELLED = 'OAUTH_CANCELLED',
33
+ OAUTH_ACCOUNT_EXISTS = 'OAUTH_ACCOUNT_EXISTS',
34
+
35
+ // Operation Errors
36
+ SIGN_IN_FAILED = 'SIGN_IN_FAILED',
37
+ SIGN_UP_FAILED = 'SIGN_UP_FAILED',
38
+ SIGN_OUT_FAILED = 'SIGN_OUT_FAILED',
39
+ PASSWORD_RESET_FAILED = 'PASSWORD_RESET_FAILED',
40
+ EMAIL_VERIFICATION_FAILED = 'EMAIL_VERIFICATION_FAILED',
41
+
42
+ // Profile Errors
43
+ PROFILE_UPDATE_FAILED = 'PROFILE_UPDATE_FAILED',
44
+ EMAIL_UPDATE_FAILED = 'EMAIL_UPDATE_FAILED',
45
+ PASSWORD_UPDATE_FAILED = 'PASSWORD_UPDATE_FAILED',
46
+ ACCOUNT_DELETE_FAILED = 'ACCOUNT_DELETE_FAILED',
47
+
48
+ // Reauthentication Errors
49
+ REAUTHENTICATION_REQUIRED = 'REAUTHENTICATION_REQUIRED',
50
+ REAUTHENTICATION_FAILED = 'REAUTHENTICATION_FAILED',
51
+
52
+ // Unknown Error
53
+ UNKNOWN = 'UNKNOWN',
54
+ }
55
+
56
+ export function createAuthError(
57
+ code: AuthErrorCode,
58
+ message?: string,
59
+ originalError?: unknown
60
+ ): AuthError {
61
+ const defaultMessage = getAuthErrorMessage(code)
62
+ return new AuthError(message || defaultMessage, code, originalError)
63
+ }
64
+
65
+ function getAuthErrorMessage(code: AuthErrorCode): string {
66
+ switch (code) {
67
+ case AuthErrorCode.USER_NOT_FOUND:
68
+ return 'User not found'
69
+ case AuthErrorCode.USER_ALREADY_EXISTS:
70
+ return 'User already exists'
71
+ case AuthErrorCode.INVALID_CREDENTIALS:
72
+ return 'Invalid credentials'
73
+ case AuthErrorCode.WEAK_PASSWORD:
74
+ return 'Password is too weak'
75
+ case AuthErrorCode.EMAIL_NOT_VERIFIED:
76
+ return 'Email not verified'
77
+ case AuthErrorCode.SESSION_EXPIRED:
78
+ return 'Session expired'
79
+ case AuthErrorCode.UNAUTHENTICATED:
80
+ return 'User not authenticated'
81
+ case AuthErrorCode.TOO_MANY_REQUESTS:
82
+ return 'Too many requests'
83
+ case AuthErrorCode.OAUTH_ERROR:
84
+ return 'OAuth error occurred'
85
+ case AuthErrorCode.OAUTH_CANCELLED:
86
+ return 'OAuth cancelled by user'
87
+ case AuthErrorCode.OAUTH_ACCOUNT_EXISTS:
88
+ return 'Account already exists with this provider'
89
+ case AuthErrorCode.SIGN_IN_FAILED:
90
+ return 'Sign in failed'
91
+ case AuthErrorCode.SIGN_UP_FAILED:
92
+ return 'Sign up failed'
93
+ case AuthErrorCode.SIGN_OUT_FAILED:
94
+ return 'Sign out failed'
95
+ case AuthErrorCode.PASSWORD_RESET_FAILED:
96
+ return 'Password reset failed'
97
+ case AuthErrorCode.EMAIL_VERIFICATION_FAILED:
98
+ return 'Email verification failed'
99
+ case AuthErrorCode.PROFILE_UPDATE_FAILED:
100
+ return 'Profile update failed'
101
+ case AuthErrorCode.EMAIL_UPDATE_FAILED:
102
+ return 'Email update failed'
103
+ case AuthErrorCode.PASSWORD_UPDATE_FAILED:
104
+ return 'Password update failed'
105
+ case AuthErrorCode.ACCOUNT_DELETE_FAILED:
106
+ return 'Account deletion failed'
107
+ case AuthErrorCode.REAUTHENTICATION_REQUIRED:
108
+ return 'Reauthentication required'
109
+ case AuthErrorCode.REAUTHENTICATION_FAILED:
110
+ return 'Reauthentication failed'
111
+ case AuthErrorCode.UNKNOWN:
112
+ default:
113
+ return 'An unknown error occurred'
114
+ }
115
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Domain Errors for Repository Operations
3
+ * @description Custom error types for repository-related failures
4
+ */
5
+
6
+ export class RepositoryError extends Error {
7
+ constructor(
8
+ message: string,
9
+ public code: RepositoryErrorCode,
10
+ public originalError?: unknown
11
+ ) {
12
+ super(message)
13
+ this.name = 'RepositoryError'
14
+ }
15
+ }
16
+
17
+ export enum RepositoryErrorCode {
18
+ // Document Errors
19
+ DOCUMENT_NOT_FOUND = 'DOCUMENT_NOT_FOUND',
20
+ DOCUMENT_ALREADY_EXISTS = 'DOCUMENT_ALREADY_EXISTS',
21
+ DOCUMENT_INVALID = 'DOCUMENT_INVALID',
22
+
23
+ // Collection Errors
24
+ COLLECTION_NOT_FOUND = 'COLLECTION_NOT_FOUND',
25
+ COLLECTION_INVALID = 'COLLECTION_INVALID',
26
+
27
+ // Query Errors
28
+ QUERY_INVALID = 'QUERY_INVALID',
29
+ QUERY_FAILED = 'QUERY_FAILED',
30
+
31
+ // Transaction Errors
32
+ TRANSACTION_FAILED = 'TRANSACTION_FAILED',
33
+ TRANSACTION_ABORTED = 'TRANSACTION_ABORTED',
34
+
35
+ // Network Errors
36
+ NETWORK_ERROR = 'NETWORK_ERROR',
37
+ TIMEOUT = 'TIMEOUT',
38
+ OFFLINE = 'OFFLINE',
39
+
40
+ // Permission Errors
41
+ PERMISSION_DENIED = 'PERMISSION_DENIED',
42
+ UNAUTHORIZED = 'UNAUTHORIZED',
43
+
44
+ // Validation Errors
45
+ VALIDATION_FAILED = 'VALIDATION_FAILED',
46
+ INVALID_DATA = 'INVALID_DATA',
47
+
48
+ // Concurrency Errors
49
+ CONFLICT = 'CONFLICT',
50
+ VERSION_MISMATCH = 'VERSION_MISMATCH',
51
+
52
+ // Storage Errors
53
+ STORAGE_ERROR = 'STORAGE_ERROR',
54
+ FILE_NOT_FOUND = 'FILE_NOT_FOUND',
55
+ FILE_TOO_LARGE = 'FILE_TOO_LARGE',
56
+ INVALID_FILE_TYPE = 'INVALID_FILE_TYPE',
57
+
58
+ // Unknown Error
59
+ UNKNOWN = 'UNKNOWN',
60
+ }
61
+
62
+ export function createRepositoryError(
63
+ code: RepositoryErrorCode,
64
+ message?: string,
65
+ originalError?: unknown
66
+ ): RepositoryError {
67
+ const defaultMessage = getRepositoryErrorMessage(code)
68
+ return new RepositoryError(message || defaultMessage, code, originalError)
69
+ }
70
+
71
+ function getRepositoryErrorMessage(code: RepositoryErrorCode): string {
72
+ switch (code) {
73
+ case RepositoryErrorCode.DOCUMENT_NOT_FOUND:
74
+ return 'Document not found'
75
+ case RepositoryErrorCode.DOCUMENT_ALREADY_EXISTS:
76
+ return 'Document already exists'
77
+ case RepositoryErrorCode.DOCUMENT_INVALID:
78
+ return 'Document is invalid'
79
+ case RepositoryErrorCode.COLLECTION_NOT_FOUND:
80
+ return 'Collection not found'
81
+ case RepositoryErrorCode.COLLECTION_INVALID:
82
+ return 'Collection is invalid'
83
+ case RepositoryErrorCode.QUERY_INVALID:
84
+ return 'Query is invalid'
85
+ case RepositoryErrorCode.QUERY_FAILED:
86
+ return 'Query failed'
87
+ case RepositoryErrorCode.TRANSACTION_FAILED:
88
+ return 'Transaction failed'
89
+ case RepositoryErrorCode.TRANSACTION_ABORTED:
90
+ return 'Transaction aborted'
91
+ case RepositoryErrorCode.NETWORK_ERROR:
92
+ return 'Network error'
93
+ case RepositoryErrorCode.TIMEOUT:
94
+ return 'Request timeout'
95
+ case RepositoryErrorCode.OFFLINE:
96
+ return 'Client is offline'
97
+ case RepositoryErrorCode.PERMISSION_DENIED:
98
+ return 'Permission denied'
99
+ case RepositoryErrorCode.UNAUTHORIZED:
100
+ return 'Unauthorized'
101
+ case RepositoryErrorCode.VALIDATION_FAILED:
102
+ return 'Validation failed'
103
+ case RepositoryErrorCode.INVALID_DATA:
104
+ return 'Invalid data'
105
+ case RepositoryErrorCode.CONFLICT:
106
+ return 'Conflict occurred'
107
+ case RepositoryErrorCode.VERSION_MISMATCH:
108
+ return 'Version mismatch'
109
+ case RepositoryErrorCode.STORAGE_ERROR:
110
+ return 'Storage error'
111
+ case RepositoryErrorCode.FILE_NOT_FOUND:
112
+ return 'File not found'
113
+ case RepositoryErrorCode.FILE_TOO_LARGE:
114
+ return 'File is too large'
115
+ case RepositoryErrorCode.INVALID_FILE_TYPE:
116
+ return 'Invalid file type'
117
+ case RepositoryErrorCode.UNKNOWN:
118
+ default:
119
+ return 'An unknown error occurred'
120
+ }
121
+ }
@@ -3,5 +3,28 @@
3
3
  * Subpath: @umituz/web-firebase/domain
4
4
  */
5
5
 
6
- export * from './entities/firebase.entity';
7
- export * from './interfaces/repository.interface';
6
+ /**
7
+ * Domain Layer Public API
8
+ * @description Exports all domain entities, value objects, interfaces, and errors
9
+ */
10
+
11
+ // Entities
12
+ export type { FirebaseUser, FirebaseTimestamp } from './entities/firebase.entity'
13
+ export * from './entities/user.entity'
14
+ export * from './entities/file.entity'
15
+ export * from './entities/timestamp.entity'
16
+
17
+ // Value Objects
18
+ export * from './value-objects/email.vo'
19
+ export * from './value-objects/user-id.vo'
20
+ export * from './value-objects/file-path.vo'
21
+
22
+ // Interfaces
23
+ export * from './interfaces/repository.interface'
24
+ export * from './interfaces/auth.repository.interface'
25
+ export * from './interfaces/user.repository.interface'
26
+ export * from './interfaces/file.repository.interface'
27
+
28
+ // Errors
29
+ export * from './errors/auth.errors'
30
+ export * from './errors/repository.errors'
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Authentication Repository Interface
3
+ * @description Defines contract for authentication operations
4
+ */
5
+
6
+ import type { User as FirebaseUser, UserCredential } from 'firebase/auth'
7
+ import type { User } from '../entities/user.entity'
8
+
9
+ /**
10
+ * Authentication Repository Interface
11
+ * Defines operations for user authentication and management
12
+ */
13
+ export interface IAuthRepository {
14
+ /**
15
+ * Sign in with email and password
16
+ */
17
+ signIn(email: string, password: string): Promise<UserCredential>
18
+
19
+ /**
20
+ * Sign up with email, password, and display name
21
+ */
22
+ signUp(email: string, password: string, displayName: string): Promise<UserCredential>
23
+
24
+ /**
25
+ * Sign in with Google OAuth
26
+ */
27
+ signInWithGoogle(): Promise<UserCredential>
28
+
29
+ /**
30
+ * Sign out current user
31
+ */
32
+ signOut(): Promise<void>
33
+
34
+ /**
35
+ * Send password reset email
36
+ */
37
+ sendPasswordReset(email: string): Promise<void>
38
+
39
+ /**
40
+ * Resend email verification
41
+ */
42
+ resendEmailVerification(): Promise<void>
43
+
44
+ /**
45
+ * Update user profile (displayName, photoURL)
46
+ */
47
+ updateProfile(updates: Partial<Pick<User['profile'], 'displayName' | 'photoURL'>>): Promise<void>
48
+
49
+ /**
50
+ * Update user email (requires password)
51
+ */
52
+ updateEmail(newEmail: string, password: string): Promise<void>
53
+
54
+ /**
55
+ * Update user password (requires current password)
56
+ */
57
+ updatePassword(currentPassword: string, newPassword: string): Promise<void>
58
+
59
+ /**
60
+ * Delete user account (requires password)
61
+ */
62
+ deleteAccount(password: string): Promise<void>
63
+
64
+ /**
65
+ * Get current authenticated user
66
+ */
67
+ getCurrentUser(): FirebaseUser | null
68
+
69
+ /**
70
+ * Subscribe to auth state changes
71
+ */
72
+ onAuthStateChanged(callback: (user: FirebaseUser | null) => void): () => void
73
+
74
+ /**
75
+ * Create user document in Firestore
76
+ */
77
+ createUserDocument(userId: string, data: Partial<Omit<User, 'profile'>> & { email: string; displayName: string }): Promise<void>
78
+
79
+ /**
80
+ * Update last login timestamp
81
+ */
82
+ updateLastLogin(userId: string): Promise<void>
83
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * File Repository Interface
3
+ * @description Defines contract for file storage operations
4
+ */
5
+
6
+ import type {
7
+ FileMetadata,
8
+ UploadResult,
9
+ UploadOptions,
10
+ FileFilters,
11
+ FileQueryResult,
12
+ StorageStats,
13
+ } from '../entities/file.entity'
14
+
15
+ /**
16
+ * File Repository Interface
17
+ * Defines operations for file storage and management
18
+ */
19
+ export interface IFileRepository {
20
+ /**
21
+ * Upload file to storage
22
+ */
23
+ uploadFile(
24
+ userId: string,
25
+ path: string,
26
+ file: File | Blob,
27
+ options?: UploadOptions
28
+ ): Promise<UploadResult>
29
+
30
+ /**
31
+ * Upload image with automatic categorization
32
+ */
33
+ uploadImage(userId: string, file: File, filename?: string): Promise<UploadResult>
34
+
35
+ /**
36
+ * Upload video with automatic categorization
37
+ */
38
+ uploadVideo(userId: string, file: File, filename?: string): Promise<UploadResult>
39
+
40
+ /**
41
+ * Upload document with automatic categorization
42
+ */
43
+ uploadDocument(userId: string, file: File, filename?: string): Promise<UploadResult>
44
+
45
+ /**
46
+ * Upload profile picture
47
+ */
48
+ uploadProfilePicture(userId: string, file: File): Promise<UploadResult>
49
+
50
+ /**
51
+ * Get download URL for a file
52
+ */
53
+ getDownloadURL(path: string): Promise<string>
54
+
55
+ /**
56
+ * Delete file by path
57
+ */
58
+ deleteFile(path: string): Promise<void>
59
+
60
+ /**
61
+ * Delete all user files
62
+ */
63
+ deleteUserFiles(userId: string): Promise<void>
64
+
65
+ /**
66
+ * Delete user image
67
+ */
68
+ deleteImage(userId: string, filename: string): Promise<void>
69
+
70
+ /**
71
+ * Delete user video
72
+ */
73
+ deleteVideo(userId: string, filename: string): Promise<void>
74
+
75
+ /**
76
+ * Delete profile picture
77
+ */
78
+ deleteProfilePicture(userId: string, filename: string): Promise<void>
79
+
80
+ /**
81
+ * List user files
82
+ */
83
+ listUserFiles(userId: string, path?: string): Promise<string[]>
84
+
85
+ /**
86
+ * List user images
87
+ */
88
+ listUserImages(userId: string): Promise<string[]>
89
+
90
+ /**
91
+ * List user videos
92
+ */
93
+ listUserVideos(userId: string): Promise<string[]>
94
+
95
+ /**
96
+ * Get file metadata
97
+ */
98
+ getFileMetadata(path: string): Promise<FileMetadata>
99
+
100
+ /**
101
+ * Query files with filters
102
+ */
103
+ queryFiles(userId: string, filters?: FileFilters): Promise<FileQueryResult>
104
+
105
+ /**
106
+ * Get storage statistics
107
+ */
108
+ getStorageStats(userId: string): Promise<StorageStats>
109
+
110
+ /**
111
+ * Validate file before upload
112
+ */
113
+ validateFile(file: File, options?: {
114
+ maxSizeBytes?: number
115
+ maxSizeMB?: number
116
+ allowedTypes?: string[]
117
+ }): boolean
118
+
119
+ /**
120
+ * Check if file is an image
121
+ */
122
+ isImageFile(file: File): boolean
123
+
124
+ /**
125
+ * Check if file is a video
126
+ */
127
+ isVideoFile(file: File): boolean
128
+
129
+ /**
130
+ * Check if file is a document
131
+ */
132
+ isDocumentFile(file: File): boolean
133
+
134
+ /**
135
+ * Generate unique filename
136
+ */
137
+ generateUniqueFilename(originalName: string): string
138
+
139
+ /**
140
+ * Get file extension
141
+ */
142
+ getFileExtension(filename: string): string
143
+ }