File size: 15,389 Bytes
fba6023
 
 
 
3493993
 
 
 
 
 
 
 
 
fba6023
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e1104b3
 
 
 
3493993
fba6023
 
 
 
 
 
 
 
 
e1104b3
 
 
 
 
 
3493993
e1104b3
 
 
 
 
 
 
 
 
3493993
e1104b3
 
 
 
fba6023
 
3493993
 
fba6023
 
3493993
 
 
fba6023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3493993
c91c7db
3493993
 
c91c7db
 
 
e1104b3
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fba6023
 
3493993
 
 
 
 
 
c91c7db
 
3493993
 
 
 
 
 
fba6023
3493993
 
 
fba6023
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fba6023
 
 
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fba6023
e1104b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e1104b3
 
 
 
 
 
3493993
 
 
 
 
 
 
 
 
 
e1104b3
3493993
e1104b3
 
3493993
e1104b3
 
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fba6023
 
3493993
fba6023
 
 
 
 
 
 
 
c91c7db
 
 
 
 
 
 
 
 
 
 
 
3493993
c91c7db
3493993
 
c91c7db
 
 
e1104b3
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fba6023
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
from __future__ import annotations

from dataclasses import dataclass

from app.ai.service import AiStudioService
from app.brand.repositories.brand_repository import BrandKitRepository
from app.brand.services.brand_service import BrandKitService
from app.analytics.service import AnalyticsDomainService
from app.analytics.workers.sync import AnalyticsSyncWorker
from app.copilot.actions import CopilotActionRegistry
from app.copilot.planner import CopilotPlanner
from app.copilot.repository import CopilotRepository
from app.copilot.service import CopilotService
from app.core.config import Settings
from app.generation.model_registry import GenerationModelRegistration, GenerationModelRegistry
from app.generation.providers.flux import (
    FLUX_BASE_MODEL_ID,
    FLUX_DISTILLED_MODEL_ID,
    FLUX_MODEL_CAPABILITY,
    FLUX_PROVIDER_ID,
    FLUX_TASK,
    FluxProviderAdapter,
)
from app.generation.providers.registry import GenerationProviderRegistry
from app.generation.providers.wan import WAN_MODEL_CAPABILITY, WAN_PROVIDER_ID, WanProviderAdapter
from app.generation.repositories.generation import GenerationRepository
from app.generation.services.generation_service import GenerationService
from app.generation.services.output_ingestion import GenerationOutputIngestor
from app.generation.workers.generation_worker import GenerationWorker
from app.projects.repositories.editor_repository import ProjectEditorRepository
from app.projects.repositories.project_repository import ProjectRepository
from app.projects.repositories.render_repository import ProjectRenderRepository
from app.projects.repositories.collaboration_repository import CollaborationRepository
from app.projects.repositories.approval_repository import ApprovalRepository
from app.projects.services.editor_service import ProjectEditorService
from app.projects.services.project_service import ProjectService
from app.projects.services.collaboration_service import CollaborationService
from app.projects.services.approval_service import ApprovalService
from app.projects.services.render_service import ProjectRenderService
from app.projects.workers.render_worker import ProjectRenderWorker
from app.security.assets import CanonicalAssetService
from app.security.audit import AuditService
from app.security.database import SecurityDatabase
from app.security.rate_limit import APIKeyRateLimiter
from app.security.service import APIKeyService
from app.security.tenancy import TenantService
from app.services.cleanup import CleanupService
from app.services.downloader import Downloader
from app.services.ffmpeg_service import FFmpegService
from app.services.ffprobe_service import FFprobeService
from app.services.input_resolver import InputResolver
from app.services.media_service import MediaProcessor
from app.services.validator import MediaValidator
from app.services.whisper_service import WhisperService
from app.services.ytdlp_service import YTDLPService
from app.social.database import SocialDatabase
from app.social.oauth.encryption import TokenCipher
from app.social.oauth.state import OAuthStateService
from app.social.providers.registry import build_provider_registry
from app.social.repositories.accounts import AccountRepository
from app.social.repositories.assets import SocialMediaAssetRepository
from app.social.repositories.batches import PublishingBatchRepository
from app.social.repositories.jobs import JobRepository
from app.social.repositories.posts import PostRepository
from app.social.repositories.tokens import TokenRepository
from app.social.services.account_service import AccountService
from app.social.services.analytics_service import AnalyticsService
from app.social.services.audit_service import SocialAuditService
from app.social.services.job_service import JobService
from app.social.services.media_asset_service import SocialMediaAssetService
from app.social.services.oauth_service import OAuthService
from app.social.services.publishing_operations_service import PublishingOperationsService
from app.social.services.publishing_service import PublishingService
from app.social.services.scheduling_service import SchedulingService
from app.social.services.social_service import SocialService
from app.social.services.token_service import TokenService
from app.templates.executor import OperationExecutor, TemplateExecutor
from app.templates.loader import TemplateLoader
from app.templates.marketplace_repository import MarketplaceTemplateRepository
from app.templates.marketplace_service import MarketplaceTemplateService
from app.templates.registry import TemplateRegistry
from app.templates.validator import TemplateValidator
from app.analytics.repository import AnalyticsRepository
from app.projects.repositories.notification_repository import NotificationRepository
from app.projects.services.notification_service import NotificationService


