Commit History
-
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: gold standards tests (15 days + STT + vision) & botName editable in AI setup
CognxSafeTrack +1: Claude Sonnet 4.6- ai-gold-standards: 40 test cases covering all 15 lesson days, STT smoke, vision (day 11 imageUrl), CRM broadcast/conversation, curriculum (FR+EN), pitch deck EN, business profile extraction days 1-6 with quality assertions - AIAgentSetup: botName field now editable (was hardcoded 'Agent IA'); loaded from personality API on mount, saved with PATCH; falls back to 'Agent IA' if blank - i18n: add bot_name_label/placeholder/hint keys to FR, EN, ES, PT locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1c602ea -
chore: remove Stripe — replaced by Orange Money / Wave payment gateway
CognxSafeTrack +1: Claude Sonnet 4.6Delete stripe.ts route file, remove import and /v1/stripe registration from app.ts, drop stripe npm dependency, remove deprecated stripeWebhookRoute stub from payments.ts, and remove stripeCustomerId from admin Organization interface. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>641e72b -
feat: complete agentic audit roadmap — retry, KB generate, real costs, traceId, rate-limit
CognxSafeTrack +1: Claude Sonnet 4.6- ai-sdk: exponential backoff retry (3 attempts, 1s→2s) in callWithFailover; skips 4xx and QuotaExceededError - api/whatsapp: traceId (crypto.randomUUID) propagated to worker bridge via x-trace-id header - api/whatsapp: route-level rate limit 500/min on POST /webhook, returns 200 on rejection - api/organizations: POST /:id/kb/generate — GPT-4o-mini JSON mode generates FAQ pairs, embeds via IndexingService - api/indexing-service: new service batching OpenAI text-embedding-3-small + pgvector INSERT - admin/AnalyticsPage: real cost from UsageEvent aggregate + byFeature breakdown table - admin/KnowledgeBasePage: KB auto-generation panel (description textarea, generate button, FAQ preview) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b438786 -
feat: agentic platform — text-to-sql, pedagogy advisor, security hardening & performance
CognxSafeTrack +1: Claude Sonnet 4.6- Analytics: POST /v1/analytics/query — natural language → GPT-4o-mini → SELECT → results (Text-to-SQL) - Analytics UI: example chips, SQL results table, 'Voir SQL' toggle - Billing: role guard on change_organization_mode (ADMIN+ only) - Nav: /ai-setup accessible to all org members (not just super admin) - Scheduler: startPedagogyAdvisor() — Wednesday 08:30 UTC cron, at-risk nudges (5 languages) + email report - S1 security: organizationId always from JWT for non-super-admin (never from header) - A6: InboundHandler passes user.language to Whisper transcription (Wolof hint: 'fr') - A2: Redis 6h cache for personalized lessons keyed by (trackDayId, activity, language) - P1: sendLessonDay() parallelized from 4 sequential DB queries to 2 (user+trackDay batch, userProgress parallel) - D2: Redis 30s dedup lock on exercise submission to prevent double-submit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5b8761d -
fix(admin): migrate raw fetch() to api client in ClientsManagementView
CognxSafeTrack +1: Claude Sonnet 4.6Removes the last manual fetch() call outside lib/api.ts — billing/admin/allocate now goes through api.post() which injects Authorization and Content-Type automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>60c3938 -
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(crm-ux): tag management, unread badge, handoff release UI
CognxSafeTrack +1: Claude Sonnet 4.6- ContactsPage: tag filter chips, per-contact tag editing with inline input, add/remove tags via PATCH API, colSpan fix for new Tags column - MainLayout: SSE-powered unread message badge on conversations nav item, resets on navigation - UserListPage: soft-delete button, handoff status fetch + "Libérer l'IA" button in conversation modal - admin routes: DELETE /users/:id (soft-delete), GET/DELETE /users/:id/handoff endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>42a2598 -
fix(org-resolve): support legacy non-UUID custom IDs (e.g. default-org-id) + analytics orgId header
CognxSafeTrack +1: Claude Sonnet 4.6- resolveOrgId now uses findFirst with OR [slug, id] so literal custom IDs like "default-org-id" (the seed org XAMLÉ Global) are resolved correctly instead of returning 404 - ContactsPage.tsx: pass selectedOrgId to analytics/usage call — was missing the x-organization-id header, causing systematic 400 on the contacts page Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2cc44c6 -
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 -
fix(conversations): resolve /conversations blank page + slug→UUID KB routes + WABA banner
CognxSafeTrack +1: Claude Sonnet 4.6- Add missing /conversations route to App.tsx (was nav-linked but unregistered) - Apply resolveOrgId() to all 5 KB routes so slug-based org IDs (e.g. xamle-admin-org) no longer cause 404/400 - TemplatesPage: detect WABA-not-configured 400 and show amber banner instead of silently failing - KnowledgeBasePage: show toast on index-kb 400 (no KB URL) with actionable message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9f72dd7 -
feat(admin): UX non-tech complète + i18n 4 langues
CognxSafeTrack +1: Claude Sonnet 4.6- Phases 1-5 : masquage JSON avancé, chat IA global (AdminChat), onboarding WhatsApp guidé, templates assistés IA, agent IA setup guidé - i18n exhaustif : ~70 nouvelles clés en FR/EN/ES/PT pour tous les composants ajoutés (AdminChat, AIAgentSetup, SettingsPage, TemplatesPage, OnboardingWizard) - Chat IA multilingue : l'assistant répond désormais dans la langue de l'utilisateur (FR/EN/ES/PT) sur toutes les pages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>66ff7a1 -
feat(billing): refonte UX non-tech + enrichissement contexte IA
CognxSafeTrack +1: Claude Sonnet 4.6Frontend (BillingPage): - Renommage "Wallet" → "Crédits disponibles" (langage non-technique) - Badge projection dynamique "À ce rythme : encore ~X jours" calculé depuis les transactions des 7 derniers jours - Questions suggérées cliquables (quick-reply chips) avant le 1er message - Suppression "Tokens entrants/sortants" (jargon incompréhensible) - Transactions filtrées : BYOK masqué, layout liste simple vs tableau - Section "Où vont vos crédits IA ?" remplace le jargon feature/type - Indicateur de frappe animé (3 points) dans le chat - Packs recharge avec explication "≈ N messages IA" et badge populaire - Texte WhatsApp clarifié : "Gratuit pour vous — Meta facture directement" Backend (billing.ts /chat): - Wallet balance + isHardStopped ajoutés dans le contexte IA → l'assistant peut maintenant répondre "combien de crédits me reste-t-il" - Burn rate (débit moyen 7j) calculé et injecté : "À ce rythme, votre solde durera encore X jours" - Statut wallet (SUSPENDU / bas / actif) expl…f5ea14d -
feat(billing): close 3 remaining wallet gaps from implementation plan
CognxSafeTrack +1: Claude Sonnet 4.6⑫ sendTextMessage() wallet debit coverage: - Add organizationId?: string to sendTextMessage() config — calls trackWhatsAppSent() automatically after each successful send - NudgeHandler, ContentHandler, EnrollHandler, MediaHandler, AdminHandler: pass organizationId in tenantConfig so every outbound message triggers the debit without touching each callsite individually ⑯ GET /billing/summary now includes wallet block: - wallet: { balance, isHardStopped, creditToFcfa, balanceFcfa } appended to every summary response ⑱ BillingPage: wallet transaction table: - Table showing last 20 transactions (date, type, description, amount, balance after) - Type labels with emoji (recharge vs debit), BYOK badge, red/green amount colouring - Inserted between feature breakdown and chat widget Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f5126bc -
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): enforce AI credit limits across all surfaces
CognxSafeTrack +1: Claude Sonnet 4.6- credit-guard.ts (worker): assertCredits() blocks AI when creditsUsed >= creditsLimit; Redis cache 60s prevents DB hit on every message - whatsapp-logic.ts: credit guard injected before handler chain; RECHARGE keyword bypasses the guard so users can always request a payment link - CommandHandler: new RECHARGE keyword sends payment URL or contact message - i18n: credit_exhausted + recharge_link + recharge_contact in 5 languages - requireCredits middleware (api): 402 on personalize-lesson, tts, generate-feedback, crm/generate-campaign - billing route: POST /v1/billing/admin/allocate (SUPER_ADMIN only) supports set/add actions + optional usage reset + Redis cache invalidation - ClientsManagementView: "Crédits IA" button (SUPER_ADMIN only) per org opens allocation modal with set/add/reset controls - BillingPage: red exhaustion banner when creditsUsed >= creditsLimit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6484585
-
fix(admin): make all modals scrollable and responsive on mobile
CognxSafeTrack +1: Claude Sonnet 4.6RechargeModal (BillingPage), create-org modal (ClientsManagementView), and create-template modal (TemplatesPage) now use the bottom-sheet pattern: fixed header + scrollable body + fixed footer, max-h-[90vh], and items-end on mobile so they slide up from the bottom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a3f8777 -
fix(training): fix o.map crash on /training page
CognxSafeTrack +1: Claude Sonnet 4.6TrainingService.getPendingAudios returns { pending, total, page, limit } but TrainingLab was calling setAudios(data) directly — audios became an object and .map() crashed on page load. Also guard missingWords ?? []. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e8b9f53 -
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(admin): sidebar active states, responsive mobile drawer, correct nav labels
CognxSafeTrack +1: Claude Sonnet 4.6- NavLink with isActive for proper active highlight (bg-white/15) - end={true} on home so "/" doesn't match all child routes - Added /conversations and /ai-setup to nav; fixed /kb and /content labels - Scrollable nav (overflow-y-auto) so it never clips on small screens - Desktop: sticky h-screen sidebar (hidden lg:flex) - Mobile: hamburger in sticky top bar + translate-x drawer + backdrop overlay - Better avatar initial fallback (name → email → 'U') - Shared sidebarInner JSX var avoids duplicate markup - Added nav.kb / nav.content / nav.conversations / nav.ai_setup keys to all 4 locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>785cec2 -
fix(ux): dashboard error state with 15s timeout and retry button
CognxSafeTrack +1: Claude Sonnet 4.6Add fetchError state, Promise.race timeout (15s), and an error screen with AlertTriangle + "Réessayer" button if the API doesn't respond. Prevents the spinner from hanging indefinitely on network failures. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>34c32dc -
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 -
feat(admin): responsive bottom sheet + spring animation for TierInfoModal
CognxSafeTrack +1: Claude Sonnet 4.6- Mobile: slides up from bottom (spring, damping 32), rounded-t-3xl, drag handle pill, max 85dvh with internal scroll + overscroll-contain - Desktop (sm+): centered card with same spring entrance - AnimatePresence handles exit animation (slides back down) - ESC key closes + body scroll lock during open - Backdrop separated from panel div for correct z-layering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>74aa3a1 -
feat(admin): tier color + info modal for WhatsApp messaging limits
CognxSafeTrack +1: Claude Sonnet 4.6- Color-coded limit display: red (TIER_50/250), blue (TIER_1K), emerald (10K+) - Info button (ℹ) on DailyLimitCell and billing modal opens TierInfoModal - TierInfoModal: ladder of all 6 Meta tiers with current highlighted, quality rating panel (GREEN/YELLOW/RED) with contextual explanation - BillingTierDisplay: reusable component for billing modal with same colors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>00b9619 -
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
-
fix(wizard): replace alert() with toast + add tech debt audit doc
CognxSafeTrack +1: Claude Sonnet 4.6Replaces native alert() calls in OnboardingWizard with useToast(). Adds docs/audit_dette_technique_10052026.md with 10 identified debt items (2 critical: token expiry monitoring, Redis singleton). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e1ca6ab -
feat(wizard): rewrite OnboardingWizard for super-admin org creation
CognxSafeTrack +1: Claude Sonnet 4.63 steps: Organisation (name + slug auto + mode selector) → Administrateur (name + email + optional password) → WhatsApp (optional: direct config OR embedded signup OR skip). Fixes: - admin credentials were never collected or sent to the API - mode was hardcoded to EDTECH - contract/signerName were collected but never transmitted - WhatsApp is now integrated but fully optional (configurable later) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bccc5b6 -
feat(meta-status): sync daily limit + quality rating live from Meta phone number API
CognxSafeTrack +1: Claude Sonnet 4.6fetchMetaStatus now calls GET /{phoneNumberId}?fields=messaging_limit_tier,quality_rating to get the real tier from Meta (TIER_1K, TIER_10K, TIER_100K, UNLIMITED) instead of a hardcoded value inferred from WABA status. Frontend: TIER_LABELS map for human-readable labels, QualityDot badge (green/amber/red) displayed next to the limit. dailyLimitLabel now uses the real tier from the API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8aa43f4 -
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 -
fix(meta-status): split combined Meta API call + fix business badge for test WABAs
CognxSafeTrack +1: Claude Sonnet 4.6Split `account_review_status,business{...}` into two independent calls so test WABAs (which forbid the `business` field) no longer poison WABA status. Business verification is now optional/non-fatal (wrapped in try/catch). BusinessBadge and BusinessVerificationCell now show "—" with neutral styling when `businessId` is undefined (field inaccessible) instead of misleading "Non vérifiée" amber warning + "Vérifier →" link. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7e2166c
-
feat(whatsapp-setup): direct config mode for platform-owner accounts
CognxSafeTrack +1: Claude Sonnet 4.6Backend: - accessToken now optional in /whatsapp-setup — falls back to WHATSAPP_ACCESS_TOKEN env var (for platform-owner self-setup) Frontend: - "Reconfigurer WhatsApp" button now opens a choice modal instead of launching Embedded Signup directly - Option A (Direct): enter WABA ID + optional token — for accounts already configured on Meta (token from env var used if field left empty) - Option B (Embedded Signup): Facebook login popup — for new client accounts - Phone Number ID pre-filled from existing DB record - Auto-refreshes Meta status after successful save Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2f67731 -
fix(admin): show Reconfigurer WhatsApp when phone exists but token/wabaId missing
CognxSafeTrack +1: Claude Sonnet 4.6Orgs migrated from single-tenant setup have a WhatsAppPhoneNumber record but no wabaId/systemUserToken in Organization table. Without the token the Meta status endpoint returns configured:false and WABA shows "Non connecté". When fetchMetaStatus returns configured:false on an org that already has a phone number, replace the "En ligne" indicator with an amber "Reconfigurer WhatsApp" button that re-triggers the Embedded Signup flow to store the correct wabaId and long-lived token. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4f87bfb -
feat(meta): live Meta verification status + WhatsApp setup fixes
CognxSafeTrack +1: Claude Sonnet 4.6- GET /v1/organizations/:id/meta-status — fetches WABA account_review_status and business verification_status live from Meta Graph API, cached 1h in Redis - POST /v1/organizations/:id/meta-status/refresh — force-invalidates the cache - ClientsManagementView: replaced static metaVerificationStatus field with live per-org Meta status (WABA badge, Business badge, derived daily limit) - launchEmbeddedSignup: fixed race condition — now waits for both the OAuth code (FB.login) and WABA/phone IDs (WA_EMBEDDED_SIGNUP_EVENT) before resolving - /whatsapp-setup: exchanges OAuth code for long-lived Meta token (60 days) before storing; bypasses exchange if token already starts with EAA - OnboardingWizard: removed broken WhatsApp step (3 steps: welcome, legal, AI) - OrganizationSchema: removed non-existent DB fields (contractSigned, contractSignedAt, contractSignerName, metaVerificationStatus, dailyMessageLimit) that caused prisma.organization.create() to throw Unknown arg at runtime Re…bd9eb5b -
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
-
chore: update locale files
CognxSafeTrackc4ab07f -
feat: wire i18n to all remaining admin pages
CognxSafeTrack +1: Claude Sonnet 4.6AIAgentSetup, AnalyticsPage, CampaignHistoryPage, ContactsPage, KnowledgeBasePage, LiveFeed, TrackDaysPage, TrackFormPage, TrackListPage, TrainingLab now use useTranslation() throughout. STATUS_CONFIG labels migrated to labelKey pattern to stay compatible with the hook-only call site. Removed all fr-FR locale hardcoding in toLocaleDateString/toLocaleString calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6b2ad5a -
feat: wire i18n to dashboard, settings, users — complete locale files
CognxSafeTrack +1: Claude Sonnet 4.6DashboardPage, SettingsPage, UserListPage now use useTranslation(). fr/es/pt locale files expanded with dashboard, analytics, users, contacts, settings, crm, knowledge sections. Sidebar was already translated; main content pages now follow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ab43d7b -
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
-
feat: implement bulk whatsapp campaigns with BullMQ and modular activation refactor (isCrmActive/isEdTechActive)
CognxSafeTracke286845 -
fix: stabilize speech recognition logic and ignore aborted error
CognxSafeTrack5634afc -
feat: implement real-time streaming transcription using Web Speech API
CognxSafeTrack4fd3a34 -
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 RoleGuard for centralized authorization
CognxSafeTrack- Created reusable RoleGuard component - Refactored MainLayout to use RoleGuard for admin features - Reduced manual role checks in the UI layout803f4c5 -
style: standardize frontend imports using @/ alias
CognxSafeTrack- Updated App.tsx, MainLayout.tsx, and core pages (Dashboard, CRM) - Standardized library imports in tenant.tsx and main.tsx - Improved codebase consistency by eliminating deep relative paths1ef1cda -
refactor: extract shell and sidebar to MainLayout
CognxSafeTrack- Improved component modularity by separating layout from routing - Cleaned up App.tsx (removed unused imports and complex UI logic) - Standardized navigation and organization selection in a dedicated Layout2c400a5 -
feat: implement premium animated smart chips in CRM Dashboard chat UI
CognxSafeTrack2f133f7