Commit History
-
fix(webhook+worker): restore gateway forwarding and fix token decryption
CognxSafeTrack +1: Claude Sonnet 4.61. Gateway architecture restored (whatsapp.ts) - When RAILWAY_INTERNAL_URL is set (HF Space), forward raw payload to Railway worker bridge instead of adding directly to Redis. - Original architecture: HF → Railway bridge → Redis → Worker. - Root cause of INSCRIPTION silence: direct Redis queue from HF Space was failing because Redis connection doesn't work from HF containers. 2. MessageHandler: decrypt systemUserToken before use - Was reading org.systemUserToken raw (AES-encrypted) from prisma, sending encrypted string to Meta → auth failure. - Now uses getCachedOrganization() which calls decryptOrgSecrets(). 3. AdminHandler: eliminate double DB query + empty enrollmentId - Was calling prisma.enrollment.findFirst() twice for same record. - Validates enrollment exists before proceeding; adds mediaUrl to Response. 4. CommandHandler: route MENU_HISTORIQUE through queue - Direct sendInteractiveListMessage() call bypassed tenant config. - Now use…2b96936 -
chore: trigger redeploy for technical debt resolution verification
CognxSafeTrack44f1818 -
revert: remove startup seed function — data inserted directly in DB
CognxSafeTrack +1: Claude Sonnet 4.6WhatsAppPhoneNumber (969048009628694 -> default-org-id) and systemUserToken for XAMLÉ Global seeded directly via script. No runtime seed needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6f838af -
fix(seed): auto-register global WhatsApp phone number from env vars on startup
CognxSafeTrack +1: Claude Sonnet 4.6On API start, if WHATSAPP_PHONE_NUMBER_ID + WHATSAPP_ACCESS_TOKEN are set, finds the org whose systemUserToken (decrypted) matches the env token and upserts WhatsAppPhoneNumber so webhook routing works without manual setup. Fixes first/global organization breaking after multi-org migration. Idempotent — no-op if record already exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>34691b4 -
fix(webhook): handle all message types via extractWhatsAppPayload + true Async-First
CognxSafeTrack +1: Claude Sonnet 4.6Previous fix only extracted message.text?.body, silently dropping: - interactive/button_reply (LANG_FR, LANG_WO, SUITE, APPROFONDIR, sector choices) - interactive/list_reply (sector selection list) Now uses extractWhatsAppPayload() from @repo/shared-types which handles all types. Responds 200 before setImmediate enqueue (true Async-First, < 1ms to Meta). Zod schema simplified to z.any() for messages content (Meta types are unbounded). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ad9d288 -
fix(webhook): resolve org by phone_number_id instead of wabaId, enqueue async
CognxSafeTrack +1: Claude Sonnet 4.6Two silent failures broke INSCRIPTION since multi-org was added: 1. Lookup by wabaId failed when org.wabaId was unset → org=null → message dropped 2. whatsappService.handleIncomingMessage does not exist → TypeError swallowed by catch Fix: resolve organizationId from value.metadata.phone_number_id via getOrganizationByPhoneNumberId(), then enqueue handle-inbound to BullMQ. Restores Async-First rule (webhook responds 200 immediately, worker processes). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>15d45f6 -
feat: backlog P0→P3 — toast system, payments, tenant isolation, feedback handler, i18n parity
CognxSafeTrack +1: Claude Sonnet 4.6P0 — Critical fixes - Fix generate-feedback job silently dropped: register FeedbackHandler in worker index.ts - Wire FeedbackHandler: AI feedback, Day 11 TeamMember extraction, atomicity enforced P0 — Toast system (replace all alert()) - Add useToast hook + ToastContext + Toaster component - Replace every alert() across admin pages with toast.success/error/warning/info - Migrate all raw fetch() in pages to api.upload() / api.get() / api.post() P1 — Type safety - CrmAIAssistant: icon prop any → React.ElementType - useAudioRecorder: add onError callback instead of alert() - api.ts: add upload() method for multipart FormData P1 — Payment gateway - Add payment-gateway.ts: Orange Money + Wave initiation and webhook parsing - Rewrite payments.ts routes: initiate, status, webhook handlers with auto-enrollment on SUCCESS P1 — AI regression tests - Add apps/api/test/regression/ai-gold-standards.test.ts (12 tests, 5 suites) P2 — Visual recruitment (Day 11) - FeedbackHandler extracts TeamMem…6dd9bad -
fix(auth): validateApiKey accepts Bearer pattern used by worker
CognxSafeTrack +1: Claude Sonnet 4.6The worker's api-client.ts sends Authorization: Bearer ADMIN_API_KEY, not x-api-key. Without this fix all worker→API internal calls would get 401 after the preHandler security chain was wired. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c5813d5 -
fix(security): wire auth middleware chain in app.ts preHandler
CognxSafeTrack +1: Claude Sonnet 4.6validateApiKey, verifyJwt, enforceOrgIsolation were created during the debt refactor but never imported — admin routes were reachable without a valid JWT token. Chain: API key (worker) → skip JWT | user → jwtVerify → enforceOrgIsolation → injectTenantConfig → runWithTenant Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>cbaf159
-
fix: update production port to 7860 for Hugging Face compatibility and add audit report
CognxSafeTrack10211c3 -
fix: resolve login 400 — auto-resolve organizationId from email when omitted
CognxSafeTrack +1: Claude Sonnet 4.6Backend now falls back to findUserByEmailOnly() when the frontend doesn't send organizationId (deployed admin still uses old build). Password verification still required — auth security unchanged. Also adds organizationId field to login form for first-time users, and removes last default-org-id references from tenant.tsx. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4e2a593
-
feat: implement whatsapp templates management with security hardening, audit logs, and crm integration
CognxSafeTrack0f2f80a -
chore: stabilization, audit fixes and project synchronization
CognxSafeTrack7b0c22b
-
docs: finalize audit report and apply immediate fixes (#1, #10, #16)
CognxSafeTrackb0e801b -
feat: implement bulk whatsapp campaigns with BullMQ and modular activation refactor (isCrmActive/isEdTechActive)
CognxSafeTracke286845 -
fix: log silent catch blocks, remove emojis from production logs
CognxSafeTrack +1: Claude Sonnet 4.6- MediaHandler.ts: .catch(()=>({})) on normalization rules now logs warning with err context before returning empty fallback - indexing.ts: catch{} on URL parsing now logs at debug level; remove duplicate logger import - index.ts: remove emoji characters from logger calls (🚀 ❌ 🛑 👋) — replaced with plain ASCII text prefixes for clean log aggregation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3165bfa -
fix: security hardening, log all silent catch blocks, remove prisma cast
CognxSafeTrack +1: Claude Sonnet 4.6Security: - whatsapp.ts: remove WHATSAPP_VERIFY_TOKEN hardcoded fallback — return 500 if env var is missing instead of silently accepting a public default - rateLimit.ts: key by req.ip (not spoofable x-organization-id header) Code quality — 7 empty catch blocks now log with context: - NudgeHandler, AdminHandler (+ missing logger import), EnrollHandler (x2), MediaHandler (x2), organization.ts invalidateOrgCache - admin.ts: remove (prisma as any).normalizationRule — model is in schema, cast was unnecessary Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aa4f69f -
fix: batch scheduler updates, typed JWT user, log catch blocks, move script
CognxSafeTrack +1: Claude Sonnet 4.6- scheduler.ts: collect completed enrollment IDs in loop, single updateMany after — eliminates N queries per day for completions - ContentHandler.ts: log Redis cache failures instead of swallowing silently - index.ts: remove (request as any).user cast — now safe via FastifyJWT augmentation in types/fastify.d.ts - types/fastify.d.ts: augment @fastify/jwt FastifyJWT interface so request.user resolves to {id, role, organizationId} after jwtVerify(), not string|object|Buffer - delete-user.ts: moved from apps/api root to apps/api/scripts/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2859b85 -
fix: worker cleanup await, Stripe upsert completeness, redundant schema index
CognxSafeTrack +1: Claude Sonnet 4.6- cleanup.ts: cron callback now async/await so cleanWorkerTempFiles() errors are caught instead of silently dropped fire-and-forget - payments.ts: upsert update clause now includes status, amount, currency so a Stripe webhook replay fully idempotent instead of leaving stale fields - schema.prisma: remove redundant @@index([userId, trackId]) on UserProgress — the @@unique constraint already creates a B-tree index on those columns Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ec9b5da -
feat: centralize AI logic in @repo /ai-sdk, harmonize worker HTTP clients
CognxSafeTrack +1: Claude Sonnet 4.6Architecture refactoring: - Extract all AI providers (OpenAI, Gemini, ProviderRegistry, ffmpeg, search) from apps/api/src/services/ai/ into new packages/ai-sdk package - API's services/ai/index.ts is now a thin wrapper that injects prisma, redis and organization context into the shared AIService - Worker gains @repo/ai-sdk dependency; ai-pedagogy.ts delegates to aiService.generatePersonalizedLesson instead of duplicating logic - New apiClient (Axios, 30s timeout) and whatsappClient replace bare fetch calls in InboundHandler and MediaHandler for consistent error handling - Prisma seed fixed: Tracks now include organizationId for multi-tenant compliance Build: all 8 packages pass pnpm turbo run build from clean state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2849f33 -
feat(crm): optimize multimedia pipeline and harden contact schema
CognxSafeTrack- Refactored CrmConversationalDashboard into modular components and hooks (FileImporter, useAudioRecorder) - Centralized contact normalization and bulk import in ContactService - Implemented binary streaming for media proxy to reduce memory pressure - Hardened database schema with MediaType Enum for better data integrityc5fde49 -
feat: implement inbound audio/image transcription, secure media proxy, and client-side bulk contact import
CognxSafeTrack30d60ea -
feat: implement centralized API ErrorHandler
CognxSafeTrack- Created standardized error mapping for Prisma, JWT, and validation errors - Registered setupErrorHandler in Fastify entry point - Improved API reliability and observability through consistent error structurec51c0db
-
chore: CRM stabilization sprint completion
CognxSafeTrack- Refactor: Decomposed CrmConversationalDashboard into modular components (Inbox, AIAssistant, StatsHeader) - Fix: Centralized entity resolution with EntityResolver service (API & Worker) - Fix: Strict Prisma typing, removed 'as any' casts in organization and whatsapp routes - Fix: Implemented broadcast message persistence and accurate usage quota tracking - Schema: Added MessageStatus and status field to Message model4339e77 -
fix: implement GET organization by ID route and direct password setting for new tenants
CognxSafeTracke00083b -
feat: implement 1-to-1 CRM messaging with interactive reply bar
CognxSafeTrack7eaff31 -
fix: resolve prisma type mismatches in monorepo using explicit casts
CognxSafeTrack2088906 -
feat: implement inbound message tracking and CRM inbox view
CognxSafeTracke01e314 -
feat: implement WhatsApp broadcast system with BullMQ worker and rate limiting
CognxSafeTrackf000fc9 -
feat: implement AI campaign generation logic and frontend integration
CognxSafeTrack9f0410f -
fix: bypass stale IDE types for BroadcastList calls
CognxSafeTrack8f24b32 -
feat: implement BroadcastList model and 1-file-per-list import logic
CognxSafeTrack263f6e0 -
feat: enhance CRM contact import with smart heuristics and upsert logic
CognxSafeTrack35ba0c2 -
feat: add organization useCase selection to modal and backend
CognxSafeTrack55a1607 -
chore: deploy manual fixes for TS strict mode
CognxSafeTrack9b8717a -
fix: resolve turbo build failures blocking Railway deployment
CognxSafeTrack +1: Claude Sonnet 4.6- Add missing logger imports in MessageHandler.ts and pedagogy.ts - Remove conflicting fastify.d.ts (prisma: PrismaClient vs prisma: any) - Consolidate all Fastify type augmentations in types/fastify.d.ts - Import @fastify/multipart types to restore req.file() signature All 7 packages now pass pnpm turbo run build (matches Dockerfile builder step). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1fa2a07 -
chore: finalize Sprint P2 & P3 optimizations, baseline prisma migrations, and update technical audit docs
CognxSafeTrackcfbb685 -
feat: push notifications, CRM analytics, Fastify v5 upgrades, schema updates
CognxSafeTrack +1: Claude Sonnet 4.6- Add web push notification service and admin endpoints - Add CRM analytics component and conversational dashboard - Extend Contacts page with campaign management - Update AI and whatsapp routes (Fastify v5 compat, webhook fixes) - Extend Prisma schema with new models and indexes - Add CRM campaign prompt template Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b43e552
-
feat: complete CRM module with ContactsPage and dynamic navigation
CognxSafeTrackcc6456d -
fix: resolve TS errors for CRM import and update dependencies
CognxSafeTrack15f7569 -
feat: implement Excel/CSV contact import route for CRM module
CognxSafeTrack6b487fc -
fix: restore missing Zod schema and regenerate prisma client
CognxSafeTrack5eb7a8b -
feat: implement PaaS modularity foundation (Contact model, modular OrganizationMode, and redesigned creation modal)
CognxSafeTrack3992613 -
fix: resolve 401/400 errors by centralizing API client and injecting organizationId in backend
CognxSafeTrackcfeac02 -
fix: explicit type casting for simulation response
CognxSafeTrack06cb7f3 -
fix: resolve frontend API export and remove node-fetch dependency
CognxSafeTrack5220c27 -
feat: finalize Embedded Signup flow and add webhook simulator
CognxSafeTrackd3a9684 -
feat: implement WhatsApp setup route and documentation for Embedded Signup
CognxSafeTrack3078897 -
fix: replace non-existent RateLimitReplyContext with inline type
CognxSafeTrack979cb50 -
fix: add explicit types to rateLimit errorResponseBuilder parameters
CognxSafeTrackbb62bf7