main
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-05-06 10:48:07 +02:00
parent 2d6f068363
commit a40619ef33
44 changed files with 4295 additions and 126 deletions
+1765
View File
File diff suppressed because it is too large Load Diff
+236
View File
@@ -0,0 +1,236 @@
[Nest] 1 - 05/03/2026, 1:45:28 PM  LOG [Bootstrap] 🔄 ContentGen AI başlatılıyor...
📦 Using in-memory cache
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"NestFactory","msg":"Starting Nest application..."}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"DatabaseModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"PassportModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ExtractorModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"EventsModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ConfigHostModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"DiscoveryModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"StorageService","msg":"📦 Storage: lokal depolama — /data/media"}
{"level":40,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"BillingService","msg":"⚠️ STRIPE_SECRET_KEY ayarlanmamış — Ödeme sistemi devre dışı"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"XTwitterModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ConfigModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ConfigModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ConfigModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"TerminusModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"StorageModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"VideoAiModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"BullModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"GeminiModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"RenderCallbackModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"BullModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"NotificationsModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"HealthModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ThrottlerModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"JwtModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"LoggerModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"CacheModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"BillingModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"BullModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"UsersModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"VideoQueueModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"AuthModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"DashboardModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"AdminModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"ProjectsModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"AppModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"InstanceLoader","msg":"I18nModule dependencies initialized"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"📂 Medya dizini: /data/media → /media/*"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"Swagger başlatılıyor..."}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"Swagger hazır"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"Port 3000 üzerinde dinleniyor..."}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"WebSocketsController","msg":"EventsGateway subscribed to the \"join:project\" message"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"WebSocketsController","msg":"EventsGateway subscribed to the \"leave:project\" message"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"WebSocketsController","msg":"EventsGateway subscribed to the \"join:user\" message"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"WebSocketsController","msg":"EventsGateway subscribed to the \"leave:user\" message"}
{"level":40,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"LegacyRouteConverter","msg":"Unsupported route path: \"/api/*\". In previous versions, the symbols ?, *, and + were used to denote optional or repeating path parameters. The latest version of \"path-to-regexp\" now requires the use of named parameters. For example, instead of using a route like /users/* to capture all routes starting with \"/users\", you should use /users/*path. For more details, refer to the migration guide. Attempting to auto-convert..."}
{"level":40,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"LegacyRouteConverter","msg":"Unsupported route path: \"/api/*\". In previous versions, the symbols ?, *, and + were used to denote optional or repeating path parameters. The latest version of \"path-to-regexp\" now requires the use of named parameters. For example, instead of using a route like /users/* to capture all routes starting with \"/users\", you should use /users/*path. For more details, refer to the migration guide. Attempting to auto-convert..."}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"AuthController {/api/auth}:"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/auth/register, POST} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/auth/login, POST} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/auth/refresh, POST} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/auth/logout, POST} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"UsersController {/api/users}:"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/me, GET} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/me, PATCH} route"}
{"level":30,"time":1777815928191,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/me/password, PATCH} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/:id, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/:id, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/users/:id/restore, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"AdminController {/api/admin}:"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/stats, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/plans, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/plans/:id, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:userId/credits, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:id/detail, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:id/toggle-active, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:userId/roles/:roleId, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:userId/roles/:roleId, DELETE} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles/:id, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles/:id, DELETE} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/permissions, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/permissions, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles/:roleId/permissions/:permissionId, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/roles/:roleId/permissions/:permissionId, DELETE} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/projects, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/projects/:id, DELETE} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/render-jobs, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:id/ban, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/admin/users/:id/activate, PUT} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"HealthController {/api/health}:"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/health, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/health/ready, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/health/live, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"ProjectsController {/api/projects}:"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/render-queue, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id, GET} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id, PATCH} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id, DELETE} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/generate-script, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/approve, POST} route"}
{"level":30,"time":1777815928192,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/cancel-render, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/from-tweet, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/from-youtube, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/from-text, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/from-document, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/extract-document-topics, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/document-from-topic, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/scenes/:sceneId, PATCH} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/scenes/:sceneId/regenerate, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/media/:mediaId, DELETE} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/generate-seo-titles, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/generate-social-content, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/select-title, PATCH} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/translate, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/scenes/:sceneId/generate-image, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/projects/:id/scenes/:sceneId/upscale-image, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"XTwitterController {/api/x-twitter}:"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/x-twitter/preview, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/x-twitter/fetch, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"BillingController {/api/billing}:"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/plans, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/checkout, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/credits/balance, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/credits/history, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/subscription, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/billing/webhook, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"RenderCallbackController {/api/render-callback}:"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/render-callback/progress, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/render-callback/completed, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/render-callback/failed, POST} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"NotificationsController {/api/notifications}:"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/notifications, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/notifications/unread-count, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/notifications/read-all, PATCH} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/notifications/:id/read, PATCH} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/notifications/:id, DELETE} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RoutesResolver","msg":"DashboardController {/api/dashboard}:"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/dashboard/stats, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/dashboard/queue-status, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"RouterExplorer","msg":"Mapped {/api/dashboard/chart, GET} route"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"PrismaService","msg":"Connecting to database... URL: postgres:5432/contgen_ai_db?schema=public"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"PrismaService","msg":"✅ Database connected successfully"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"GeminiService","msg":"✅ Gemini AI initialized successfully"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"NestApplication","msg":"Nest application successfully started"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"═══════════════════════════════════════════════════════════"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"🚀 ContentGen AI API: http://localhost:3000/api"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"📚 Swagger Docs: http://localhost:3000/api/docs"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"💚 Health Check: http://localhost:3000/api/health"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"📂 Medya Dosyaları: http://localhost:3000/media/"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"🌍 Ortam: PRODUCTION"}
{"level":30,"time":1777815928193,"pid":1,"hostname":"7cc81a3344b4","context":"Bootstrap","msg":"═══════════════════════════════════════════════════════════"}
{"level":40,"time":1777815932499,"pid":1,"hostname":"7cc81a3344b4","req":{"id":1,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":45034},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815932507,"pid":1,"hostname":"7cc81a3344b4","req":{"id":1,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":45034},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":9,"msg":"request completed"}
{"level":40,"time":1777815947561,"pid":1,"hostname":"7cc81a3344b4","req":{"id":2,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":43340},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815947564,"pid":1,"hostname":"7cc81a3344b4","req":{"id":2,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":43340},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"45","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":3,"msg":"request completed"}
{"level":40,"time":1777815957201,"pid":1,"hostname":"7cc81a3344b4","req":{"id":3,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":60126},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777815957220,"pid":1,"hostname":"7cc81a3344b4","req":{"id":4,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":43280},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777815957238,"pid":1,"hostname":"7cc81a3344b4","req":{"id":5,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":60769},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815957266,"pid":1,"hostname":"7cc81a3344b4","req":{"id":3,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":60126},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""}},"responseTime":65,"msg":"request completed"}
{"level":30,"time":1777815957268,"pid":1,"hostname":"7cc81a3344b4","req":{"id":4,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":43280},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""}},"responseTime":48,"msg":"request completed"}
{"level":40,"time":1777815957274,"pid":1,"hostname":"7cc81a3344b4","req":{"id":6,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815957277,"pid":1,"hostname":"7cc81a3344b4","req":{"id":5,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":60769},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":39,"msg":"request completed"}
{"level":30,"time":1777815957284,"pid":1,"hostname":"7cc81a3344b4","req":{"id":6,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":61500},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":10,"msg":"request completed"}
{"level":40,"time":1777815957285,"pid":1,"hostname":"7cc81a3344b4","req":{"id":7,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":60769},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815957298,"pid":1,"hostname":"7cc81a3344b4","req":{"id":7,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":60769},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""}},"responseTime":14,"msg":"request completed"}
{"level":40,"time":1777815962630,"pid":1,"hostname":"7cc81a3344b4","req":{"id":8,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":60769},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777815962637,"pid":1,"hostname":"7cc81a3344b4","req":{"id":9,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":56112},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815962641,"pid":1,"hostname":"7cc81a3344b4","req":{"id":9,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":56112},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"97","x-ratelimit-reset":"30","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":5,"msg":"request completed"}
{"level":40,"time":1777815962647,"pid":1,"hostname":"7cc81a3344b4","req":{"id":10,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815962650,"pid":1,"hostname":"7cc81a3344b4","req":{"id":8,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":60769},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"55","etag":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""}},"responseTime":20,"msg":"request completed"}
{"level":30,"time":1777815962657,"pid":1,"hostname":"7cc81a3344b4","req":{"id":10,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":61500},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"55","etag":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""}},"responseTime":10,"msg":"request completed"}
{"level":40,"time":1777815962659,"pid":1,"hostname":"7cc81a3344b4","req":{"id":11,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":60769},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815962667,"pid":1,"hostname":"7cc81a3344b4","req":{"id":11,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":60769},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"55","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":9,"msg":"request completed"}
{"level":40,"time":1777815962670,"pid":1,"hostname":"7cc81a3344b4","req":{"id":12,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":60769},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815962680,"pid":1,"hostname":"7cc81a3344b4","req":{"id":12,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":60769},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"55","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":10,"msg":"request completed"}
{"level":40,"time":1777815962682,"pid":1,"hostname":"7cc81a3344b4","req":{"id":13,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815962695,"pid":1,"hostname":"7cc81a3344b4","req":{"id":13,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":61500},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"55","etag":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""}},"responseTime":13,"msg":"request completed"}
{"level":40,"time":1777815967979,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815967989,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"ProjectsController","msg":"SEO ve Sosyal Medya üretim isteği: 686d6496-2963-4527-8703-02b843e50159"}
{"level":30,"time":1777815967992,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"ProjectsService","msg":"Sosyal medya & SEO içerik üretimi başlatılıyor: 686d6496-2963-4527-8703-02b843e50159"}
{"level":30,"time":1777815967992,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"VideoAiService","msg":"Sosyal medya ve SEO içerikleri üretiliyor — Konu: \"Aşağıda dökümü (transcript) verilmiş YouTube videosundan en can alıcı 60 saniyelik bir Shorts videosu üret:\n\nالمترجم: Walaa Mohammed في مكان ما في سويسرا في العصور الوسطى، يشعر المسافر المرهق\nبالارتياح لرؤية دير أمامك. تم الترحيب به وإرشاده إلى دار ضيافة مزدحم، وخدم على الفور تخصص\nالدير: كأس طويل من البيرة. لقرون، كانت الأديرة في جميع أنحاء أوروبا الحديثة هي مصانع البيرة\nالرئيسية على نطاق واسع. ولكن هذا بالكاد هو المكان الذي بدأت\nفيه رحلة هذا المشروب. تشير البيرة إلى أي مشروب كحولي\nمصنوع من حبوب الحبوب المخمرة - البذور الصالحة للأكل\nلمجموعة معينة من الأعشاب. يعود أقدم دليل على تخمير\nالبيرة إلى 13000 عام إلى ما يعرف الآن بإسرائيل، لكن الخبراء يعتقدون أن المشروب\nتطور بشكل مستقل في جميع أنحاء العالم. في كل من هذه المناطق، تم تشكيل تكوينها من خلال الحبوب المحلية. على سبيل المثال،\nقبل 9000 عام في شرق الصين، كان الناس يشربون بيرة حلوة غائمة مصنوعة\nمن الأرز والدخن والدرنات. في منطقة الأنديز بأمريكا الجنوبية، يقترح الفخار الذي يعود\nتاريخه إلى 5000 عام إنتاج الشيشة، وهي مشروب من الذرة المخمرة. \""}
{"level":40,"time":1777815977701,"pid":1,"hostname":"7cc81a3344b4","req":{"id":15,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":55504},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815977705,"pid":1,"hostname":"7cc81a3344b4","req":{"id":15,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":55504},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"15","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":3,"msg":"request completed"}
{"level":40,"time":1777815977711,"pid":1,"hostname":"7cc81a3344b4","req":{"id":16,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":40350},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815977720,"pid":1,"hostname":"7cc81a3344b4","req":{"id":16,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":40350},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"97","x-ratelimit-reset":"40","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":9,"msg":"request completed"}
{"level":50,"time":1777815978646,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"VideoAiService","msg":"Eksik alanlar var. Gemini'den gelen RAW JSON: {\n \"seo\": {\n \"title\": \"Bier: 13.000 Jahre Geschichte Von Klöstern zur Antike\",\n \"description\": \"Entdecken Sie die faszinierende 13.000-jährige Geschichte des Bieres! Von den ersten Brauereien in Klöstern bis zu seinen antiken Wurzeln in Israel, China und den Anden. Ein überraschender Einblick in die Entwicklung dieses globalen Getränks.\",\n \"keywords\": [\n \"Biergeschichte\",\n \"Antikes Bier\",\n \"Bier Ursprung\",\n \"Brauereigeschichte\",\n \"Mittelalter Bier\"\n ],\n \"hashtags\": [\n \"#Bier\",\n \"#Biergeschichte\",\n \"#Antike\"\n ],\n \"trendingHashtags\": [\n \"#WusstestDuSchon\",\n \"#Kurzvideo\"\n ],\n \"estimatedSearchVolume\": \"Mittel bis hoch für allgemeine Begriffe wie 'Biergeschichte' und 'Bier Ursprung'. 'Antikes Bier' hat ein geringeres, aber spezifisches Volumen.\",\n \"schemaMarkup\": {\n \"@type\": \"VideoObject\",\n \"name\": \"Bier: 13.000 Jahre Geschichte Von Klöstern zur Antike\",\n \"description\": \"Entdecken Sie die faszinierende 13.000-jährige Geschichte des Bieres! Von den ersten Brauere"}
{"level":50,"time":1777815978646,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"VideoAiService","msg":"SEO/Sosyal Medya içerik üretim hatası: Eksik alanlar (seo veya socialContent yok)"}
{"level":50,"time":1777815978649,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"context":"GlobalExceptionFilter","err":{"type":"Error","message":"POST /api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content - 500 - İçerik üretimi başarısız oldu.","stack":"InternalServerErrorException: İçerik üretimi başarısız oldu.\n at VideoAiService.generateSocialAndSeoContent (/app/dist/modules/video-ai/video-ai.service.js:975:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async ProjectsService.generateSocialAndSeoContent (/app/dist/modules/projects/projects.service.js:1339:24)"},"msg":"POST /api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content - 500 - İçerik üretimi başarısız oldu."}
{"level":30,"time":1777815978650,"pid":1,"hostname":"7cc81a3344b4","req":{"id":14,"method":"POST","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159/generate-social-content","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159","generate-social-content"]},"headers":{"host":"localhost:3000","connection":"keep-alive","content-length":"0","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd"},"remoteAddress":"172.66.147.243","remotePort":61500},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","content-type":"application/json; charset=utf-8","content-length":"103","etag":"W/\"67-lEL0KjEt2TCH0FBkqp/J2sPkYTY\""}},"err":{"type":"InternalServerErrorException","message":"İçerik üretimi başarısız oldu.","stack":"InternalServerErrorException: İçerik üretimi başarısız oldu.\n at VideoAiService.generateSocialAndSeoContent (/app/dist/modules/video-ai/video-ai.service.js:975:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async ProjectsService.generateSocialAndSeoContent (/app/dist/modules/projects/projects.service.js:1339:24)","response":{"type":"Object","message":"İçerik üretimi başarısız oldu.","stack":"","error":"Internal Server Error","statusCode":500},"status":500,"options":{},"name":"InternalServerErrorException"},"responseTime":10672,"msg":"request errored"}
{"level":40,"time":1777815992736,"pid":1,"hostname":"7cc81a3344b4","req":{"id":17,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":37611},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815992745,"pid":1,"hostname":"7cc81a3344b4","req":{"id":17,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":37611},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"97","x-ratelimit-reset":"25","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":10,"msg":"request completed"}
{"level":40,"time":1777815992751,"pid":1,"hostname":"7cc81a3344b4","req":{"id":18,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":37611},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815992755,"pid":1,"hostname":"7cc81a3344b4","req":{"id":18,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":37611},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"25","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":4,"msg":"request completed"}
{"level":40,"time":1777815992767,"pid":1,"hostname":"7cc81a3344b4","req":{"id":19,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":59832},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777815992768,"pid":1,"hostname":"7cc81a3344b4","req":{"id":19,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":59832},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"60","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":1,"msg":"request completed"}
{"level":40,"time":1777816007816,"pid":1,"hostname":"7cc81a3344b4","req":{"id":20,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":34654},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816007818,"pid":1,"hostname":"7cc81a3344b4","req":{"id":20,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":34654},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"45","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":2,"msg":"request completed"}
{"level":40,"time":1777816009705,"pid":1,"hostname":"7cc81a3344b4","req":{"id":21,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":32890},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816009717,"pid":1,"hostname":"7cc81a3344b4","req":{"id":21,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":32890},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"95","x-ratelimit-reset":"8","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":13,"msg":"request completed"}
{"level":40,"time":1777816009765,"pid":1,"hostname":"7cc81a3344b4","req":{"id":22,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":32890},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777816009769,"pid":1,"hostname":"7cc81a3344b4","req":{"id":23,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":20038},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816009775,"pid":1,"hostname":"7cc81a3344b4","req":{"id":22,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":32890},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"8","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":10,"msg":"request completed"}
{"level":30,"time":1777816009778,"pid":1,"hostname":"7cc81a3344b4","req":{"id":23,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":20038},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"97","x-ratelimit-reset":"8","etag":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""}},"responseTime":9,"msg":"request completed"}
{"level":40,"time":1777816022877,"pid":1,"hostname":"7cc81a3344b4","req":{"id":24,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":51924},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816022879,"pid":1,"hostname":"7cc81a3344b4","req":{"id":24,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":51924},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"30","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":2,"msg":"request completed"}
{"level":40,"time":1777816024762,"pid":1,"hostname":"7cc81a3344b4","req":{"id":25,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":49910},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816024770,"pid":1,"hostname":"7cc81a3344b4","req":{"id":25,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":49910},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"60","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":8,"msg":"request completed"}
{"level":40,"time":1777816037958,"pid":1,"hostname":"7cc81a3344b4","req":{"id":26,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":43202},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816037960,"pid":1,"hostname":"7cc81a3344b4","req":{"id":26,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":43202},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"15","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":3,"msg":"request completed"}
{"level":40,"time":1777816039816,"pid":1,"hostname":"7cc81a3344b4","req":{"id":27,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":23259},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777816039828,"pid":1,"hostname":"7cc81a3344b4","req":{"id":28,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":33251},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816039831,"pid":1,"hostname":"7cc81a3344b4","req":{"id":27,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":23259},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"45","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":15,"msg":"request completed"}
{"level":30,"time":1777816039834,"pid":1,"hostname":"7cc81a3344b4","req":{"id":28,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":33251},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"97","x-ratelimit-reset":"60","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":6,"msg":"request completed"}
{"level":40,"time":1777816053020,"pid":1,"hostname":"7cc81a3344b4","req":{"id":29,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":40452},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816053022,"pid":1,"hostname":"7cc81a3344b4","req":{"id":29,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":40452},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"60","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":2,"msg":"request completed"}
{"level":40,"time":1777816054864,"pid":1,"hostname":"7cc81a3344b4","req":{"id":30,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":21411},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816054876,"pid":1,"hostname":"7cc81a3344b4","req":{"id":30,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":21411},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"30","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":12,"msg":"request completed"}
{"level":40,"time":1777816068055,"pid":1,"hostname":"7cc81a3344b4","req":{"id":31,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":44474},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816068056,"pid":1,"hostname":"7cc81a3344b4","req":{"id":31,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":44474},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"45","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":1,"msg":"request completed"}
{"level":40,"time":1777816069856,"pid":1,"hostname":"7cc81a3344b4","req":{"id":32,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":59802},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816069871,"pid":1,"hostname":"7cc81a3344b4","req":{"id":32,"method":"GET","url":"/api/notifications?limit=20","query":{"limit":"20"},"params":{"path":["notifications"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""},"remoteAddress":"172.66.147.243","remotePort":59802},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"98","x-ratelimit-reset":"30","etag":"W/\"9e-+B0Qyyn9/c3BPgdU5km0/p8euYo\""}},"responseTime":15,"msg":"request completed"}
{"level":40,"time":1777816069888,"pid":1,"hostname":"7cc81a3344b4","req":{"id":33,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":59802},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816069894,"pid":1,"hostname":"7cc81a3344b4","req":{"id":33,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":59802},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"15","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":6,"msg":"request completed"}
{"level":40,"time":1777816083111,"pid":1,"hostname":"7cc81a3344b4","req":{"id":34,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":51272},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816083115,"pid":1,"hostname":"7cc81a3344b4","req":{"id":34,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":51272},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"30","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":4,"msg":"request completed"}
{"level":40,"time":1777816083477,"pid":1,"hostname":"7cc81a3344b4","req":{"id":35,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":23554},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":40,"time":1777816083488,"pid":1,"hostname":"7cc81a3344b4","req":{"id":36,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":17949},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816083491,"pid":1,"hostname":"7cc81a3344b4","req":{"id":35,"method":"GET","url":"/api/users/me","query":{},"params":{"path":["users","me"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""},"remoteAddress":"172.66.147.243","remotePort":23554},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"14f-L/SIvI60CNQEG2eghHMt0B6Kt1c\""}},"responseTime":14,"msg":"request completed"}
{"level":30,"time":1777816083493,"pid":1,"hostname":"7cc81a3344b4","req":{"id":36,"method":"GET","url":"/api/billing/credits/balance","query":{},"params":{"path":["billing","credits","balance"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""},"remoteAddress":"172.66.147.243","remotePort":17949},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"d5-0hoMgaPijvQYaATiaDlsLB+veIk\""}},"responseTime":5,"msg":"request completed"}
{"level":40,"time":1777816083501,"pid":1,"hostname":"7cc81a3344b4","req":{"id":37,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":17949},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816083506,"pid":1,"hostname":"7cc81a3344b4","req":{"id":37,"method":"GET","url":"/api/notifications/unread-count","query":{},"params":{"path":["notifications","unread-count"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""},"remoteAddress":"172.66.147.243","remotePort":17949},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"95","x-ratelimit-reset":"2","etag":"W/\"68-wEwkNxOfBuB9DKgc5LcelqmpXac\""}},"responseTime":5,"msg":"request completed"}
{"level":40,"time":1777816083516,"pid":1,"hostname":"7cc81a3344b4","req":{"id":38,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":17949},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816083522,"pid":1,"hostname":"7cc81a3344b4","req":{"id":38,"method":"GET","url":"/api/projects/686d6496-2963-4527-8703-02b843e50159","query":{},"params":{"path":["projects","686d6496-2963-4527-8703-02b843e50159"]},"headers":{"host":"localhost:3000","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NDA1YjE4Mi0zMTQ1LTQwOWUtOWIxYS0zMDBmZjVhOGY3NDYiLCJlbWFpbCI6ImFkbWluQGNvbnRlbnRnZW4uYWkiLCJyb2xlcyI6WyJhZG1pbiIsInVzZXIiXSwicGVybWlzc2lvbnMiOlsicHJvamVjdHM6Y3JlYXRlIiwicHJvamVjdHM6cmVhZCIsInByb2plY3RzOnVwZGF0ZSIsInByb2plY3RzOmRlbGV0ZSIsInRlbXBsYXRlczpyZWFkIiwidGVtcGxhdGVzOmNyZWF0ZSIsInRlbXBsYXRlczptYW5hZ2UiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsImFkbWluOmFjY2VzcyIsImFkbWluOnVzZXJzIiwiYWRtaW46c3lzdGVtIiwibm90aWZpY2F0aW9uczpyZWFkIiwibm90aWZpY2F0aW9uczptYW5hZ2UiLCJwcm9qZWN0czpjcmVhdGUiLCJwcm9qZWN0czpyZWFkIiwicHJvamVjdHM6dXBkYXRlIiwicHJvamVjdHM6ZGVsZXRlIiwidGVtcGxhdGVzOnJlYWQiLCJiaWxsaW5nOnJlYWQiLCJiaWxsaW5nOm1hbmFnZSIsIm5vdGlmaWNhdGlvbnM6cmVhZCJdLCJpYXQiOjE3Nzc1ODkyOTksImV4cCI6MTc3ODE5NDA5OX0.MlHlNSrKNm7n7AobvvqUmUdxbW2wQ9otSYA1Y4t45QI","accept-language":"tr","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Brave\";v=\"147\", \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"147\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36","sec-ch-ua-mobile":"?0","sec-gpc":"1","origin":"http://localhost:3001","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3001/","accept-encoding":"gzip, deflate, br, zstd","if-none-match":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""},"remoteAddress":"172.66.147.243","remotePort":17949},"res":{"statusCode":304,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","access-control-allow-origin":"http://localhost:3001","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"99","x-ratelimit-reset":"60","etag":"W/\"7cc6-TgiZx+Q9SwW+pSCBe3bnx3DQjr8\""}},"responseTime":6,"msg":"request completed"}
{"level":40,"time":1777816098172,"pid":1,"hostname":"7cc81a3344b4","req":{"id":39,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":38574},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816098174,"pid":1,"hostname":"7cc81a3344b4","req":{"id":39,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":38574},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"15","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":2,"msg":"request completed"}
{"level":40,"time":1777816113228,"pid":1,"hostname":"7cc81a3344b4","req":{"id":40,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":44076},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816113229,"pid":1,"hostname":"7cc81a3344b4","req":{"id":40,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":44076},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"60","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":1,"msg":"request completed"}
{"level":40,"time":1777816128291,"pid":1,"hostname":"7cc81a3344b4","req":{"id":41,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":60192},"context":"I18nService","msg":"HeaderResolver does not support RFC4647 Accept-Language header. Please use AcceptLanguageResolver instead."}
{"level":30,"time":1777816128294,"pid":1,"hostname":"7cc81a3344b4","req":{"id":41,"method":"GET","url":"/api/health","query":{},"params":{"path":["health"]},"headers":{"host":"127.0.0.1:3000","user-agent":"Wget","accept":"*/*","connection":"close"},"remoteAddress":"127.0.0.1","remotePort":60192},"res":{"statusCode":200,"headers":{"cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"cross-origin","origin-agent-cluster":"?1","referrer-policy":"no-referrer","strict-transport-security":"max-age=31536000; includeSubDomains","x-content-type-options":"nosniff","x-dns-prefetch-control":"off","x-download-options":"noopen","x-frame-options":"SAMEORIGIN","x-permitted-cross-domain-policies":"none","x-xss-protection":"0","vary":"Origin","access-control-allow-credentials":"true","x-ratelimit-limit":"100","x-ratelimit-remaining":"96","x-ratelimit-reset":"45","cache-control":"no-cache, no-store, must-revalidate","content-type":"application/json; charset=utf-8","content-length":"125","etag":"W/\"7d-+NqX3LD+/EIYtKNA6BMzFGpz21M\""}},"responseTime":3,"msg":"request completed"}
@@ -35,6 +35,8 @@ public class ApiSettings
public string TtsVoiceId { get; set; } = "pNInz6obpgDQGcFmaJgB";
public string OpenAiApiKey { get; set; } = string.Empty;
public string OpenAiTtsVoiceId { get; set; } = "alloy";
public string MinimaxApiKey { get; set; } = string.Empty;
public string MinimaxTtsVoiceId { get; set; } = "male-qn-qingse";
public string SunoBaseUrl { get; set; } = string.Empty;
public string SunoApiKey { get; set; } = string.Empty;
public string CoreApiBaseUrl { get; set; } = "http://localhost:3000/api";
@@ -29,6 +29,9 @@ public class VideoGenerationJob
[JsonPropertyName("videoStyle")]
public string VideoStyle { get; set; } = "CINEMATIC";
[JsonPropertyName("visualEffect")]
public string VisualEffect { get; set; } = "kenburns";
[JsonPropertyName("targetDuration")]
public int TargetDuration { get; set; } = 60;
+3
View File
@@ -70,6 +70,9 @@ try
builder.Services.AddHttpClient<OpenAiTtsService>("OpenAITTS")
.AddPolicyHandler(combinedPolicy);
builder.Services.AddHttpClient<MinimaxTtsService>("MinimaxTTS")
.AddPolicyHandler(combinedPolicy);
builder.Services.AddHttpClient<SunoMusicService>("Suno")
.AddPolicyHandler(combinedPolicy);
+132
View File
@@ -0,0 +1,132 @@
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SaasMediaWorker.Configuration;
using SaasMediaWorker.Models;
namespace SaasMediaWorker.Services;
/// <summary>
/// Minimax TTS API Client — Metin → Ses dönüşümü.
/// </summary>
public class MinimaxTtsService
{
private readonly HttpClient _httpClient;
private readonly ILogger<MinimaxTtsService> _logger;
private readonly ApiSettings _settings;
public MinimaxTtsService(
HttpClient httpClient,
ILogger<MinimaxTtsService> logger,
IOptions<ApiSettings> settings)
{
_httpClient = httpClient;
_logger = logger;
_settings = settings.Value;
_httpClient.BaseAddress = new Uri("https://api.minimax.chat/v1/");
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _settings.MinimaxApiKey);
_httpClient.Timeout = TimeSpan.FromMinutes(2);
}
/// <summary>
/// Bir sahnenin narration metnini sese çevirir ve dosyaya kaydeder.
/// </summary>
public async Task<GeneratedMediaFile> GenerateNarrationAsync(
ScenePayload scene,
string outputDirectory,
string voiceStyle,
CancellationToken ct)
{
_logger.LogInformation(
"🎙️ Minimax TTS üretimi — Sahne {Order}: \"{Text}\"",
scene.Order,
scene.NarrationText[..Math.Min(60, scene.NarrationText.Length)]);
// Varsayılan voiceStyle kullan veya fallback
var voiceId = string.IsNullOrWhiteSpace(voiceStyle) ? _settings.MinimaxTtsVoiceId : voiceStyle;
var requestBody = new
{
model = "speech-01-turbo",
text = scene.NarrationText,
voice_setting = new
{
voice_id = voiceId,
speed = 1.0,
vol = 1.0,
pitch = 0
},
audio_setting = new
{
sample_rate = 32000,
bitrate = 128000,
format = "mp3",
channel = 1
}
};
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json");
var response = await _httpClient.PostAsync("t2a_v2", content, ct);
response.EnsureSuccessStatusCode();
// Minimax T2A V2 returns JSON with data.audio containing hex string
var responseString = await response.Content.ReadAsStringAsync(ct);
var jsonResponse = JsonSerializer.Deserialize<JsonElement>(responseString);
if (jsonResponse.TryGetProperty("data", out var dataElement) && dataElement.TryGetProperty("audio", out var audioHex))
{
var hexString = audioHex.GetString() ?? "";
byte[] audioBytes = ConvertHexStringToByteArray(hexString);
var outputPath = Path.Combine(outputDirectory, $"scene_{scene.Order:D2}_narration.mp3");
await File.WriteAllBytesAsync(outputPath, audioBytes, ct);
var fileInfo = new FileInfo(outputPath);
_logger.LogInformation(
"Minimax TTS tamamlandı — Sahne {Order}: {Size} bytes",
scene.Order, fileInfo.Length);
return new GeneratedMediaFile
{
SceneId = scene.Id,
SceneOrder = scene.Order,
Type = MediaFileType.AudioNarration,
LocalPath = outputPath,
FileSizeBytes = fileInfo.Length,
DurationSeconds = scene.Duration,
MimeType = "audio/mpeg",
AiProvider = "minimax"
};
}
else
{
throw new Exception("Minimax API response invalid: " + responseString);
}
}
private static byte[] ConvertHexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
{
throw new ArgumentException("Hex string must have an even length.");
}
byte[] data = new byte[hexString.Length / 2];
for (int index = 0; index < data.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
data[index] = byte.Parse(byteValue, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture);
}
return data;
}
}
+2
View File
@@ -21,6 +21,7 @@ public class RemotionService
List<GeneratedMediaFile> generatedMedia,
string? musicPath,
int targetDurationSeconds,
string visualEffect,
CancellationToken ct)
{
_logger.LogInformation("🎬 Remotion render başlatılıyor — Project: {Id}", projectId);
@@ -32,6 +33,7 @@ public class RemotionService
var props = new
{
musicPath = musicPath,
visualEffect = visualEffect,
scenes = scenes.Select(s => new
{
imagePath = s.ImagePath,
+47 -5
View File
@@ -24,6 +24,7 @@ public class VideoRenderPipeline
private readonly HiggsFieldService _higgsField;
private readonly TtsService _tts;
private readonly OpenAiTtsService _openAiTts;
private readonly MinimaxTtsService _minimaxTts;
private readonly SunoMusicService _sunoMusic;
private readonly AudioCraftService _audioCraft;
private readonly RemotionService _remotion;
@@ -36,6 +37,7 @@ public class VideoRenderPipeline
HiggsFieldService higgsField,
TtsService tts,
OpenAiTtsService openAiTts,
MinimaxTtsService minimaxTts,
SunoMusicService sunoMusic,
AudioCraftService audioCraft,
RemotionService remotion,
@@ -47,6 +49,7 @@ public class VideoRenderPipeline
_higgsField = higgsField;
_tts = tts;
_openAiTts = openAiTts;
_minimaxTts = minimaxTts;
_sunoMusic = sunoMusic;
_audioCraft = audioCraft;
_remotion = remotion;
@@ -176,13 +179,48 @@ public class VideoRenderPipeline
await progressCallback(70, "AMBIENT_GENERATION");
// ═══════════════════════════════════════
// ADIM 5: REMOTION — Video render (Ken Burns + Audio Merge + Subtitles)
// ADIM 5: REMOTION — Segmented Video render + FFmpeg Merge
// ═══════════════════════════════════════
_logger.LogInformation("🎬 Adım 5/6: Remotion render — Ken Burns + audio merge + subtitle");
await progressCallback(75, "MEDIA_MERGE");
_logger.LogInformation("🎬 Adım 5/6: Remotion Segmented Render — Ken Burns + audio merge + subtitle");
await progressCallback(70, "MEDIA_MERGE");
var finalLocalPath = await _remotion.RenderVideoAsync(
job.ProjectId, projectDir, scenes, allMediaFiles, musicFile?.LocalPath, job.TargetDuration, ct);
int chunkSize = 20; // 20 scenes per chunk to prevent OOM
var chunkPaths = new List<string>();
var chunkIndex = 0;
for (int i = 0; i < scenes.Count; i += chunkSize)
{
var chunkScenes = scenes.Skip(i).Take(chunkSize).ToList();
chunkIndex++;
_logger.LogInformation("Render Chunk {ChunkIndex} (Scenes {Start} to {End})",
chunkIndex, i + 1, i + chunkScenes.Count);
// Pass null for musicPath so Remotion doesn't add music to each chunk
var chunkPath = await _remotion.RenderVideoAsync(
$"{job.ProjectId}_chunk_{chunkIndex}",
projectDir,
chunkScenes,
allMediaFiles,
null, // No music per chunk
0,
job.VisualEffect,
ct);
chunkPaths.Add(chunkPath);
var progress = 70 + (int)(20.0 * (i + chunkScenes.Count) / scenes.Count);
await progressCallback(progress, "MEDIA_MERGE");
}
_logger.LogInformation("🎬 Chunklar birleştiriliyor ve müzik ekleniyor (FFmpeg)");
var finalLocalPath = await _ffmpeg.ConcatenateAndFinalize(
chunkPaths,
musicFile?.LocalPath,
projectDir,
job.ProjectId,
job.TargetDuration,
ct);
allMediaFiles.Add(new GeneratedMediaFile
{
@@ -234,6 +272,10 @@ public class VideoRenderPipeline
{
result = await _openAiTts.GenerateNarrationAsync(scene, outputDir, voiceStyle, ct);
}
else if (!string.IsNullOrEmpty(scene.TtsProvider) && scene.TtsProvider.Equals("minimax", StringComparison.OrdinalIgnoreCase))
{
result = await _minimaxTts.GenerateNarrationAsync(scene, outputDir, voiceStyle, ct);
}
else
{
// Default: ElevenLabs
+76 -9
View File
@@ -20,9 +20,10 @@ export type SceneProp = {
export type MainVideoProps = {
scenes: SceneProp[];
musicPath?: string;
visualEffect?: string;
};
export const MainVideo: React.FC<MainVideoProps> = ({ scenes, musicPath }) => {
export const MainVideo: React.FC<MainVideoProps> = ({ scenes, musicPath, visualEffect }) => {
const { fps } = useVideoConfig();
// Helper: map local absolute path to standard file:// URL so Remotion Chromium can load it
@@ -50,7 +51,7 @@ export const MainVideo: React.FC<MainVideoProps> = ({ scenes, musicPath }) => {
from={startFrame}
durationInFrames={scene.durationInFrames}
>
<SceneRenderer scene={scene} index={index} />
<SceneRenderer scene={scene} index={index} visualEffect={visualEffect} />
</Sequence>
);
})}
@@ -58,18 +59,40 @@ export const MainVideo: React.FC<MainVideoProps> = ({ scenes, musicPath }) => {
);
};
const SceneRenderer: React.FC<{ scene: SceneProp; index: number }> = ({ scene, index }) => {
const SceneRenderer: React.FC<{ scene: SceneProp; index: number; visualEffect?: string }> = ({ scene, index, visualEffect }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Ken Burns Effect (Zoom In / Pan)
// Even scenes zoom in, odd scenes zoom out slightly for variation
const scale = interpolate(
frame,
[0, scene.durationInFrames],
index % 2 === 0 ? [1, 1.1] : [1.1, 1],
{ extrapolateRight: "clamp" }
);
// Base scale for kenburns and general movement
let scale = 1;
let filter = "";
let mixBlendMode: any = "normal";
// If no effect or kenburns, apply the default Ken Burns
if (!visualEffect || visualEffect === "kenburns" || visualEffect === "filmgrain" || visualEffect === "lightleaks" || visualEffect === "sparkles") {
scale = interpolate(
frame,
[0, scene.durationInFrames],
index % 2 === 0 ? [1, 1.1] : [1.1, 1],
{ extrapolateRight: "clamp" }
);
}
if (visualEffect === "glitch") {
// Quick jitter
const jitter = Math.sin(frame * 0.5) * 5;
const jitterScale = index % 2 === 0 ? 1.05 : 1.0;
scale = jitterScale + Math.abs(jitter) * 0.01;
if (frame % 15 < 3) {
filter = `hue-rotate(${jitter * 10}deg) contrast(150%)`;
}
}
// Common effect overlays
const noiseOpacity = interpolate(frame % 10, [0, 5, 10], [0.1, 0.15, 0.1]);
const lightLeakOpacity = interpolate(Math.sin(frame * 0.05), [-1, 1], [0.1, 0.4]);
const makeFileUrl = (path?: string) => {
if (!path) return undefined;
@@ -84,6 +107,8 @@ const SceneRenderer: React.FC<{ scene: SceneProp; index: number }> = ({ scene, i
style={{
transform: `scale(${scale})`,
transformOrigin: "center center",
filter: filter ? filter : undefined,
mixBlendMode: mixBlendMode
}}
>
{scene.imagePath ? (
@@ -98,6 +123,48 @@ const SceneRenderer: React.FC<{ scene: SceneProp; index: number }> = ({ scene, i
</div>
</AbsoluteFill>
)}
{visualEffect === "filmgrain" && (
<AbsoluteFill style={{
opacity: noiseOpacity,
backgroundColor: "white",
mixBlendMode: "overlay",
filter: "url(#noiseFilter)"
}}>
<svg>
<filter id="noiseFilter">
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" stitchTiles="stitch"/>
</filter>
</svg>
</AbsoluteFill>
)}
{visualEffect === "lightleaks" && (
<AbsoluteFill style={{
background: "linear-gradient(45deg, rgba(255,100,0,0) 0%, rgba(255,50,0,0.5) 50%, rgba(255,0,0,0) 100%)",
opacity: lightLeakOpacity,
mixBlendMode: "screen",
transform: `scale(1.5) rotate(${frame * 0.5}deg)`
}} />
)}
{visualEffect === "sparkles" && (
<AbsoluteFill style={{
background: "radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 10%)",
backgroundSize: "50px 50px",
backgroundPosition: `${frame}px ${frame * 2}px`,
opacity: interpolate(Math.sin(frame * 0.1), [-1, 1], [0.3, 0.8]),
mixBlendMode: "screen"
}} />
)}
{visualEffect === "glitch" && frame % 20 < 4 && (
<AbsoluteFill style={{
backgroundColor: "rgba(255, 0, 0, 0.2)",
mixBlendMode: "color-burn",
transform: `translateX(${Math.random() * 20 - 10}px)`
}} />
)}
</AbsoluteFill>
{/* Audio Tracks */}
+2
View File
@@ -63,6 +63,8 @@
"sharp": "^0.34.5",
"socket.io": "^4.8.3",
"stripe": "^21.0.1",
"youtube-transcript": "^1.3.1",
"youtubei.js": "^17.0.1",
"zod": "^4.3.5"
},
"devDependencies": {
+31
View File
@@ -131,6 +131,12 @@ importers:
stripe:
specifier: ^21.0.1
version: 21.0.1(@types/node@22.19.15)
youtube-transcript:
specifier: ^1.3.1
version: 1.3.1
youtubei.js:
specifier: ^17.0.1
version: 17.0.1
zod:
specifier: ^4.3.5
version: 4.3.6
@@ -586,6 +592,9 @@ packages:
'@borewit/text-codec@0.2.2':
resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==}
'@bufbuild/protobuf@2.12.0':
resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==}
'@cacheable/utils@2.4.1':
resolution: {integrity: sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==}
@@ -3470,6 +3479,10 @@ packages:
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
meriyah@6.1.4:
resolution: {integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==}
engines: {node: '>=18.0.0'}
methods@1.1.2:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
@@ -4487,6 +4500,13 @@ packages:
resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==}
engines: {node: '>=18'}
youtube-transcript@1.3.1:
resolution: {integrity: sha512-NDCjwad113TGybbYF51y9Z4tcwzBHUZWQdF9veULNca18L+FdDbHHtTHIr69WVa3bB90l67S8kN0HtL2JO9fhg==}
engines: {node: '>=18.0.0'}
youtubei.js@17.0.1:
resolution: {integrity: sha512-1lO4b8UqMDzE0oh2qEGzbBOd4UYRdxn/4PdpRM7BGTHxM6ddsEsKZTu90jp8V9FHVgC2h1UirQyqoqLiKwl+Zg==}
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
@@ -5181,6 +5201,8 @@ snapshots:
'@borewit/text-codec@0.2.2': {}
'@bufbuild/protobuf@2.12.0': {}
'@cacheable/utils@2.4.1':
dependencies:
hashery: 1.5.1
@@ -8468,6 +8490,8 @@ snapshots:
merge-stream@2.0.0: {}
meriyah@6.1.4: {}
methods@1.1.2: {}
micromatch@4.0.8:
@@ -9526,4 +9550,11 @@ snapshots:
yoctocolors-cjs@2.1.3: {}
youtube-transcript@1.3.1: {}
youtubei.js@17.0.1:
dependencies:
'@bufbuild/protobuf': 2.12.0
meriyah: 6.1.4
zod@4.3.6: {}
+55 -1
View File
@@ -33,6 +33,8 @@ model User {
templateUsages TemplateUsage[]
notifications Notification[]
preferences UserPreference?
youtubeAnalyses YoutubeAnalysis[]
youtubeSeoAnalyses YoutubeSeoAnalysis[]
// Multi-tenancy (optional)
tenantId String?
@@ -247,7 +249,7 @@ model Project {
id String @id @default(uuid())
title String @db.VarChar(200)
description String? @db.VarChar(1000)
prompt String @db.VarChar(2000)
prompt String @db.Text
// AI Generated Script
scriptJson Json? // Gemini API raw JSON output
@@ -658,3 +660,55 @@ model Notification {
@@index([isRead])
@@index([createdAt])
}
// ============================================
// YouTube Analysis History
// ============================================
model YoutubeAnalysis {
id String @id @default(uuid())
videoUrl String @db.VarChar(500)
videoId String @db.VarChar(100)
title String? @db.VarChar(500)
thumbnail String? @db.VarChar(500)
viewCount String? @db.VarChar(50)
likeCount String? @db.VarChar(50)
commentCount Int?
analysisData Json // Bütün Gemini analizi burada duracak
// Relations
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// Timestamps
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@index([videoId])
}
// ============================================
// YouTube SEO Analysis History
// ============================================
model YoutubeSeoAnalysis {
id String @id @default(uuid())
videoUrl String @db.VarChar(500)
videoId String @db.VarChar(100)
title String? @db.VarChar(500)
thumbnail String? @db.VarChar(500)
seoScore Int @default(0)
analysisData Json // Bütün Gemini analizi (Başlık, Açıklama, Keywords, Shorts fikirleri) burada duracak
// Relations
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// Timestamps
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@index([videoId])
}
View File
+2
View File
@@ -53,6 +53,7 @@ import { RenderCallbackModule } from './modules/render-callback/render-callback.
import { DashboardModule } from './modules/dashboard/dashboard.module';
import { NotificationsModule } from './modules/notifications/notifications.module';
import { ExtractorModule } from './modules/extractor/extractor.module';
import { YoutubeToolsModule } from './modules/youtube-tools/youtube-tools.module';
// Guards
import {
@@ -202,6 +203,7 @@ import {
DashboardModule,
NotificationsModule,
ExtractorModule,
YoutubeToolsModule,
],
providers: [
// Global Exception Filter
@@ -2,6 +2,7 @@ import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import axios from 'axios';
import * as fs from 'fs';
import FormData from 'form-data';
import { YoutubeTranscript } from 'youtube-transcript';
@Injectable()
export class ExtractorService {
@@ -13,6 +14,23 @@ export class ExtractorService {
async extractFromUrl(url: string): Promise<string> {
this.logger.log(`URL'den içerik çekiliyor: ${url}`);
// Özel Durum: YouTube Linkleri için transkript çekmeyi dene
if (url.includes('youtube.com') || url.includes('youtu.be')) {
try {
this.logger.log(`YouTube URL algılandı, transkript çekiliyor...`);
const transcript = await YoutubeTranscript.fetchTranscript(url);
const textContent = transcript.map(t => t.text).join(' ');
if (textContent && textContent.trim().length > 0) {
this.logger.log(`YouTube transkripti başarıyla çekildi. (${textContent.length} karakter)`);
return textContent;
}
} catch (err: any) {
this.logger.warn(`YouTube transkripti çekilemedi: ${err.message}. Standart extractor'a düşülüyor...`);
}
}
try {
const response = await axios.post(
`${this.extractorUrl}/extract/url`,
+59 -54
View File
@@ -257,6 +257,7 @@ IMPORTANT: Only output valid JSON, no markdown code blocks or other text.`;
prompt: string,
aspectRatio: '16:9' | '9:16' | '1:1' = '16:9',
isIllustration: boolean = false,
forceImagen: boolean = false,
): Promise<{ buffer: Buffer; mimeType: string } | null> {
if (!this.isAvailable()) {
throw new Error('Gemini AI is not available. Check your configuration.');
@@ -287,73 +288,77 @@ IMPORTANT: Only output valid JSON, no markdown code blocks or other text.`;
: `SUBJECT: ${prompt}\n\nINSTRUCTIONS: Generate a high-quality photorealistic cinematic image of the EXACT SUBJECT described above. Use professional lighting and make it highly detailed. Aspect ratio: ${aspectRatio} ${orientation}. DO NOT deviate from the SUBJECT.`;
// ── Katman 1: gemini-2.5-flash-image (Nano Banana) — 2 deneme ──
for (let attempt = 1; attempt <= 2; attempt++) {
try {
this.logger.log(`🔄 Katman 1 (deneme ${attempt}/2): ${primaryModel}`);
const result = await this.tryGenerateContentImage(
primaryModel,
enhancedPrompt,
);
if (result && result.buffer.length > 0) {
this.logger.log(
`✅ Görsel üretildi (${primaryModel}): ${(result.buffer.length / 1024).toFixed(1)} KB`,
if (!forceImagen) {
for (let attempt = 1; attempt <= 2; attempt++) {
try {
this.logger.log(`🔄 Katman 1 (deneme ${attempt}/2): ${primaryModel}`);
const result = await this.tryGenerateContentImage(
primaryModel,
enhancedPrompt,
);
return { buffer: result.buffer, mimeType: result.mimeType };
}
if (result && result.buffer.length > 0) {
this.logger.log(
`✅ Görsel üretildi (${primaryModel}): ${(result.buffer.length / 1024).toFixed(1)} KB`,
);
return { buffer: result.buffer, mimeType: result.mimeType };
}
const reason = result?.errorReason || 'null response';
this.logger.warn(
`⚠️ ${primaryModel} deneme ${attempt}: görsel döndürmedi (${reason})`,
);
if (
['IMAGE_OTHER', 'SAFETY', 'PROHIBITED_CONTENT'].includes(reason)
) {
const reason = result?.errorReason || 'null response';
this.logger.warn(
`🚫 Güvenlik/Politika filtresi tetiklendi (${reason}). Denemeler iptal ediliyor.`,
`⚠️ ${primaryModel} deneme ${attempt}: görsel döndürmedi (${reason})`,
);
break; // Fail fast for safety blocks
}
if (attempt < 2) await this.sleep(2000);
} catch (err1: any) {
this.logger.warn(
`⚠️ ${primaryModel} deneme ${attempt} hata: ${err1.message?.substring(0, 200)}`,
);
if (attempt < 2) await this.sleep(2000);
if (
['IMAGE_OTHER', 'SAFETY', 'PROHIBITED_CONTENT'].includes(reason)
) {
this.logger.warn(
`🚫 Güvenlik/Politika filtresi tetiklendi (${reason}). Denemeler iptal ediliyor.`,
);
break; // Fail fast for safety blocks
}
if (attempt < 2) await this.sleep(2000);
} catch (err1: any) {
this.logger.warn(
`⚠️ ${primaryModel} deneme ${attempt} hata: ${err1.message?.substring(0, 200)}`,
);
if (attempt < 2) await this.sleep(2000);
}
}
}
// ── Katman 2: gemini-3.1-flash-image-preview (Nano Banana 2) ──
try {
this.logger.log(`🔄 Katman 2: ${fallbackModel}`);
const result = await this.tryGenerateContentImage(
fallbackModel,
enhancedPrompt,
);
if (result && result.buffer.length > 0) {
this.logger.log(
`✅ Görsel üretildi (${fallbackModel}): ${(result.buffer.length / 1024).toFixed(1)} KB`,
if (!forceImagen) {
try {
this.logger.log(`🔄 Katman 2: ${fallbackModel}`);
const result = await this.tryGenerateContentImage(
fallbackModel,
enhancedPrompt,
);
return { buffer: result.buffer, mimeType: result.mimeType };
}
this.logger.warn(
`⚠️ ${fallbackModel}: görsel döndürmedi (${result?.errorReason || 'null response'})`,
);
if (
['IMAGE_OTHER', 'SAFETY', 'PROHIBITED_CONTENT'].includes(
result?.errorReason || '',
)
) {
if (result && result.buffer.length > 0) {
this.logger.log(
`✅ Görsel üretildi (${fallbackModel}): ${(result.buffer.length / 1024).toFixed(1)} KB`,
);
return { buffer: result.buffer, mimeType: result.mimeType };
}
this.logger.warn(
`🚫 Katman 2 Güvenlik/Politika filtresi tetiklendi. Katman 3'e geçiliyor.`,
`⚠️ ${fallbackModel}: görsel döndürmedi (${result?.errorReason || 'null response'})`,
);
if (
['IMAGE_OTHER', 'SAFETY', 'PROHIBITED_CONTENT'].includes(
result?.errorReason || '',
)
) {
this.logger.warn(
`🚫 Katman 2 Güvenlik/Politika filtresi tetiklendi. Katman 3'e geçiliyor.`,
);
}
} catch (err2: any) {
this.logger.warn(
`⚠️ ${fallbackModel} hata: ${err2.message?.substring(0, 200)}`,
);
}
} catch (err2: any) {
this.logger.warn(
`⚠️ ${fallbackModel} hata: ${err2.message?.substring(0, 200)}`,
);
}
// ── Katman 3: Imagen 4 Fast (generateImages API) ──
+7 -7
View File
@@ -90,7 +90,7 @@ export class CreateProjectDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
@ApiPropertyOptional({
@@ -159,7 +159,7 @@ export class UpdateProjectDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
@@ -229,7 +229,7 @@ export class CreateFromTweetDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
@@ -294,7 +294,7 @@ export class CreateFromYoutubeDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
@@ -347,7 +347,7 @@ export class CreateFromDocumentDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
@@ -406,7 +406,7 @@ export class CreateFromExtractedTextDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
@@ -471,6 +471,6 @@ export class CreateFromTextDto {
@IsInt()
@IsOptional()
@Min(15)
@Max(180)
@Max(900)
targetDuration?: number;
}
+21 -1
View File
@@ -156,11 +156,12 @@ export class ProjectsController {
@ApiResponse({ status: 202, description: 'Video üretimi kuyruğa eklendi' })
async approveAndStartGeneration(
@Param('id', ParseUUIDPipe) id: string,
@Body() body: { ttsProvider?: string; visualEffect?: string },
@Req() req: any,
) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Proje onaylanıyor ve kuyruğa gönderiliyor: ${id}`);
return this.projectsService.approveAndQueueGeneration(userId, id);
return this.projectsService.approveAndQueueGeneration(userId, id, body?.ttsProvider, body?.visualEffect);
}
/**
@@ -373,6 +374,25 @@ export class ProjectsController {
return this.projectsService.generateSeoTitles(userId, id);
}
/**
* Proje için kapsamlı SEO ve Sosyal Medya içeriklerini yeniden üretir (Gemini AI).
*/
@Post(':id/generate-social-content')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'AI ile SEO ve Sosyal Medya içeriklerini üret' })
@ApiResponse({
status: 200,
description: 'İçerikler başarıyla üretildi',
})
async generateSocialContent(
@Param('id', ParseUUIDPipe) id: string,
@Req() req: any,
) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`SEO ve Sosyal Medya üretim isteği: ${id}`);
return this.projectsService.generateSocialAndSeoContent(userId, id);
}
/**
* Alternatif SEO başlıklarından birini seçerek projenin ana başlığını günceller.
*/
+63 -3
View File
@@ -392,7 +392,7 @@ export class ProjectsService {
}
}
async approveAndQueueGeneration(userId: string, projectId: string) {
async approveAndQueueGeneration(userId: string, projectId: string, ttsProvider?: string, visualEffect?: string) {
const project = await this.findOne(userId, projectId);
if (!project.scriptJson) {
@@ -430,6 +430,7 @@ export class ProjectsService {
aspectRatio: project.aspectRatio,
videoStyle: project.videoStyle,
targetDuration: project.targetDuration,
visualEffect: visualEffect || 'kenburns',
scenes: project.scenes.map((s) => {
const thumbnail = s.mediaAssets?.find((m) => m.type === 'THUMBNAIL');
const imagePath =
@@ -445,7 +446,7 @@ export class ProjectsService {
duration: s.duration,
transitionType: s.transitionType,
imagePath,
ttsProvider: 'openai', // TODO: Make configurable from frontend or project settings
ttsProvider: ttsProvider || 'openai',
};
}),
});
@@ -814,7 +815,7 @@ export class ProjectsService {
targetDurationSeconds: project.targetDuration,
language: project.language,
videoStyle: project.videoStyle,
cinematicReference: undefined,
cinematicReference: dto.cinematicReference,
seoKeywords: [],
referenceUrl: dto.youtubeUrl,
});
@@ -1758,6 +1759,65 @@ ${JSON.stringify(
};
}
/**
* Projenin mevcut verilerinden yola çıkarak eksiksiz SEO ve Sosyal Medya içeriklerini yeniden üretir.
*/
async generateSocialAndSeoContent(userId: string, projectId: string) {
const project = await this.db.project.findFirst({
where: { id: projectId, userId, deletedAt: null },
});
if (!project) {
throw new NotFoundException(`Proje bulunamadı: ${projectId}`);
}
this.logger.log(`Sosyal medya & SEO içerik üretimi başlatılıyor: ${projectId}`);
const scriptJson = (project.scriptJson as Record<string, any>) || {};
let videoContentSummary = project.title;
if (scriptJson.scenes && Array.isArray(scriptJson.scenes)) {
videoContentSummary = scriptJson.scenes.map((s: any) => s.narration).join(' ');
} else if (project.prompt) {
videoContentSummary = project.prompt.substring(0, 1000);
}
const result = await this.videoAiService.generateSocialAndSeoContent(
videoContentSummary,
project.title,
project.language,
project.seoKeywords || [],
);
const updated = await this.db.project.update({
where: { id: projectId },
data: {
seoTitle: result.seo?.title || project.seoTitle,
seoDescription: result.seo?.description || project.seoDescription,
seoKeywords: result.seo?.keywords || project.seoKeywords,
socialContent: result.socialContent as object,
scriptJson: {
...scriptJson,
seo: {
...(scriptJson.seo || {}),
...result.seo,
},
socialContent: result.socialContent,
},
},
});
this.logger.log(`✅ Sosyal medya ve SEO içerikleri başarıyla güncellendi: ${projectId}`);
return {
seoTitle: updated.seoTitle,
seoDescription: updated.seoDescription,
seoKeywords: updated.seoKeywords,
socialContent: updated.socialContent,
scriptJson: updated.scriptJson,
};
}
/**
* Alternatif SEO başlıklarından birini seçerek projenin ana başlığını günceller.
* Ayrıca seoTitle ve socialContent.youtubeTitle alanlarını da senkronize eder.
+522 -38
View File
@@ -31,6 +31,37 @@ export interface ScriptGenerationInput {
};
}
export interface ScriptChapter {
chapterNumber: number;
title: string;
description: string;
targetDurationSeconds: number;
expectedScenes: number;
}
export interface ScriptOutline {
metadata: {
title: string;
description: string;
totalDurationSeconds: number;
language: string;
hashtags: string[];
};
seo: any;
seoTitleAlternatives: string[];
seoScore: number;
chapters: ScriptChapter[];
musicPrompt: string;
musicStyle: string;
musicTechnical: {
bpm: number;
key?: string;
instruments: string[];
emotionalArc: string;
};
}
export interface GeneratedScene {
order: number;
title?: string;
@@ -854,56 +885,380 @@ export class VideoAiService {
`Süre: ${input.targetDurationSeconds}s, Dil: ${input.language}`,
);
const userPrompt = this.buildUserPrompt(input);
const expectedScenes = Math.floor(input.targetDurationSeconds / 5);
if (expectedScenes > 18) {
// LONG-FORM VIDEO (CHAPTER-BASED)
return this.generateLongFormScript(input, expectedScenes);
} else {
// SHORT-FORM VIDEO (SINGLE PASS + CHUNKING IF NEEDED)
return this.generateShortFormScript(input, expectedScenes);
}
}
private async generateShortFormScript(
input: ScriptGenerationInput,
expectedScenes: number,
): Promise<GeneratedScript> {
this.logger.log(
`Senaryo üretimi başladı — Konu: "${input.topic}", ` +
`Süre: ${input.targetDurationSeconds}s, Dil: ${input.language}`,
);
const userPrompt = this.buildUserPrompt(input);
const MAX_GLOBAL_ATTEMPTS = 3;
for (let globalAttempt = 1; globalAttempt <= MAX_GLOBAL_ATTEMPTS; globalAttempt++) {
try {
const response = await this.genAI.models.generateContent({
model: this.modelName,
contents: userPrompt,
config: {
systemInstruction: SYSTEM_PROMPT,
temperature: 0.85,
topP: 0.95,
topK: 40,
maxOutputTokens: 8192,
responseMimeType: 'application/json',
},
});
const rawText = response.text ?? '';
if (!rawText.trim()) {
throw new InternalServerErrorException(
'Gemini API boş yanıt döndü. Lütfen tekrar deneyin.',
);
}
// true passed for allowPartial, so it doesn't throw if scenes are incomplete initially
const script = this.parseAndValidateScript(rawText, input.targetDurationSeconds, true);
// --- CHUNKING LOGIC ---
let attempts = 0;
const MAX_ATTEMPTS = 3;
while (script.scenes.length < expectedScenes && attempts < MAX_ATTEMPTS) {
attempts++;
const remainingCount = expectedScenes - script.scenes.length;
this.logger.log(`Chunking: AI ${script.scenes.length}/${expectedScenes} sahne üretti. Kalan ${remainingCount} sahne için istek atılıyor (Deneme ${attempts})...`);
const lastScene = script.scenes[script.scenes.length - 1];
const continuationPrompt = `You previously generated ${script.scenes.length} scenes for the script. We need EXACTLY ${remainingCount} more scenes to reach the target of ${expectedScenes} scenes. Do NOT stop the story early.
Here is the LAST scene you generated for context:
${JSON.stringify(lastScene, null, 2)}
Requirements:
- Generate EXACTLY ${remainingCount} more scenes to complete the story.
- Maintain the same high level of visual detail (all 5 layers) and storytelling continuity.
- The next scene's order number must be ${script.scenes.length + 1}.
- Output ONLY a valid JSON object containing a "scenes" array with the new scenes.
- DO NOT wrap in markdown, just output JSON.`;
const contResponse = await this.genAI.models.generateContent({
model: this.modelName,
contents: continuationPrompt,
config: {
systemInstruction: 'You are an AI video script continuation generator.',
temperature: 0.85,
topP: 0.95,
topK: 40,
maxOutputTokens: 8192,
responseMimeType: 'application/json',
},
});
const rawCont = contResponse.text || '';
const parsedCont = this.parsePartialScenes(rawCont);
if (parsedCont && parsedCont.length > 0) {
// Adjust order numbers just in case AI gets it wrong
let nextOrder = script.scenes.length + 1;
for (const s of parsedCont) {
s.order = nextOrder++;
script.scenes.push(s);
}
} else {
this.logger.warn(`Chunking başarısız oldu, AI devam edemedi. Beklenen: ${expectedScenes}, Üretilen: ${script.scenes.length}`);
break;
}
}
// Final strict validation
const minScenes = Math.max(2, Math.floor(expectedScenes * 0.9));
if (script.scenes.length < minScenes) {
throw new InternalServerErrorException(
`AI yeterli sahne üretemedi (Beklenen: ~${expectedScenes}, Üretilen: ${script.scenes.length}). Bu genellikle uzun videolarda modelin kesilmesinden kaynaklanır. Lütfen "Yeniden Üret" butonuna basın.`
);
}
// -----------------------
const humanizedScript = this.applyHumanizerPass(script);
const enrichedScript = this.enrichVisualPrompts(
humanizedScript,
input.videoStyle,
input.cinematicReference,
input.aspectRatio,
);
this.logger.log(
`✅ Senaryo üretildi — "${enrichedScript.metadata.title}", ` +
`${enrichedScript.scenes.length} sahne, ${enrichedScript.metadata.totalDurationSeconds}s, ` +
`SEO keywords: ${enrichedScript.seo?.keywords?.length || 0}, ` +
`Avg visual prompt words: ${Math.round(enrichedScript.scenes.reduce((sum, s) => sum + s.visualPrompt.split(' ').length, 0) / enrichedScript.scenes.length)}`,
);
return enrichedScript;
} catch (error) {
this.logger.warn(`Senaryo üretim denemesi ${globalAttempt}/${MAX_GLOBAL_ATTEMPTS} başarısız oldu: ${error instanceof Error ? error.message : 'Bilinmeyen Hata'}`);
if (globalAttempt >= MAX_GLOBAL_ATTEMPTS) {
if (error instanceof InternalServerErrorException) throw error;
this.logger.error(
`Gemini API hatası (Tüm denemeler tükendi): ${error instanceof Error ? error.message : 'Bilinmeyen'}`,
);
throw new InternalServerErrorException(
`Senaryo üretimi başarısız: ${error instanceof Error ? error.message : 'API hatası'}`,
);
}
}
}
throw new InternalServerErrorException('Beklenmeyen bir hata oluştu ve senaryo üretilemedi.');
}
private async generateLongFormScript(
input: ScriptGenerationInput,
expectedScenes: number,
): Promise<GeneratedScript> {
this.logger.log(`[Long-Form] Üretim başlatılıyor. Hedef süre: ${input.targetDurationSeconds}s, Toplam beklenen sahne: ${expectedScenes}`);
const expectedChapters = Math.ceil(expectedScenes / 15); // ~75 saniyelik chapterlar
// 1. Generate Outline
const outlinePrompt = this.buildOutlinePrompt(input, expectedScenes, expectedChapters);
let outline: ScriptOutline;
try {
const response = await this.genAI.models.generateContent({
model: this.modelName,
contents: userPrompt,
contents: outlinePrompt,
config: {
systemInstruction: SYSTEM_PROMPT,
temperature: 0.85,
topP: 0.95,
topK: 40,
maxOutputTokens: 8192,
temperature: 0.8,
responseMimeType: 'application/json',
},
});
const rawText = response.text ?? '{}';
outline = JSON.parse(jsonrepair(rawText)) as ScriptOutline;
} catch (error) {
this.logger.error('Outline üretimi başarısız oldu.', error);
throw new InternalServerErrorException('Outline üretimi başarısız.');
}
const rawText = response.text ?? '';
// Initialize full script
const script: GeneratedScript = {
metadata: outline.metadata,
seo: outline.seo,
seoTitleAlternatives: outline.seoTitleAlternatives,
seoScore: outline.seoScore,
scenes: [],
musicPrompt: outline.musicPrompt || 'Epic cinematic music',
musicStyle: outline.musicStyle || 'Cinematic',
musicTechnical: outline.musicTechnical || { bpm: 120, instruments: [], emotionalArc: 'Building' },
ambientSoundPrompts: [],
voiceStyle: 'professional',
socialContent: {
youtubeTitle: outline.metadata.title,
youtubeDescription: outline.metadata.description,
tiktokCaption: outline.metadata.title,
instagramCaption: outline.metadata.title,
twitterText: outline.metadata.title,
}
};
if (!rawText.trim()) {
throw new InternalServerErrorException(
'Gemini API boş yanıt döndü. Lütfen tekrar deneyin.',
);
let previousChapterSummary = "This is the very beginning of the story. Establish the hook and the visual language.";
let globalSceneOrder = 1;
// 2. Generate each chapter sequentially
for (const chapter of outline.chapters) {
this.logger.log(`[Long-Form] Chapter ${chapter.chapterNumber}/${outline.chapters.length} üretiliyor: ${chapter.title}`);
const chapterPrompt = this.buildChapterPrompt(input, outline, chapter, previousChapterSummary, globalSceneOrder);
let attempts = 0;
let chapterScenes: GeneratedScene[] = [];
const MAX_ATTEMPTS = 3;
while (attempts < MAX_ATTEMPTS) {
attempts++;
try {
const response = await this.genAI.models.generateContent({
model: this.modelName,
contents: chapterPrompt,
config: {
systemInstruction: SYSTEM_PROMPT,
temperature: 0.85,
responseMimeType: 'application/json',
},
});
const rawText = response.text ?? '{}';
const parsed = JSON.parse(jsonrepair(rawText));
chapterScenes = parsed.scenes || [];
if (chapterScenes.length > 0) {
break;
}
} catch (error) {
this.logger.warn(`[Long-Form] Chapter ${chapter.chapterNumber} üretim denemesi ${attempts} başarısız oldu.`);
}
}
const script = this.parseAndValidateScript(rawText, input.targetDurationSeconds);
const humanizedScript = this.applyHumanizerPass(script);
const enrichedScript = this.enrichVisualPrompts(
humanizedScript,
input.videoStyle,
input.cinematicReference,
input.aspectRatio,
);
if (chapterScenes.length === 0) {
this.logger.error(`Chapter ${chapter.chapterNumber} için sahne üretilemedi.`);
// Devam etmeyi deneyelim, tamamen çökmesin
} else {
// Add to full script and update counters/context
for (const scene of chapterScenes) {
scene.order = globalSceneOrder++;
script.scenes.push(scene);
}
this.logger.log(
`✅ Senaryo üretildi — "${enrichedScript.metadata.title}", ` +
`${enrichedScript.scenes.length} sahne, ${enrichedScript.metadata.totalDurationSeconds}s, ` +
`SEO keywords: ${enrichedScript.seo?.keywords?.length || 0}, ` +
`Avg visual prompt words: ${Math.round(enrichedScript.scenes.reduce((sum, s) => sum + s.visualPrompt.split(' ').length, 0) / enrichedScript.scenes.length)}`,
);
return enrichedScript;
} catch (error) {
if (error instanceof InternalServerErrorException) throw error;
this.logger.error(
`Gemini API hatası: ${error instanceof Error ? error.message : 'Bilinmeyen'}`,
);
throw new InternalServerErrorException(
`Senaryo üretimi başarısız: ${error instanceof Error ? error.message : 'API hatası'}`,
);
// Update previous summary for the next chapter
previousChapterSummary = `In chapter ${chapter.chapterNumber} ("${chapter.title}"), we covered: ${chapter.description}. The last scene ended with: ${chapterScenes[chapterScenes.length - 1].narrationText}`;
}
}
if (script.scenes.length === 0) {
throw new InternalServerErrorException('Long-form senaryo üretimi başarısız oldu (hiç sahne üretilemedi).');
}
// 3. Post-processing
const humanizedScript = this.applyHumanizerPass(script);
const enrichedScript = this.enrichVisualPrompts(
humanizedScript,
input.videoStyle,
input.cinematicReference,
input.aspectRatio,
);
this.logger.log(`✅ [Long-Form] Senaryo üretildi — Toplam ${enrichedScript.scenes.length} sahne.`);
return enrichedScript;
}
private buildOutlinePrompt(input: ScriptGenerationInput, expectedScenes: number, expectedChapters: number): string {
const langMap: Record<string, string> = {
tr: 'Turkish', en: 'English', es: 'Spanish', de: 'German', fr: 'French',
it: 'Italian', pt: 'Portuguese', ru: 'Russian', ja: 'Japanese', ko: 'Korean',
zh: 'Chinese', ar: 'Arabic', hi: 'Hindi', nl: 'Dutch', sv: 'Swedish', pl: 'Polish'
};
const languageName = langMap[input.language] || input.language;
let prompt = `Create a robust OUTLINE for a long-form video script about: "${input.topic}"
Requirements:
- Target duration: ${input.targetDurationSeconds} seconds
- Narration and subtitle language: ${languageName}
- Total expected scenes across the entire video: ${expectedScenes} scenes (each scene is ~5 seconds).
- You MUST divide this into EXACTLY ${expectedChapters} chapters.
- Distribute the ${expectedScenes} scenes roughly equally across the ${expectedChapters} chapters.
- Provide full SEO metadata, alternative titles, and music generation parameters.
Output ONLY a JSON object matching this structure:
{
"metadata": {
"title": "...",
"description": "...",
"totalDurationSeconds": ${input.targetDurationSeconds},
"language": "${input.language}",
"hashtags": []
},
"seo": {
"title": "...",
"description": "...",
"keywords": [],
"estimatedSearchVolume": "...",
"trendingHashtags": [],
"schemaMarkup": {}
},
"seoTitleAlternatives": [],
"seoScore": 95,
"chapters": [
{
"chapterNumber": 1,
"title": "...",
"description": "Detailed description of what happens in this chapter",
"targetDurationSeconds": 75,
"expectedScenes": 15
}
],
"musicPrompt": "...",
"musicStyle": "...",
"musicTechnical": { "bpm": 120, "instruments": [], "emotionalArc": "Building" }
}
`;
if (input.seoKeywords && input.seoKeywords.length) {
prompt += `\nTarget SEO keywords to incorporate naturally: ${input.seoKeywords.join(', ')}\n`;
}
if (input.referenceUrl) {
prompt += `\nReference video/content for style inspiration: ${input.referenceUrl}\n`;
}
if (input.sourceTweet) {
const tw = input.sourceTweet;
prompt += `\n═══ X/TWITTER SOURCE CONTENT ═══\n`;
prompt += `This video is based on a viral X/Twitter post by @${tw.authorUsername}.\n`;
prompt += `Original tweet text:\n"${tw.text}"\n`;
prompt += `\nIMPORTANT WHITE-LABELING RULES: Do NOT mention the original author or that this is from a tweet.\n`;
}
return prompt;
}
private buildChapterPrompt(input: ScriptGenerationInput, outline: ScriptOutline, chapter: ScriptChapter, previousChapterSummary: string, startOrder: number): string {
const langMap: Record<string, string> = {
tr: 'Turkish', en: 'English', es: 'Spanish', de: 'German', fr: 'French',
it: 'Italian', pt: 'Portuguese', ru: 'Russian', ja: 'Japanese', ko: 'Korean',
zh: 'Chinese', ar: 'Arabic', hi: 'Hindi', nl: 'Dutch', sv: 'Swedish', pl: 'Polish'
};
const languageName = langMap[input.language] || input.language;
const aspectRatioGuide = this.getAspectRatioGuide(input.aspectRatio);
return `Create the scenes for CHAPTER ${chapter.chapterNumber} of a long-form video script.
Topic of the full video: "${input.topic}"
Overall style: ${input.videoStyle}${aspectRatioGuide}
CHAPTER ${chapter.chapterNumber} DETAILS:
- Title: "${chapter.title}"
- Description: ${chapter.description}
- Previous Chapter Context: ${previousChapterSummary}
- Target Duration for this chapter: ${chapter.targetDurationSeconds} seconds
- EXACTLY ${chapter.expectedScenes} scenes must be generated for this chapter.
- Narration Language: ${languageName}
- Start the scene "order" sequence from ${startOrder}.
Your task is to output ONLY the scenes for this specific chapter. Output a JSON object with a "scenes" array.
Each scene MUST follow the 5-Layer Visual Prompt Architecture in English.
JSON structure:
{
"scenes": [
{
"order": ${startOrder},
"narrationText": "...",
"visualPrompt": "Subject: ... Mood: ... Lighting: ... Camera & Lens: ... Finishing: ... Avoid: ...",
"subtitleText": "...",
"durationSeconds": 5,
"transitionType": "CUT"
}
]
}
REMEMBER: Generate EXACTLY ${chapter.expectedScenes} scenes. Make the transition from the previous chapter flow seamlessly.
`;
}
/**
@@ -1007,6 +1362,95 @@ Return ONLY valid JSON:
}
}
/**
* Projenin konusu ve diğer detaylarına göre kapsamlı SEO ve Sosyal Medya içerikleri üretir.
*/
async generateSocialAndSeoContent(
topic: string,
currentTitle: string,
language: string,
keywords: string[],
): Promise<{ seo: any; socialContent: any }> {
this.logger.log(`Sosyal medya ve SEO içerikleri üretiliyor — Konu: "${topic}"`);
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "${topic}"
CURRENT TITLE: "${currentTitle}"
LANGUAGE: ${language} (generate all text in THIS language)
EXISTING KEYWORDS: ${keywords.join(', ')}
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["most_valuable_keyword", "keyword2", "keyword3", "...", "keyword10"], // Generate at least 10 keywords, ordered by most valuable to least valuable
"hashtags": ["hashtag1", "hashtag2", "hashtag3"], // Do NOT include the # symbol in the strings
"trendingHashtags": ["trending1", "trending2"], // Do NOT include the # symbol in the strings
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await this.genAI.models.generateContent({
model: this.modelName,
contents: promptText,
config: {
temperature: 0.8,
topP: 0.95,
maxOutputTokens: 8192,
responseMimeType: 'application/json',
},
});
const rawText = response.text ?? '';
if (!rawText.trim()) {
throw new InternalServerErrorException('Gemini API boş yanıt döndü.');
}
let parsed: any;
try {
parsed = JSON.parse(rawText);
} catch {
// Fallback parser if JSON parse fails
try {
const repaired = jsonrepair(rawText);
parsed = JSON.parse(repaired);
} catch {
// simple regex to extract json block
const match = rawText.match(/\\{.*\\}/s);
if (match) parsed = JSON.parse(match[0]);
else throw new Error('Cannot parse JSON');
}
}
if (!parsed.seo || !parsed.socialContent) {
this.logger.error(`Eksik alanlar var. Gemini'den gelen RAW JSON: ${rawText}`);
throw new Error('Eksik alanlar (seo veya socialContent yok)');
}
return parsed;
} catch (error) {
this.logger.error(`SEO/Sosyal Medya içerik üretim hatası: ${error instanceof Error ? error.message : 'Bilinmeyen'}`);
const errMsg = error instanceof Error ? error.message : '';
if (errMsg.includes('Eksik alanlar') || errMsg.includes('Cannot parse JSON')) {
throw new InternalServerErrorException(`İçerik üretimi başarısız oldu: AI modelinden eksik veya hatalı veri döndü. Lütfen tekrar deneyin.`);
}
throw new InternalServerErrorException('İçerik üretimi başarısız oldu.');
}
}
/**
* Uzun metinlerden (kitap, uzun makale vb.) potansiyel video konuları çıkarır.
* Gemini 1.5 Flash kullanarak 3-4 çarpıcı YouTube video başlığı önerir.
@@ -1113,7 +1557,7 @@ REQUIREMENTS:
prompt += `5. FINISHING: DOF, film stock, color grade, texture, post-processing\n`;
prompt += `Each visualPrompt MUST end with "Avoid: [list of things to avoid]"\n`;
prompt += `Scene 1 establishes the visual world — all subsequent scenes maintain continuity.\n`;
prompt += `IMPORTANT FOR LONG VIDEOS: To avoid hitting length limits, keep visual prompts for scenes 2 to ${exactSceneCount} VERY CONCISE (15-20 words max), focusing only on what changes. You MUST finish all ${exactSceneCount} scenes!\n`;
prompt += `CRITICAL: Every single scene MUST have a fully detailed visualPrompt containing ALL 5 layers (Subject, Mood, Lighting, Camera, Finishing). Do NOT shorten prompts for later scenes! However, to save space, use concise comma-separated keywords for technical details instead of flowery sentences.\n`;
prompt += `═══════════════════════════════════════════\n`;
if (input.seoKeywords?.length) {
@@ -1925,7 +2369,47 @@ REQUIREMENTS:
return dnaMap[videoStyle] || dnaMap['CINEMATIC'];
}
private parseAndValidateScript(rawText: string, targetDurationSeconds?: number): GeneratedScript {
private parsePartialScenes(rawText: string): any[] {
try {
let cleanText = rawText.trim();
cleanText = cleanText.replace(/^```(?:json)?\s*/i, '');
cleanText = cleanText.replace(/\s*```\s*$/i, '');
cleanText = cleanText.replace(/```(?:json)?\s*/gi, '');
const startIndex = cleanText.indexOf('{');
const endIndex = cleanText.lastIndexOf('}');
if (startIndex >= 0 && endIndex > startIndex) {
cleanText = cleanText.substring(startIndex, endIndex + 1);
}
let parsed;
try {
const repaired = jsonrepair(cleanText);
parsed = JSON.parse(repaired);
} catch (repairError) {
const lastBrace = cleanText.lastIndexOf('}');
if (lastBrace > 0) {
const truncated = cleanText.substring(0, lastBrace + 1);
const repairedTruncated = jsonrepair(truncated);
parsed = JSON.parse(repairedTruncated);
} else {
return [];
}
}
if (parsed && Array.isArray(parsed.scenes)) {
return parsed.scenes;
} else if (Array.isArray(parsed)) {
return parsed;
}
return [];
} catch (e) {
this.logger.error('Continuation JSON parse error', e);
return [];
}
}
private parseAndValidateScript(rawText: string, targetDurationSeconds?: number, allowPartial: boolean = false): GeneratedScript {
let parsed: GeneratedScript;
try {
let cleanText = rawText.trim();
@@ -1982,7 +2466,7 @@ REQUIREMENTS:
throw new InternalServerErrorException('AI en az 2 sahne üretmelidir. Lütfen tekrar deneyin.');
}
if (targetDurationSeconds) {
if (targetDurationSeconds && !allowPartial) {
const expectedScenes = Math.floor(targetDurationSeconds / 5);
// Give 10% margin for Gemini being slightly off, e.g. 24 scenes expected -> min 21 scenes.
const minScenes = Math.max(2, Math.floor(expectedScenes * 0.9));
@@ -12,6 +12,7 @@ export interface VideoGenerationJobPayload {
aspectRatio: string;
videoStyle: string;
targetDuration: number;
visualEffect?: string;
scenes: Array<{
id: string;
order: number;
@@ -0,0 +1,68 @@
import { Controller, Post, Body, Get, Param, UseGuards, HttpCode, HttpStatus, Req } from '@nestjs/common';
import { YoutubeToolsService } from './youtube-tools.service';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/auth.guards';
@ApiTags('youtube-tools')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('youtube-tools')
export class YoutubeToolsController {
constructor(private readonly youtubeToolsService: YoutubeToolsService) {}
@Post('analyze')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'YouTube video ve yorum analiz aracı' })
@ApiResponse({ status: 200, description: 'Analiz tamamlandı' })
async analyzeYoutubeVideo(@Body('url') url: string, @Req() req: any) {
return this.youtubeToolsService.analyzeYoutubeVideo(url, req.user.id);
}
@Get('history')
@ApiOperation({ summary: 'Kullanıcının geçmiş YouTube analizlerini getirir' })
@ApiResponse({ status: 200, description: 'Geçmiş analizler listelendi' })
async getHistory(@Req() req: any) {
return this.youtubeToolsService.getAnalysisHistory(req.user.id);
}
@Get('analyze/:id')
@ApiOperation({ summary: 'Belirli bir analizin detaylarını getirir' })
@ApiResponse({ status: 200, description: 'Analiz detayı getirildi' })
async getAnalysisById(@Param('id') id: string, @Req() req: any) {
return this.youtubeToolsService.getAnalysisById(id, req.user.id);
}
// ==========================================
// SEO ENDPOINTS
// ==========================================
@Post('seo/analyze')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'YouTube SEO analizi yapar' })
@ApiResponse({ status: 200, description: 'SEO Analizi tamamlandı' })
async analyzeYoutubeSEO(@Body('url') url: string, @Req() req: any) {
return this.youtubeToolsService.analyzeYoutubeSEO(url, req.user.id);
}
@Get('seo/history')
@ApiOperation({ summary: 'Kullanıcının geçmiş YouTube SEO analizlerini getirir' })
@ApiResponse({ status: 200, description: 'Geçmiş SEO analizler listelendi' })
async getSeoHistory(@Req() req: any) {
return this.youtubeToolsService.getSeoHistory(req.user.id);
}
@Get('seo/analyze/:id')
@ApiOperation({ summary: 'Belirli bir SEO analizinin detaylarını getirir' })
@ApiResponse({ status: 200, description: 'SEO Analizi detayı getirildi' })
async getSeoAnalysisById(@Param('id') id: string, @Req() req: any) {
return this.youtubeToolsService.getSeoAnalysisById(id, req.user.id);
}
@Post('seo/generate-image')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'SEO Thumbnail promptuna göre kapak görseli üretir' })
@ApiResponse({ status: 200, description: 'Görsel üretildi ve URL dönüldü' })
async generateSeoImage(@Body('prompt') prompt: string) {
return this.youtubeToolsService.generateSeoImage(prompt);
}
}
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { YoutubeToolsController } from './youtube-tools.controller';
import { YoutubeToolsService } from './youtube-tools.service';
import { GeminiModule } from '../gemini/gemini.module';
@Module({
imports: [GeminiModule],
controllers: [YoutubeToolsController],
providers: [YoutubeToolsService],
exports: [YoutubeToolsService],
})
export class YoutubeToolsModule {}
@@ -0,0 +1,591 @@
import { Injectable, Logger, BadRequestException } from '@nestjs/common';
import { YoutubeTranscript } from 'youtube-transcript';
import { Innertube } from 'youtubei.js';
import { GeminiService } from '../gemini/gemini.service';
import { PrismaService } from '../../database/prisma.service';
import { StorageService } from '../storage/storage.service';
@Injectable()
export class YoutubeToolsService {
private readonly logger = new Logger(YoutubeToolsService.name);
private youtubeClient: Innertube | null = null;
constructor(
private readonly geminiService: GeminiService,
private readonly prisma: PrismaService,
private readonly storageService: StorageService
) {
this.initYoutubeClient();
}
private async initYoutubeClient() {
try {
this.youtubeClient = await Innertube.create({ lang: 'tr', location: 'TR' });
this.logger.log('youtubei.js Innertube client başarıyla başlatıldı.');
} catch (error: any) {
this.logger.error(`Innertube başlatılamadı: ${error.message}`);
}
}
/**
* Videonun transkriptini çeker ve uzunsa Gemini ile özetler/bölümlendirir.
*/
async extractAndAnalyzeTranscript(url: string) {
this.logger.log(`Transkript çekiliyor: ${url}`);
try {
const transcriptList = await YoutubeTranscript.fetchTranscript(url);
// Metni tam olarak birleştir (Timecode olmadan ham metin)
const fullText = transcriptList.map(t => t.text).join(' ');
// Transcript'i parçalara böleceğiz (Gemini sınırları için)
// Şimdilik 10.000 kelimelik parçalar uygundur (yaklaşık 40-50 dk video)
const chunkSize = 25000; // karakter
const chunks: string[] = [];
for (let i = 0; i < fullText.length; i += chunkSize) {
chunks.push(fullText.substring(i, i + chunkSize));
}
this.logger.log(`Transkript toplam ${chunks.length} parçaya (chunk) bölündü.`);
let combinedSummaries = '';
const chapters: any[] = [];
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const prompt = `Aşağıdaki video transkriptinin bir parçası verilmiştir. Lütfen bu bölümdeki en önemli konu başlıklarını, ne anlatıldığını özetle.
Transkript Parçası:
${chunk}
Lütfen JSON formatında dön:
{
"summary": "Bu parçanın genel bir paragraf özeti",
"keyPoints": ["Önemli nokta 1", "Önemli nokta 2"]
}`;
const result = await this.geminiService.generateText(prompt, { model: 'gemini-2.5-flash' });
try {
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const parsed = JSON.parse(jsonMatch[0]);
combinedSummaries += `[Bölüm ${i + 1}] ${parsed.summary}\n`;
chapters.push({
title: `Bölüm ${i + 1}`,
summary: parsed.summary,
points: parsed.keyPoints || [],
});
}
} catch (e) {
this.logger.warn(`Chunk ${i} için JSON parse hatası, ham metin ekleniyor.`);
combinedSummaries += `[Bölüm ${i + 1}] ${result.text}\n`;
}
}
// Genel bir özet (Tüm parçaların özeti)
let overallSummary = combinedSummaries;
if (chunks.length > 1) {
const finalPrompt = `Aşağıda bir videonun çeşitli bölümlerine ait özetler verilmiştir. Bu videonun genel temasını ve ana hatlarını 2-3 paragrafta özetle.\n\nÖzetler:\n${combinedSummaries}`;
const finalResult = await this.geminiService.generateText(finalPrompt, { model: 'gemini-2.5-flash' });
overallSummary = finalResult.text;
}
return {
chapters,
overallSummary,
fullTextLength: fullText.length,
};
} catch (error: any) {
this.logger.error(`Transkript alınırken hata oluştu: ${error.message}`);
return {
error: "Transkript bulunamadı veya okunamadı. Videonun alt yazısı olmayabilir.",
};
}
}
/**
* youtubei.js kullanarak videonun yorumlarını çeker ve Gemini ile analiz eder.
*/
async extractAndAnalyzeComments(videoId: string) {
this.logger.log(`Yorumlar çekiliyor: ${videoId}`);
if (!this.youtubeClient) {
await this.initYoutubeClient();
}
if (!this.youtubeClient) {
throw new BadRequestException('YouTube istemcisi başlatılamadı.');
}
try {
const info = await this.youtubeClient.getInfo(videoId);
const videoDetails = {
title: info.basic_info.title,
thumbnail: info.basic_info.thumbnail?.[0]?.url,
viewCount: info.basic_info.view_count,
likeCount: info.basic_info.like_count,
};
// Yorumları almak için doğrudan youtubeClient kullanıyoruz
const commentThread = await this.youtubeClient.getComments(videoId);
let comments: any[] = [];
// İlk sayfadaki yorumları al
if (commentThread.contents) {
for (const thread of commentThread.contents) {
if (thread.comment?.content?.text) {
comments.push({
text: thread.comment.content.text,
likes: thread.comment.like_count ? parseInt(thread.comment.like_count.toString().replace(/[^0-9]/g, '')) || 0 : 0,
replies: thread.comment.reply_count ? parseInt(thread.comment.reply_count.toString().replace(/[^0-9]/g, '')) || 0 : 0,
author: thread.comment.author?.name || 'Anonim',
});
}
}
}
// Eğer daha fazla yoruma ihtiyacımız varsa bir kaç sayfa daha çekebiliriz
// Token limitleri için 5000 yoruma kadar toplayalım
let currentThread = commentThread;
let pages = 0;
while (currentThread.has_continuation && comments.length < 5000 && pages < 250) {
pages++;
const next = await currentThread.getContinuation();
if (next.contents) {
for (const thread of next.contents) {
if (thread.comment?.content?.text) {
comments.push({
text: thread.comment.content.text,
likes: thread.comment.like_count ? parseInt(thread.comment.like_count.toString().replace(/[^0-9]/g, '')) || 0 : 0,
replies: thread.comment.reply_count ? parseInt(thread.comment.reply_count.toString().replace(/[^0-9]/g, '')) || 0 : 0,
author: thread.comment.author?.name || 'Anonim',
});
}
}
}
currentThread = next;
}
this.logger.log(`Toplam ${comments.length} yorum toplandı.`);
if (comments.length === 0) {
return {
sentiment: { positive: 0, negative: 0, neutral: 100 },
faq: [],
suggestions: [],
commentCount: 0,
videoDetails,
error: "Bu videoda yorum bulunamadı veya yorumlar kapalı."
};
}
// En çok beğeni ve yanıt alanları öne alarak sıralayalım
const sortedComments = [...comments].sort((a, b) => (b.likes + b.replies * 2) - (a.likes + a.replies * 2));
const topComments = sortedComments.slice(0, 10);
const commentTexts = sortedComments.map(c => `- ${c.text}`).join('\n');
const maxCommentText = commentTexts.substring(0, 30000); // Ortalama 30.000 karakterlik (yaklaşık 300-400 yorum) kesit
const prompt = `Sen uzman bir Youtube Data Analistisin. Aşağıda bir videoya gelen yorumların (en çok etkileşim alanlar ağırlıklı olarak) bir listesi bulunmaktadır. Lütfen bu yorumları derinlemesine analiz et ve aşağıdaki JSON formatında döndür:
Yorumlar:
${maxCommentText}
Beklenen JSON Formatı:
{
"sentiment": {
"positive": 45, // yüzde olarak
"negative": 15,
"neutral": 40
},
"faq": [
{
"question": "İnsanların en çok sorduğu soru veya takıldığı konu",
"context": "Neden bu soruyu soruyorlar?"
}
],
"suggestions": [
"Yorumlardan yola çıkarak kanal sahibinin bir sonraki videoda ne çekebileceğine dair 3-4 farklı fikir"
],
"generalResonance": "İzleyiciler video hakkında genel olarak ne hissetmiş, en çok neyi övmüş veya neyi eleştirmiş? (1 paragraf)"
}`;
const result = await this.geminiService.generateText(prompt, { model: 'gemini-2.5-flash' });
try {
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const parsed = JSON.parse(jsonMatch[0]);
return {
...parsed,
topComments, // En iyi 10 yorum
commentCount: comments.length,
videoDetails
};
}
} catch (e) {
this.logger.warn(`Yorum analizi JSON parse hatası. ${e.message}`);
return { error: "Yorumlar analiz edilemedi." };
}
} catch (error: any) {
this.logger.error(`Yorumlar çekilirken hata oluştu: ${error.message}`);
return { error: `Yorum çekme hatası: ${error.message}` };
}
}
/**
* Çapraz analiz yapar: Transkript Özeti vs Yorum Analizi
*/
async generateCrossAnalysis(transcriptSummary: string, commentAnalysis: any) {
this.logger.log('Çapraz analiz yapılıyor...');
if (!transcriptSummary || !commentAnalysis || commentAnalysis.error) {
return { error: "Transkript veya yorum eksik olduğu için çapraz analiz yapılamadı." };
}
const prompt = `Sen uzman bir içerik stratejistisin. Aşağıda bir videonun "Transkript Özeti" ve bu videoya gelen "Yorumların Analizi" verilmiştir.
Senin görevin, videonun içeriği ile izleyici tepkisini çapraz analiz (Cross-Analysis) yapmaktır.
Transkript Özeti:
${transcriptSummary}
Yorum Analizi:
Genel Yankı: ${commentAnalysis.generalResonance}
Duygu Durumu: %${commentAnalysis.sentiment?.positive} Pozitif, %${commentAnalysis.sentiment?.negative} Negatif
Sık Sorulan Sorular: ${JSON.stringify(commentAnalysis.faq)}
Lütfen aşağıdaki JSON formatında bir rapor döndür:
{
"alignment": "İçerik ile izleyici beklentisi ne kadar örtüşüyor? (örn: %80)",
"misunderstoodPoints": ["Videonun transkriptinde anlatılan ama izleyicilerin yorumlarda anlamadığını / farklı anladığını belirttiği noktalar"],
"highlightedStrengths": ["İzleyicilerin transkripte dayanarak en çok övdüğü veya dikkat çektiği bölümler"],
"contentGaps": ["Videoda eksik bırakılan ve yorumlarda insanların sorduğu / aradığı bilgiler"]
}`;
const result = await this.geminiService.generateText(prompt, { model: 'gemini-2.5-flash' });
try {
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
if (jsonMatch) {
return JSON.parse(jsonMatch[0]);
}
} catch (e) {
this.logger.warn(`Çapraz analiz JSON parse hatası.`);
}
return { error: "Çapraz analiz sonuçları ayrıştırılamadı." };
}
/**
* Videodan videoId çıkarır
*/
private extractVideoId(url: string): string | null {
const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
const match = url.match(regExp);
return (match && match[2].length === 11) ? match[2] : null;
}
/**
* Tüm süreçleri birleştiren ana fonksiyon
*/
async analyzeYoutubeVideo(url: string, userId: string) {
this.logger.log(`Tüm analiz süreci başlatılıyor: ${url} (User: ${userId})`);
const videoId = this.extractVideoId(url);
if (!videoId) {
throw new BadRequestException('Geçersiz YouTube URLsi');
}
// 1. Transkript çek ve özetle
const transcriptData = await this.extractAndAnalyzeTranscript(url);
// 2. Yorumları çek ve analiz et
const commentsData = await this.extractAndAnalyzeComments(videoId);
// 3. Çapraz analiz yap
let crossAnalysis = null;
if (!transcriptData.error && !commentsData.error) {
crossAnalysis = await this.generateCrossAnalysis(
transcriptData.overallSummary as string,
commentsData
);
}
const finalResult = {
videoId,
url,
transcriptAnalysis: transcriptData,
commentsAnalysis: commentsData,
crossAnalysis
};
// Save to database
try {
const savedAnalysis = await this.prisma.youtubeAnalysis.create({
data: {
userId,
videoUrl: url,
videoId,
title: commentsData.videoDetails?.title || 'Bilinmeyen Video',
thumbnail: commentsData.videoDetails?.thumbnail || '',
viewCount: commentsData.videoDetails?.viewCount?.toString() || '0',
likeCount: commentsData.videoDetails?.likeCount?.toString() || '0',
commentCount: commentsData.commentCount || 0,
analysisData: finalResult as any,
}
});
this.logger.log(`Analiz başarıyla DB'ye kaydedildi. ID: ${savedAnalysis.id}`);
} catch (dbError: any) {
this.logger.error(`Analiz kaydedilirken DB hatası: ${dbError.message}`);
}
return finalResult;
}
async getAnalysisHistory(userId: string) {
return this.prisma.youtubeAnalysis.findMany({
where: { userId },
orderBy: { createdAt: 'desc' },
select: {
id: true,
videoId: true,
videoUrl: true,
title: true,
thumbnail: true,
viewCount: true,
likeCount: true,
commentCount: true,
createdAt: true,
}
});
}
async getAnalysisById(id: string, userId: string) {
const analysis = await this.prisma.youtubeAnalysis.findUnique({
where: { id }
});
if (!analysis) {
throw new BadRequestException('Analiz bulunamadı');
}
if (analysis.userId !== userId) {
throw new BadRequestException('Bu analizi görüntüleme yetkiniz yok');
}
return analysis;
}
/**
*/
async analyzeYoutubeSEO(url: string, userId: string) {
let videoId = url;
if (url.includes('v=')) {
videoId = url.split('v=')[1].split('&')[0];
} else if (url.includes('youtu.be/')) {
videoId = url.split('youtu.be/')[1].split('?')[0];
}
if (!this.youtubeClient) {
await this.initYoutubeClient();
}
if (!this.youtubeClient) {
throw new BadRequestException('YouTube istemcisi başlatılamadı.');
}
try {
const info = await this.youtubeClient.getInfo(videoId);
const videoDetails = {
title: info.basic_info.title || '',
description: info.basic_info.short_description || '',
keywords: info.basic_info.keywords || [],
thumbnail: info.basic_info.thumbnail?.[0]?.url || '',
viewCount: info.basic_info.view_count?.toString() || '0',
likeCount: info.basic_info.like_count?.toString() || '0',
};
// Transkripti çek (Eğer varsa, kanca analizi için ilk 2000 karakteri kullanacağız)
let transcriptPreview = '';
try {
const transcriptList = await YoutubeTranscript.fetchTranscript(url);
const fullText = transcriptList.map(t => t.text).join(' ');
transcriptPreview = fullText.substring(0, 3000); // İlk ~3 dk
} catch (e) {
this.logger.warn('Transkript çekilemedi, SEO analizi onsuz devam edecek.');
}
// Gemini Prompt
const prompt = `Sen uzman bir YouTube SEO Stratejisti, Algoritma Uzmanı ve İçerik Üreticisisin.
Aşağıda bir YouTube videosunun mevcut verilerini veriyorum. Senden bu videonun SEO'sunu (Arama Motoru Optimizasyonu) ve tıklanma oranını (CTR) maksimize edecek bir analiz yapmanı istiyorum.
VİDEO BİLGİLERİ:
- Başlık: ${videoDetails.title}
- Açıklama: ${videoDetails.description}
- Mevcut Etiketler/Anahtar Kelimeler: ${videoDetails.keywords.join(', ')}
${transcriptPreview ? `- Videonun ilk 3 dakikasının transkripti (Kanca analizi için): ${transcriptPreview}` : ''}
LÜTFEN AŞAĞIDAKİ JSON FORMATINDA (SADECE JSON, BAŞKA METİN OLMADAN) YANIT VER:
{
"currentStatus": {
"seoScore": 75, // 0-100 arası mantıklı bir skor ver
"titleFeedback": "Başlığın uzunluğu ve etkisi hakkında yorum",
"descriptionFeedback": "Açıklamanın kalitesi hakkında yorum",
"keywordsFeedback": "Etiketlerin durumu hakkında yorum"
},
"hookAnalysis": {
"score": 80, // 0-100
"feedback": "Videonun ilk saniyeleri izleyiciyi tutmak için ne kadar başarılı?",
"suggestion": "Daha iyi bir giriş (hook) nasıl olmalıydı?"
},
"abTestTitles": [
{
"type": "Merak Uyandıran",
"title": "Yeni başlık önerisi",
"reason": "Neden tıklanır?",
"seoScore": 85 // 0-100 SEO skoru
},
{
"type": "Duygusal/Dramatik",
"title": "Yeni başlık önerisi",
"reason": "Neden tıklanır?",
"seoScore": 88
},
{
"type": "Nasıl Yapılır / Rehber",
"title": "Yeni başlık önerisi",
"reason": "Neden tıklanır?",
"seoScore": 92
}
],
"thumbnailIdeas": [
{
"concept": "Konsept açıklaması",
"midjourneyPrompt": "A highly detailed wide shot... --ar 16:9",
"colorPalette": "Örn: Neon Mavi ve Siyah"
} // 3 adet farklı kapak görseli fikri
],
"suggestedKeywords": ["keyword1", "keyword2"], // Aranma hacmi yüksek 10 adet öneri
"suggestedDescriptionTemplate": "YouTube SEO uyumlu, zaman çizelgesi (timestamps) içeren hazır açıklama metni şablonu",
"faqQuestions": ["Soru 1?", "Soru 2?"], // İzleyicilerin Google/YouTube'da bu konuyla ilgili en çok arattığı 5 soru
"shortsIdeas": [
{
"title": "Shorts fikir başlığı",
"context": "Videonun hangi kısmından çıkarılabilir ve neden iyi bir Shorts olur?",
"timestamp": "1.34 - 2.20 arası" // Zaman damgası veya tahmin edilen aralık
} // 3 adet Shorts/Reels video fikri
]
}
ÖNEMLİ UYARI: JSON çıktın KESİNLİKLE 'faqQuestions' ve 'shortsIdeas' dizilerini içermelidir. Bu alanları ASLA atlama. Her zaman en az 3 adet Shorts fikrini zaman damgalarıyla (timestamp) birlikte ver.`;
const result = await this.geminiService.generateText(prompt, { model: 'gemini-2.5-flash' });
let analysisData = {};
let seoScore = 0;
try {
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
if (jsonMatch) {
analysisData = JSON.parse(jsonMatch[0]);
seoScore = (analysisData as any).currentStatus?.seoScore || 0;
}
} catch (e) {
this.logger.error('Gemini SEO JSON parse hatası:', e);
throw new BadRequestException('SEO verisi ayrıştırılamadı.');
}
// Veritabanına kaydet
const savedAnalysis = await this.prisma.youtubeSeoAnalysis.create({
data: {
userId,
videoUrl: url,
videoId,
title: videoDetails.title,
thumbnail: videoDetails.thumbnail,
seoScore,
analysisData: analysisData as any,
}
});
return {
id: savedAnalysis.id,
videoDetails,
seoAnalysis: analysisData
};
} catch (error: any) {
this.logger.error(`SEO Analizi sırasında hata: ${error.message}`);
throw new BadRequestException('SEO analizi yapılamadı: ' + error.message);
}
}
async getSeoHistory(userId: string) {
return this.prisma.youtubeSeoAnalysis.findMany({
where: { userId },
orderBy: { createdAt: 'desc' },
select: {
id: true,
videoId: true,
videoUrl: true,
title: true,
thumbnail: true,
seoScore: true,
createdAt: true,
}
});
}
async getSeoAnalysisById(id: string, userId: string) {
const analysis = await this.prisma.youtubeSeoAnalysis.findUnique({
where: { id }
});
if (!analysis) {
throw new BadRequestException('SEO Analizi bulunamadı');
}
if (analysis.userId !== userId) {
throw new BadRequestException('Bu analizi görüntüleme yetkiniz yok');
}
return {
id: analysis.id,
videoUrl: analysis.videoUrl,
videoDetails: {
title: analysis.title,
thumbnail: analysis.thumbnail,
},
seoAnalysis: analysis.analysisData,
};
}
/**
* Generates a thumbnail image based on the prompt provided.
*/
async generateSeoImage(prompt: string): Promise<{ url: string }> {
this.logger.log(`SEO için görsel üretiliyor: ${prompt.substring(0, 50)}...`);
// Generate the image using Gemini Service (forcing Imagen for strict 16:9)
const imageResult = await this.geminiService.generateImage(prompt, '16:9', false, true);
if (!imageResult) {
throw new BadRequestException('Görsel üretilemedi.');
}
// Upload to Cloudflare R2 / S3
const key = `youtube-seo-thumbnails/${Date.now()}-${Math.floor(Math.random() * 1000)}.jpg`;
await this.storageService.upload(
key,
imageResult.buffer,
imageResult.mimeType,
);
const url = this.storageService.getPublicUrl(key);
return { url };
}
}
+82
View File
@@ -0,0 +1,82 @@
const { PrismaClient } = require('@prisma/client');
const { GoogleGenAI } = require('@google/genai');
const prisma = new PrismaClient();
async function main() {
const project = await prisma.project.findUnique({
where: { id: '686d6496-2963-4527-8703-02b843e50159' }
});
const scriptJson = project.scriptJson || {};
let videoContentSummary = project.title;
if (scriptJson.scenes && Array.isArray(scriptJson.scenes)) {
videoContentSummary = scriptJson.scenes.map((s) => s.narration).join(' ');
} else if (project.prompt) {
videoContentSummary = project.prompt.substring(0, 1000);
}
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "${videoContentSummary.substring(0, 2000)}"
CURRENT TITLE: "${project.title}"
LANGUAGE: ${project.language} (generate all text in THIS language)
EXISTING KEYWORDS: ${(project.seoKeywords || []).join(', ')}
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash', // Trying flash 8b if flash not found, or maybe just 'gemini-1.5-flash'
contents: promptText,
config: {
temperature: 0.8,
topP: 0.95,
maxOutputTokens: 2048,
responseMimeType: 'text/plain',
},
});
console.log("RAW TEXT:\n", response.text);
} catch (err) {
if (err.status === 404) {
try {
const response2 = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: promptText,
config: {
temperature: 0.8,
topP: 0.95,
maxOutputTokens: 2048,
responseMimeType: 'text/plain',
},
});
console.log("RAW TEXT:\n", response2.text);
} catch (err2) {
console.error("Failed again:", err2);
}
} else {
console.error(err);
}
}
}
main();
+45
View File
@@ -0,0 +1,45 @@
const { PrismaClient } = require('@prisma/client');
const { GoogleGenAI } = require('@google/genai');
const prisma = new PrismaClient();
async function main() {
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
CURRENT TITLE: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
LANGUAGE: de (generate all text in THIS language)
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: promptText,
});
console.log("FULL RESPONSE OBJECT:", JSON.stringify(response, null, 2));
console.log("RAW TEXT:\n", response.text);
} catch (err) {
console.error(err);
}
}
main();
+47
View File
@@ -0,0 +1,47 @@
const { PrismaClient } = require('@prisma/client');
const { GoogleGenAI } = require('@google/genai');
const prisma = new PrismaClient();
async function main() {
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
CURRENT TITLE: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
LANGUAGE: de (generate all text in THIS language)
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: promptText,
config: {
responseMimeType: 'application/json',
}
});
console.log("RAW TEXT:\n", response.text);
} catch (err) {
console.error(err);
}
}
main();
+56
View File
@@ -0,0 +1,56 @@
const { PrismaClient } = require('@prisma/client');
const { GoogleGenAI } = require('@google/genai');
const prisma = new PrismaClient();
async function main() {
const project = await prisma.project.findUnique({
where: { id: '686d6496-2963-4527-8703-02b843e50159' }
});
const scriptJson = project.scriptJson || {};
let videoContentSummary = project.title;
if (scriptJson.scenes && Array.isArray(scriptJson.scenes)) {
videoContentSummary = scriptJson.scenes.map((s) => s.narration).join(' ');
}
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "${videoContentSummary}"
CURRENT TITLE: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
LANGUAGE: de (generate all text in THIS language)
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: promptText,
config: {
responseMimeType: 'application/json',
}
});
console.log("RAW TEXT:\n", response.text);
} catch (err) {
console.error(err);
}
}
main();
+57
View File
@@ -0,0 +1,57 @@
const { PrismaClient } = require('@prisma/client');
const { GoogleGenAI } = require('@google/genai');
const prisma = new PrismaClient();
async function main() {
const project = await prisma.project.findUnique({
where: { id: '686d6496-2963-4527-8703-02b843e50159' }
});
const scriptJson = project.scriptJson || {};
let videoContentSummary = project.title;
if (scriptJson.scenes && Array.isArray(scriptJson.scenes)) {
videoContentSummary = scriptJson.scenes.map((s) => s.narration).join(' ');
}
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const promptText = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "${videoContentSummary}"
CURRENT TITLE: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
LANGUAGE: de (generate all text in THIS language)
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: promptText,
config: {
responseMimeType: 'application/json',
maxOutputTokens: 8192,
}
});
console.log("RAW TEXT:\n", response.text);
} catch (err) {
console.error(err);
}
}
main();
+20
View File
@@ -0,0 +1,20 @@
const { Innertube } = require('youtubei.js');
const util = require('util');
async function test() {
const youtube = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
const commentThread = await youtube.getComments(videoId);
if (commentThread.contents && commentThread.contents.length > 0) {
const thread = commentThread.contents.find(t => t.has_replies);
if (thread) {
console.log('comment keys:', Object.keys(thread.comment));
console.log('comment reply_count:', thread.comment.reply_count);
console.log('comment like_count:', thread.comment.like_count);
console.log('comment content text:', thread.comment.content?.text);
}
}
}
test().catch(console.error);
+34
View File
@@ -0,0 +1,34 @@
const { Innertube } = require('youtubei.js');
async function test() {
const youtube = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
console.log('Fetching comments for', videoId);
const commentThread = await youtube.getComments(videoId);
let comments = [];
let currentThread = commentThread;
let pages = 0;
while (currentThread) {
if (currentThread.contents) {
for (const thread of currentThread.contents) {
if (thread.comment?.content?.text) {
comments.push(thread.comment.content.text);
}
}
}
if (currentThread.has_continuation && pages < 50) {
pages++;
currentThread = await currentThread.getContinuation();
console.log('Page', pages, 'Total so far:', comments.length);
} else {
break;
}
}
console.log('Total comments fetched:', comments.length);
}
test().catch(console.error);
+16 -6
View File
@@ -1,9 +1,19 @@
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function main() {
const projects = await prisma.project.findMany({ select: { id: true, userId: true, title: true, status: true, deletedAt: true } });
console.log('Projects:', projects);
const users = await prisma.user.findMany({ select: { id: true, email: true } });
console.log('Users:', users);
async function check() {
const analyses = await prisma.youtubeAnalysis.findMany({
orderBy: { createdAt: 'desc' },
take: 5
});
console.log('Recent analyses:');
analyses.forEach(a => {
console.log(`[${a.createdAt}] ID: ${a.id}, VideoId: ${a.videoId}`);
const data = a.analysisData;
console.log(` Comment Count saved: ${data.commentCount}`);
});
}
main().catch(console.error).finally(() => prisma.$disconnect());
check()
.catch(console.error)
.finally(() => prisma.$disconnect());
+48
View File
@@ -0,0 +1,48 @@
const { GoogleGenAI } = require('@google/genai');
async function main() {
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const prompt = `Generate comprehensive SEO metadata and social media content for the following video project.
TOPIC: "Summary of scene narrations..."
CURRENT TITLE: "Bier: Sein 13.000 Jahre altes Geheimnis, das Sie nicht kennen? 🤯"
LANGUAGE: tr (generate all text in THIS language)
EXISTING KEYWORDS:
Return ONLY valid JSON matching this exact structure, with no markdown formatting or backticks:
{
"seo": {
"title": "SEO optimized title (under 60 chars)",
"description": "Meta description (150-200 chars)",
"keywords": ["keyword1", "keyword2", "keyword3", "keyword4", "keyword5"],
"hashtags": ["#hashtag1", "#hashtag2", "#hashtag3"],
"trendingHashtags": ["#trending1", "#trending2"],
"estimatedSearchVolume": "Summary of search volume for keywords",
"schemaMarkup": { "@type": "VideoObject", "name": "..." }
},
"socialContent": {
"youtubeTitle": "Clickable YouTube title with emojis",
"youtubeDescription": "Full YouTube description including hashtags and call to actions",
"tiktokCaption": "Catchy TikTok caption with trending hashtags",
"instagramCaption": "Engaging Instagram caption with emojis and hashtags",
"twitterText": "Viral X (Twitter) post text under 280 characters"
}
}`;
try {
const response = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: prompt,
config: {
temperature: 0.8,
topP: 0.95,
maxOutputTokens: 2048,
responseMimeType: 'application/json',
},
});
console.log("RESPONSE:", response.text);
} catch (err) {
console.error(err);
}
}
main();
+11
View File
@@ -0,0 +1,11 @@
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function main() {
const project = await prisma.project.findUnique({
where: { id: '686d6496-2963-4527-8703-02b843e50159' }
});
console.log("SOCIAL CONTENT:", JSON.stringify(project.socialContent, null, 2));
console.log("SEO:", project.seoTitle, project.seoKeywords);
}
main();
+26
View File
@@ -0,0 +1,26 @@
const { Innertube } = require('youtubei.js');
async function test() {
const youtube = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
console.log('Fetching comments for', videoId);
const commentThread = await youtube.getComments(videoId);
if (commentThread.contents && commentThread.contents.length > 0) {
const thread = commentThread.contents.find(t => t.has_replies);
if (thread) {
console.log('Thread keys:', Object.keys(thread));
console.log('Has replies:', thread.has_replies);
try {
const replies = await thread.getReplies();
console.log('Replies type:', typeof replies);
console.log('Replies object keys:', Object.keys(replies));
} catch (e) {
console.error('Error:', e.message);
}
}
}
}
test().catch(console.error);
+18
View File
@@ -0,0 +1,18 @@
const { Innertube } = require('youtubei.js');
const util = require('util');
async function test() {
const youtube = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
const commentThread = await youtube.getComments(videoId);
if (commentThread.contents && commentThread.contents.length > 0) {
const thread = commentThread.contents.find(t => t.has_replies);
if (thread) {
console.log('replies:', util.inspect(thread.replies, {depth: null}));
console.log('comment_replies_data:', util.inspect(thread.comment_replies_data, {depth: null}));
}
}
}
test().catch(console.error);
+54
View File
@@ -0,0 +1,54 @@
const { Innertube } = require('youtubei.js');
async function test() {
const youtube = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
console.log('Fetching comments for', videoId);
const commentThread = await youtube.getComments(videoId);
let comments = [];
let currentThread = commentThread;
let pages = 0;
while (currentThread) {
if (currentThread.contents) {
for (const thread of currentThread.contents) {
if (thread.comment?.content?.text) {
comments.push(thread.comment.content.text);
}
// Fetch replies if available
if (thread.has_replies) {
try {
const replies = await thread.getReplies();
if (replies) {
// Usually replies are in replies.contents or something similar
// We need to check how to extract replies
for (const reply of replies) {
if (reply.content?.text) {
comments.push(reply.content.text);
} else if (reply.comment?.content?.text) {
comments.push(reply.comment.content.text);
}
}
}
} catch(e) {
console.error('Error fetching replies', e.message);
}
}
}
}
if (currentThread.has_continuation && pages < 50) {
pages++;
currentThread = await currentThread.getContinuation();
console.log('Page', pages, 'Total so far:', comments.length);
} else {
break;
}
}
console.log('Total comments fetched:', comments.length);
}
test().catch(console.error);
+49
View File
@@ -0,0 +1,49 @@
const { YoutubeToolsService } = require('./dist/modules/youtube-tools/youtube-tools.service');
// We need to mock Prisma and Logger
const mockPrisma = {
youtubeAnalysis: {
create: async (data) => console.log('Saved to DB')
}
};
const mockLogger = { log: console.log, error: console.error };
async function test() {
const service = new YoutubeToolsService(mockPrisma);
service.logger = mockLogger;
// We can't easily inject the whole nest app, but we can just copy the comment extraction logic
const { Innertube } = require('youtubei.js');
const youtubeClient = await Innertube.create({ lang: 'tr', location: 'TR' });
const videoId = 'ix8cLltPCCE';
const commentThread = await youtubeClient.getComments(videoId);
let comments = [];
if (commentThread.contents) {
for (const thread of commentThread.contents) {
if (thread.comment?.content?.text) {
comments.push(thread.comment.content.text);
}
}
}
let currentThread = commentThread;
let pages = 0;
while (currentThread.has_continuation && comments.length < 5000 && pages < 250) {
pages++;
const next = await currentThread.getContinuation();
if (next.contents) {
for (const thread of next.contents) {
if (thread.comment?.content?.text) {
comments.push(thread.comment.content.text);
}
}
}
currentThread = next;
}
console.log('Total fetched by logic:', comments.length);
}
test().catch(console.error);
+4
View File
@@ -0,0 +1,4 @@
const yt = require('youtube-transcript');
yt.YoutubeTranscript.fetchTranscript('https://www.youtube.com/watch?v=D98UJl6Ea6o')
.then(res => console.log('Length:', res.map(t => t.text).join(' ').length))
.catch(console.error);
+8
View File
@@ -0,0 +1,8 @@
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function main() {
const analysis = await prisma.youtubeSeoAnalysis.findUnique({ where: { id: "e3140060-2dc6-4b4d-83a6-fd69ee9cbcbd" } });
console.log("currentStatus:", JSON.stringify(analysis.analysisData.currentStatus, null, 2));
}
main().catch(console.error).finally(() => prisma.$disconnect());
+1 -1
View File
@@ -1,4 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts", "prisma", "media-worker"]
"exclude": ["node_modules", "test", "dist", "**/*spec.ts", "prisma", "media-worker", "scripts"]
}