@dataclass(slots=True)
class Container:
    settings: Settings
    cleanup: CleanupService
    validator: MediaValidator
    downloader: Downloader
    ytdlp: YTDLPService
    ffmpeg: FFmpegService
    ffprobe: FFprobeService
    whisper: WhisperService
    resolver: InputResolver
    processor: MediaProcessor
    template_registry: TemplateRegistry
    template_executor: TemplateExecutor
    template_marketplace: MarketplaceTemplateService
    security_database: SecurityDatabase
    tenants: TenantService
    assets: CanonicalAssetService
    api_keys: APIKeyService
    rate_limiter: APIKeyRateLimiter
    audit: AuditService
    social: SocialService
    ai: AiStudioService
    copilot: CopilotService
    generation: GenerationService
    generation_models: GenerationModelRegistry
    generation_worker: GenerationWorker
    projects: ProjectService
    editor: ProjectEditorService
    renders: ProjectRenderService
    render_worker: ProjectRenderWorker
    analytics: AnalyticsDomainService
    analytics_worker: AnalyticsSyncWorker
    brand_kits: BrandKitService
    collaboration: CollaborationService
    approval: ApprovalService
    notifications: NotificationService

def build_container(settings: Settings) -> Container:
    security_database = SecurityDatabase(
        settings.database_url, auto_migrate=settings.security_auto_migrate
    )
    tenants = TenantService(security_database)
    assets = CanonicalAssetService(security_database)
    api_keys = APIKeyService(security_database, settings, tenants)
    rate_limiter = APIKeyRateLimiter(security_database)
    audit = AuditService(security_database)
    brand_repository = BrandKitRepository(security_database)
    brand_kits = BrandKitService(brand_repository, assets, audit)
    projects = ProjectService(ProjectRepository(security_database), assets, audit, brand_kits)
    collaboration = CollaborationService(CollaborationRepository(security_database))
    approval = ApprovalService(ApprovalRepository(security_database), ProjectEditorRepository(security_database))
    notifications = NotificationService(NotificationRepository(security_database))
    cleanup = CleanupService(settings)
    # Generation output validation shares the established FFprobe/validator
    # services.  Construct them before the output ingestor, without changing
    # existing media or social provider behavior.
    validator = MediaValidator(settings)
    ffprobe = FFprobeService(settings)
    wan = WanProviderAdapter.from_settings(settings)
    flux = FluxProviderAdapter.from_settings(settings)
    generation_providers = GenerationProviderRegistry([wan, flux])
    generation_models = GenerationModelRegistry(
        [
            GenerationModelRegistration(
                provider_id=WAN_PROVIDER_ID,
                model=WAN_MODEL_CAPABILITY,
                configuration_reference="wan-space",
                metadata={
                    "underlying_model_id": "Wan-AI/Wan2.2-I2V-A14B-Diffusers",
                    "task": "image-to-video",
                    "fps": 16,
                },
            ),
            GenerationModelRegistration(
                provider_id=FLUX_PROVIDER_ID,
                model=FLUX_MODEL_CAPABILITY,
                configuration_reference="flux-space",
                metadata={
                    "task": FLUX_TASK,
                    "license": "Apache-2.0",
                    "models": {
                        "distilled": FLUX_DISTILLED_MODEL_ID,
                        "base": FLUX_BASE_MODEL_ID,
                    },
                },
            ),
        ]
    )
    generation = GenerationService(
        settings=settings,
        database=security_database,
        assets=assets,
        repository=GenerationRepository(security_database),
        providers=generation_providers,
        models=generation_models,
        output_ingestor=GenerationOutputIngestor(
            settings=settings,
            cleanup=cleanup,
            assets=assets,
            ffprobe=ffprobe,
            validator=validator,
        ),
    )
    generation_worker = GenerationWorker(
        settings=settings,
        generation=generation,
        assets=assets,
        cleanup=cleanup,
        audit=audit,
    )
    ai = AiStudioService(generation, projects, assets, audit)
    # Social publishing validates the same file-backed outputs as the normal
    # media pipeline, so build those shared services before wiring Social.
    downloader = Downloader(settings, validator)
    ytdlp = YTDLPService(settings, validator)
    ffmpeg = FFmpegService(settings)
    editor_repository = ProjectEditorRepository(security_database)
    editor = ProjectEditorService(
        editor_repository,
        assets,
        audit,
        state_max_bytes=settings.editor_state_max_bytes,
        max_tracks=settings.render_max_tracks,
        max_clips=settings.render_max_clips,
        max_duration_seconds=settings.render_max_duration_seconds,
    )
    render_repository = ProjectRenderRepository(security_database)
    renders = ProjectRenderService(
        settings, render_repository, editor_repository, assets, cleanup, audit
    )
    render_worker = ProjectRenderWorker(
        settings, render_repository, renders, ffmpeg, cleanup, audit
    )
    template_marketplace = MarketplaceTemplateService(
        MarketplaceTemplateRepository(security_database), assets, ai, audit
    )
    copilot_actions = CopilotActionRegistry(
        projects=projects,
        assets=assets,
        editor=editor,
        renders=renders,
        ai=ai,
        templates=template_marketplace,
    )
    copilot = CopilotService(
        repository=CopilotRepository(security_database),
        planner=CopilotPlanner(),
        actions=copilot_actions,
        projects=projects,
        assets=assets,
        editor=editor,
        ai=ai,
        audit=audit,
    )
    whisper = WhisperService(settings)
    social_database = SocialDatabase(settings)
    providers = build_provider_registry(settings)
    account_repository = AccountRepository(social_database)
    post_repository = PostRepository(social_database)
    token_cipher = TokenCipher(
        settings.social_oauth_encryption_key.get_secret_value()
        if settings.social_oauth_encryption_key
        else None
    )
    job_repository = JobRepository(social_database, token_cipher)
    token_service = TokenService(
        TokenRepository(social_database),
        settings,
        token_cipher,
    )
    account_service = AccountService(account_repository, token_service, providers)
    social_audit = SocialAuditService(social_database)
    oauth_service = OAuthService(
        settings,
        providers,
        OAuthStateService(social_database, token_service.cipher),
        account_service,
        social_audit,
    )
    social_media_assets = SocialMediaAssetService(
        settings, SocialMediaAssetRepository(social_database), assets, cleanup, ffprobe, validator
    )
    publishing_service = PublishingService(
        settings,
        post_repository,
        job_repository,
        account_repository,
        providers,
        social_media_assets,
        oauth_service,
        brand_kits,
        projects,
    )
    scheduling_service = SchedulingService(post_repository, social_media_assets)
    social_analytics = AnalyticsService(
        social_database, account_repository, providers, oauth_service
    )
    social = SocialService(
        settings=settings,
        database=social_database,
        accounts=account_service,
        oauth=oauth_service,
        publishing=publishing_service,
        operations=PublishingOperationsService(
            security_database=security_database,
            posts=post_repository,
            jobs=job_repository,
            accounts=account_repository,
            batches=PublishingBatchRepository(social_database),
            publishing=publishing_service,
            scheduling=scheduling_service,
            audit=social_audit,
        ),
        scheduling=scheduling_service,
        jobs=JobService(job_repository),
        media_assets=social_media_assets,
        analytics=social_analytics,
        audit=social_audit,
    )
    analytics = AnalyticsDomainService(
        AnalyticsRepository(social_database),
        providers,
        social_analytics,
        account_repository,
        social_audit,
        projects,
    )
    brand_repository = BrandKitRepository(security_database)
    brand_kits = BrandKitService(brand_repository, assets, audit)
    analytics_worker = AnalyticsSyncWorker(
        analytics,
        social_database,
        interval_seconds=settings.social_scheduler_interval_seconds,
    )
    copilot_actions.analytics = analytics
    copilot_actions.publishing = social.publishing
    copilot_actions.scheduling = social.scheduling
    resolver = InputResolver(settings, cleanup, downloader, ytdlp, validator)
    processor = MediaProcessor(
        settings, resolver, cleanup, validator, ffmpeg, ffprobe, ytdlp, whisper, assets
    )
    operation_executor = OperationExecutor(processor)
    template_validator = TemplateValidator(operation_executor.supported_operations)
    template_registry = TemplateRegistry(
        TemplateLoader(settings.template_dir, template_validator), template_validator
    )
    template_executor = TemplateExecutor(template_registry, operation_executor, processor)
    return Container(
        settings=settings,
        cleanup=cleanup,
        validator=validator,
        downloader=downloader,
        ytdlp=ytdlp,
        ffmpeg=ffmpeg,
        ffprobe=ffprobe,
        whisper=whisper,
        resolver=resolver,
        processor=processor,
        template_registry=template_registry,
        template_executor=template_executor,
        template_marketplace=template_marketplace,
        security_database=security_database,
        tenants=tenants,
        assets=assets,
        api_keys=api_keys,
        rate_limiter=rate_limiter,
        audit=audit,
        social=social,
        ai=ai,
        copilot=copilot,
        generation=generation,
        generation_models=generation.models,
        generation_worker=generation_worker,
        projects=projects,
        editor=editor,
        renders=renders,
        render_worker=render_worker,
        analytics=analytics,
        analytics_worker=analytics_worker,
        brand_kits=brand_kits,
        collaboration=collaboration,
        approval=approval,
        notifications=notifications,
    )