Commit History
-
fix(audit): resolve all remaining technical debt issuesβ
CognxSafeTrackC2 - analytics SQL injection: UNION detection, ALLOWED_TABLES allowlist, remove SQL from error responses to prevent schema leakage H1/H2 - override-feedback: move organizationId validation to top of handler before any DB mutation; scope enrollment.findFirst to org H6 - UserListPage: add pagination controls (PrΓ©cΓ©dent/Suivant, 20 per page) L4 - TrackDaysPage: await load() before closing editor to prevent stale data race L5 - admin.ts: replace getOrganizationId() with req.organizationId at 3 call sites, remove now-unused import M1 - EntityResolver: replace any[] types with proper Prisma payload types (ResolvedUser/Contact/Organization/Enrollment with exact include shapes) L8 - AI command fuzzy org match: return pending_confirmation when org found by partial name match, inject orgId for unambiguous confirmation retrya888244 -
fix(security): resolve critical and high technical debt from auditβ
CognxSafeTrackCRITICAL: - Exclude passwordHash from enrollment list response (admin.ts) - Add sanitizeOrg() to strip API keys/tokens from all org GET responses - Fix CORS wildcard on SSE stream; use request origin instead - Restrict super-admin routes to SUPER_ADMIN role only (was also allowing ADMIN) - Replace all Zod .parse() with .safeParse() β proper 400s instead of 500s (ai.ts, admin.ts) HIGH: - Increase ExerciseHandler Redis dedup lock from 30s to 300s - Add take:500 to unbounded trainingData.findMany (OOM risk) - Add take limits to message/contact findMany queries - Add Redis lock in EnrollHandler to prevent duplicate enrollments (TOCTOU) - Wrap override-feedback in try/catch; return 404 on P2025 - Use atomic increment for wallet credits (was TOCTOU race condition) - Scope messages/send to requesting org (was cross-org accessible) MEDIUM: - decryptSecrets returns new object instead of mutating argument in-place - GeminiProvider.generateStructuredData now validates response with Zod schema -β¦a8e18d6 -
feat: add XAMLΓ Platform Admin super-admin interfaceβ
CognxSafeTrackWhen selectedOrgId === 'xamle-admin-org', the admin switches to a full platform management dashboard instead of the normal org layout. Backend (apps/api): - New /v1/super-admin/* routes (SUPER_ADMIN/ADMIN role required): platform stats, organizations CRUD + suspend + impersonate, cross-org users + role change, WhatsApp numbers, billing transactions + manual credits, monitoring health, AI agentic command - Fixed SQL injection in analytics text-to-SQL (UNION/DROP/comment blocking) - Removed JWT secret fallback β crashes on startup if JWT_SECRET is missing - Added ORG_ADMIN role guard to all /v1/admin/* routes Frontend (apps/admin): - SuperAdminRouter: nested routes under /platform/* - SuperAdminLayout: dark sidebar (slate-950/violet), 7 nav items - PlatformDashboard: 6 KPI cards, system health, active alerts - OrganizationsManager: searchable table, suspend/edit drawer, create modal - UsersManager: cross-org table with inline role-change - WhatsAppNumbers: all registered numbers β¦6282d86
-
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 -
fix: security hardening, real AI costs, traceId propagation & audit loggingβ
CognxSafeTrack +1: Claude Sonnet 4.6- S1: enforceOrgIsolation β organizationId always from JWT for non-SUPER_ADMIN (header ignored) - S4: auditService.log() on ORG_MODE_CHANGED, ORG_PERSONALITY_UPDATED, ORG_BYOK_KEYS_UPDATED - O1: traceId (UUID) generated at webhook, forwarded via x-trace-id header, injected into BullMQ job data, threaded through whatsapp-logic handler chain - D3: /v1/analytics/usage now aggregates real UsageEvent.costUsd + tokens (tokensIn/Out) with per-feature breakdown instead of token estimates - D4: BrandingDataSchema added to shared-types β brandingData strictly typed (logoUrl, primaryColor, orgName) instead of z.any() - A6: InboundHandler fetches user.language in parallel with org token, passes it to Whisper - A2: sendLessonDay() caches personalized lesson text in Redis 6h by (trackDayId, activity, language) - P1: sendLessonDay() parallelized β user+trackDay batched in one include, userProgress fetched in parallel - D2: ExerciseHandler Redis 30s dedup lock prevents double exercise submission Co-Aβ¦87afdf1 -
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
-
chore: stabilization, audit fixes and project synchronization
CognxSafeTrack7b0c22b
-
chore: deploy manual fixes for TS strict mode
CognxSafeTrack9b8717a -
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 final technical debt polishing (structured logs, stripe tests, and automated migrations)
CognxSafeTrack86731f4
-
feat: Premium Onboarding with Meta SDK and Technical Debt resolution
CognxSafeTrack6248bf4