Commit History
-
feat(db): remove unique constraint on Organization.wabaId
CognxSafeTrackAllow multiple organizations to operate under the same WABA (one WhatsApp Business Account, multiple phone numbers / orgs). Migration applied directly on Neon — shadow DB blocked by pgvector.348fb8a
-
fix(audit): resolve remaining TypeScript any types, string enums, and Json validation
CognxSafeTrack +1: Claude Sonnet 4.6TypeScript types (ai-sdk): - Define AIServicePrismaClient structural interface — replaces prisma: any - Define TenantSecrets interface — replaces getTenantSecrets: () => Promise<any> - Define BusinessProfileContext interface — replaces businessProfile?: any in 3 methods - Define BusinessProfileExtraction interface — extractBusinessProfile now fully typed - Define ContactData interface — replaces contact: any in generateCrmCampaign - exerciseCriteria? typed as Record<string, unknown> instead of any - searchResults now typed as SearchResult[] instead of any[] DB enums: - CampaignHistory.status: String → CampaignStatus enum (SENT | DELIVERED | READ | FAILED) - AnalyticsLog.eventType: String → AnalyticsEventType enum (CLICK | READ | RESPONSE) - Migration 20260514000001 applied to production DB Zod validation: - TrackDaySchema: add exerciseCriteria (z.record) and badges (z.array(z.string)) - ai.ts /crm/generate-campaign: enforce contact.phoneNumber (required) via Zod Runtime safety: - wh…2a3e2a1 -
fix(audit): resolve remaining minor technical debt issues
CognxSafeTrack +1: Claude Sonnet 4.6AI/BYOK: - generateText now respects tenant BYOK keys via getProvidersForTenant() (was using global registry) - generateText now applies exponential backoff retry via AIService.withRetry() Backend: - notifications.ts: return 503 instead of 200+undefined when VAPID_PUBLIC_KEY absent - BillingPage: support WA number now reads from VITE_SUPPORT_WA_NUMBER env var (was hardcoded fake number) - KnowledgeBasePage: show toast.error on delete failure (was silently swallowed) DB: - Add @@index([organizationId, exerciseStatus]) on UserProgress for live-feed query performance - Add @@index([createdAt]) on AuditLog for time-range admin queries - Migration 20260513000005 applied to production DB i18n: - Add knowledge.delete_error translation key to all 4 locales (fr, en, es, pt) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d74c1b3
-
fix(audit): resolve 15 critical and major technical debt issues
CognxSafeTrack +1: Claude Sonnet 4.6Security: - campaigns.ts: prevent cross-tenant write by using req.organizationId instead of URL param - billing.ts: restrict org mode change to SUPER_ADMIN only (was incorrectly allowing ADMIN) - CommandHandler: guard SEED command with NODE_ENV !== 'production' - search.ts: return [] instead of fabricated mock data when SERPER_API_KEY absent - scheduler: filter out hard-stopped organizations from nudge and lesson delivery - payments.ts: HMAC signature verification for Wave and Orange Money webhooks + fix track.priceAmount Data integrity: - schema: TrackDay.dayNumber Float → Int, Enrollment.currentDay Float → Int - schema: add @@unique([userId, trackId]) to Enrollment to prevent race condition double-enrollment - Migration 20260513000004 applied to production DB Performance: - admin.ts /live-feed: fix N+1 queries with batch findMany + in-memory map - organizations.ts /:id/messages: add pagination (was unbounded, OOM risk) - crm-service.ts listMessages: add skip/limit/total support Co…97f541f -
feat(jour11+schema): Jour 11 photoUrl on TeamMember + audit doc updates
CognxSafeTrack +1: Claude Sonnet 4.6- TeamMember.photoUrl: new optional field stores the original WhatsApp image URL alongside the AI-extracted name/role/bio - extractAndSaveTeamMember(): now persists photoUrl field - Migration 20260513000003_add_team_member_photo_url - Audit doc: mark Semaine 3-4 fully complete, add Stripe + Jour 11 items Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>61fd7f5 -
feat: Claude Sonnet 4.6 provider + Stripe billing automation
CognxSafeTrack +1: Claude Sonnet 4.6AI: - packages/ai-sdk: ClaudeProvider implements LLMProvider via tool_use structured outputs + zod-to-json-schema - Claude registered at priority 120 (TEXT only), supersedes Gemini for feedback/lessons/chat — -40% cost, better French - ANTHROPIC_API_KEY added to API and worker env validation Stripe: - apps/api/src/routes/stripe.ts: POST /v1/stripe/webhook handles checkout.session.completed, subscription.updated/deleted, invoice.payment_failed/succeeded - Schema: stripeCustomerId + stripeSubscriptionId added to Organization - tenant.ts: 402 gate for isHardStopped orgs (x-api-key calls always pass) - ClientsManagementView: SUSPENDU badge on hard-stopped orgs - STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET added to config Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4a0c3ba -
feat(agentic-week2-4): 5 major features — AI content generator, handoff, tags, soft-delete, SSE
CognxSafeTrack +1: Claude Sonnet 4.6## Agent Créateur de Contenu (Semaine 3) - AIService.generateCurriculum() — structured GPT-4o prompt generates full Track + TrackDays - POST /v1/organizations/:id/content/ai-generate — persists curriculum directly to DB - TrackListPage: "Générer avec IA" button + modal (description, numDays, language, audience) - Auto-redirects to the generated program days after creation ## Human Handoff Detection (Semaine 4) - AIAgentHandler: detects 15 multilingual handoff keywords (FR/EN/ES) - Sets Redis flag handoff:{userId}:{orgId} (24h) — pauses AI responses - Emails org admin with contact info + link to admin UI - Handles subsequent messages while in handoff mode gracefully ## Contact Segmentation by Tags (Semaine 2) - Contact.tags String[] added to Prisma schema (migration + db:push applied) - GET /contacts/tags — list all unique tags in org - PATCH /contacts/:id/tags — set tags on a contact - GET /contacts?tags=tag1,tag2 — filter contacts by tags (hasSome) ## SSE Real-time Updates (Semaine…99f6bca -
feat(billing): implement full wallet/ledger system with hard-stop enforcement
CognxSafeTrack +1: Claude Sonnet 4.6- Add walletBalance + isHardStopped to Organization schema; WalletTransaction ledger model with full audit trail - wallet.ts (worker): debitWallet (atomic $transaction), creditWallet (with AuditLog), checkWalletBalance (Redis 30s cache), alert queuing (low/critical/exhausted/restored) - wallet.ts (api): creditWallet for admin top-up with cache invalidation - usage-tracker.ts: debitWallet integrated into trackAiUsage, trackAudioUsage, trackWhatsAppSent; BYOK orgs skipped - BroadcastHandler + CampaignHandler: bulk debit after send (BROADCAST_PER_USER per recipient) - requireCredits.ts: migrated from aiCreditsUsed/Limit to walletBalance/isHardStopped; shares Redis cache key with worker - whatsapp-logic.ts: replaced assertCredits/CreditExhaustedError with checkWalletBalance/WalletExhaustedError - ai.ts: added requireCredits preHandler to all 11 AI routes (was 4) - billing.ts: /admin/allocate now calls creditWallet(); new GET /wallet route (balance + 20 last txns) - BillingPage: wallet card…0fd3320
-
feat(billing): complete billing system, push notifications, and tech debt fixes
CognxSafeTrack +1: Claude Sonnet 4.6- Usage tracking: instrument pedagogy, audio transcription, AI Agent mode (was silently untracked) - EmailHandler: implement templates 2 (password reset), 3 (quota alert), 4 (monthly report) - Quota alert: auto-queue email + push at 85% threshold via maybeQueueQuotaAlert - Push notifications: PushHandler + send-push BullMQ job; sendPushToUser scoped by organizationId to prevent cross-tenant reads - BillingPage: add credit recharge modal with 3 packs, null guard for missing orgId - i18n: add nav.billing key in fr/en/es/pt locales - Tests: billing.test.ts (10 tests), payments.test.ts (13 tests) - Tech debt: fix empty catch blocks in ai-pedagogy.ts, exclude usage tokens from CRM API response, pass organizationId to generateChat in AIAgentHandler - Docs: add backlog and business model to docs/business/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8280d7d
-
fix(audit): resolve technical debt + UX issues from 2026-05-11 audit
CognxSafeTrack +1: Claude Sonnet 4.6Backend: - Add missing DB indexes on Response.userId and Response.enrollmentId - Add 15s timeout with fallback on AI personalization in pedagogy.ts - Fix race condition in NavigationHandler with atomic $transaction - Fix OnboardingHandler hard reset: use FK cascades, 5-lang confirmation - Change seedDatabase to static import in CommandHandler - Add proper pagination to /enrollments admin endpoint UX/Admin: - Fix responsive grid on dashboard stats (1col mobile → 5col desktop) - Show filename + status label during file upload in ContactsPage - Add success/error toast with import summary on contact CSV/XLSX upload - Add inline form validation with field-level errors in ClientsManagementView - Wire up Copy button on AI-generated messages in ContactsPage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9fe2cc7 -
refactor(debt): resolve all 10 technical debt items from audit
CognxSafeTrack +1: Claude Sonnet 4.6- Redis: singleton pattern (lib/redis.ts) in api + worker, removes 16+ new Redis() calls - Meta token: systemUserTokenIssuedAt field + weekly cron monitor (warn @50d, critical @55d) - Rate limiting: @fastify/rate-limit global 200/min, login 10/min, forgot-password 3/min - Dead code: delete WhatsAppConnectButton.tsx, archive one-off scripts - Silent catches: logger.warn(err) on all backend catch blocks, console.warn on frontend - Meta API types: 5 typed interfaces replace 6 as any casts in organization.ts - Frontend logger: lib/logger.ts wraps Sentry (active when VITE_SENTRY_DSN is set) - Migration: add systemUserTokenIssuedAt + metaBusinessId to Organization schema Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a966957
-
feat(meta-status): store metaBusinessId for reliable business verification
CognxSafeTrack +1: Claude Sonnet 4.6Add optional `metaBusinessId` field to Organization (schema + shared-types). fetchMetaStatus now queries /{businessId}?fields=verification_status directly when metaBusinessId is stored — bypasses WABA edge permission restrictions that block test WABAs and certain system user token scopes. Direct setup form gains a "Business ID Meta" input that saves via PUT /organizations/:id. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>70a5a84
-
feat: implement whatsapp templates management with security hardening, audit logs, and crm integration
CognxSafeTrack0f2f80a -
chore: stabilization, audit fixes and project synchronization
CognxSafeTrack7b0c22b
-
feat: implement bulk whatsapp campaigns with BullMQ and modular activation refactor (isCrmActive/isEdTechActive)
CognxSafeTracke286845 -
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(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 -
chore: execute Phase 1 of technical debt roadmap
CognxSafeTrack- Infra: Updated turbo.json to track Prisma schema changes - Infra: Automated 'prisma generate' in @repo/database build script - DB: Added strategic indexes on Message, Enrollment, and AnalyticsLog for performanceb168be2
-
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 -
feat: implement inbound message tracking and CRM inbox view
CognxSafeTracke01e314 -
feat: implement BroadcastList model and 1-file-per-list import logic
CognxSafeTrack263f6e0 -
feat: add organization useCase selection to modal and backend
CognxSafeTrack55a1607 -
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: implement PaaS modularity foundation (Contact model, modular OrganizationMode, and redesigned creation modal)
CognxSafeTrack3992613 -
fix: resolve IDE errors and update Prisma schema for Phase 2
CognxSafeTrackf8274a4
-
feat: migrate to multi-tenant SaaS architecture with JWT auth and BullMQ notifications
CognxSafeTrack2ab1980
-
feat: Premium Onboarding with Meta SDK and Technical Debt resolution
CognxSafeTrack6248bf4
-
feat: B2B SaaS Multi-tenant architecture & Tech Debt Resolution
CognxSafeTracke289c5c
-
feat: finalize multi-tenant WhatsApp architecture for Meta Tech Provider review
CognxSafeTrack3bf9adc
-
Fix: Add Cascade Delete for UserBadge and TeamMember during INSCRIPTION reset
CognxSafeTrack2e888dc -
Refactor: Technical Debt Repayment (Clean Dashboard, Strict Typing, Pino Logging, SQL Migration)
CognxSafeTrackde6a95b
-
fix: Resolve Production Crash & Add UX Guidance for Completed Exercises
CognxSafeTrackd9186b1 -
feat(ai): team building visual experience and persistence
CognxSafeTrack7b4936e
-
feat: Implement Multi-AI Architecture with Google Gemini provider and failover logic
CognxSafeTrackf41372b
-
feat(Sprint 40): Boucle interactive Deep Dive & persistences des réponses
CognxSafeTrackab37938
-
chore: execute Sprint 38 technical debt resolution (Type Safety, Zod validation, Vitest, Mock LLM extracted)
CognxSafeTrackd9879cf -
feat: Genspark-Standard upgrade, MLOps audit fixes, and XAMLÉ branding
CognxSafeTrackeac938a -
feat(admin): build Ground Truth Training Lab to calculate WER and capture dictionary improvements
CognxSafeTrack83c2a9a -
feat(admin): display Whisper STT confidence score in moderation live feed
CognxSafeTrack5006493
-
feat(admin): human-in-the-loop dashboard base, add PENDING_REVIEW logic and audio overdrive worker
CognxSafeTrack41fe9a9
-
fix(ai): implement pedagogical leap fixes, pending_remediation, coherence locks and cache wipes
CognxSafeTrack4967196 -
fix(ai): add imageUrl field to Prisma schema and correctly route language selection inside whatsapp.ts
CognxSafeTrackf0f0df4
-
feat(sprint19-20): production-ready video integration & STT hardening
CognxSafeTrack## Sprint 19 — STT Pipeline Fix - fix(worker): remove variable shadowing in transcribedText (index.ts) Transcribed text now correctly reaches the pedagogical handler ## Sprint 20 — Production-Ready Video Integration - feat(schema): add videoCaption field to TrackDay model (Prisma) - feat(seed): propagate videoCaption in all upsert paths - feat(pedagogy): video-first delivery with [VIDEO]/[VIDEO_OK]/[VIDEO_FALLBACK] logs - feat(pedagogy): automatic fallback — image + link when WhatsApp rejects video - feat(whatsapp): add TEST_VIDEO <TrackId> <Day> admin command ## Content — Canonical Video Mapping (T1–T5 FR+WO) - content(T1): inject videos v1_1→v1_2 on days 1,2,3,4,5,6,7,8,9,10,11 - content(T2): inject videos v4_4, v7_1, v5_1 on days 1,2,4 - content(T3): inject videos v7_4, v4_6, v9_1 on days 1,4,5 - content(T4): inject videos v5_3, v9_3 (Wave Business), v10_1 on days 5,6,7 - content(T5): inject videos v8_1, v8_2 on days 1,3 - content(T1-FR/WO): fix 26 broken dummy-storage imageUrls…19d10a4
-
feat(wolof): standardized tracks T1-T5 with glossary v4.0 and implemented adaptive multi-sector architecture
CognxSafeTrackb9727b3
-
feat(audit): hardened graduation flow and industrialized badge system
CognxSafeTrackd04688d -
feat(pedagogy): implementation of dynamic content infrastructure and evaluation criteria
CognxSafeTrackca816a7 -
feat: implement adaptive pedagogy, visuals, and remediation (WOW Phase 1)
CognxSafeTrack6c294cb -
feat: implement WOW Sprint 1 (BusinessProfile, Structured Feedback, STT Hardening, Progress Bar)
CognxSafeTrack65aabf4