chore(rxp): prep rxp_patches for evocrm rc6#117
Open
dvlexp wants to merge 43 commits into
Open
Conversation
websocket-client>=1.9 required by local skills/tools. Lock regenerated after merging origin/main; pulls in flask-limiter (rate-limit on public share endpoint, evolution-foundation#52), limits, wrapt, ordered-set, deprecated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
terminal_proxy.py fechava a ponte WS quando client_ws.receive(timeout=30) retornava None — mas None é timeout, não desconexão (disconexão real levanta ConnectionClosed). Em abas em background o ping de 25s do AgentChat é throttled pelo navegador para <1×/min, batendo o timeout e derrubando o WS com o peer ainda vivo. Como o frontend não tinha auto-reconnect, wsRef.current ficava apontando para um socket fechado e sendMessage() retornava em silêncio — sintoma do "clico enviar e nada acontece" relatado pelos usuários. Backend: continue em vez de break no receive timeout. Disconexões reais seguem caindo no except → finally normalmente. Frontend: useEffect refatorado para função connect() reusável, com backoff 1s→30s acionado no onclose. Ping interval virou per-WS (localPing) para que o onclose de uma WS antiga não limpe o ping da nova durante reconnects encadeados. wsRef agora é zerado no onclose para evitar sends em socket morto. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Antes: scrollToBottom() forçava scrollTop = scrollHeight em todo render/ delta, então o usuário não conseguia rolar pra cima pra ler histórico — a próxima mensagem (ou cada chunk de stream) jogava ele de volta no fundo. Agora: isAtBottomRef rastreia se o usuário está perto do fundo (<50px). Se ele rolou pra cima, scrollToBottom() vira no-op e aparece um botão flutuante "Ir para o final" que reativa o follow ao clicar. Mandar nova mensagem ou re-enviar (edit/rewind) força a flag de volta a true porque é sinal claro de "quero ver o resultado". History restore (session_joined, chat_history) também força true — abrindo a sessão você sempre cai no fundo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nder
3 unrelated reliability fixes accumulated in AgentChat.tsx:
1. Scroll race: under heavy streaming (60+ deltas/sec) the scrollToBottom
rAF could fire before the user's onScroll propagated, leaving
isAtBottomRef stale and teleporting them back to bottom. Now we
recompute distance-from-bottom inside the rAF callback and update the
flag proactively if the user moved away.
2. Heartbeat timeout: track lastPongAt on every server pong. The ws lib
can leave half-open sockets (TCP dead, no close frame), so onclose
never fires and chat_event stops silently. The interval now also
checks for stale pongs and forces a reconnect.
3. Defensive blocks render: msg.blocks could be undefined for assistant
messages mid-stream or from legacy formats, crashing
.map/.some/.filter and triggering the ErrorBoundary ("Unable to load
dashboard section"). Fixed in 3 sites: getMessageText (line 771),
blocks rendering (1278), streaming hasVisibleContent check (1292).
Bug 3 was breaking the entire /agents/<name> page for every agent with
chat history — reported today on clawdia-assistant but not specific.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
TTL fix (RXP 2026-05-18): default was 24h in both server.js and session-store.js, deleting Daniel's conversations every night. Override via TERMINAL_SESSION_TTL_HOURS env still works. Bind fix: listen on '::' (IPv6 wildcard, dual-stack) instead of '0.0.0.0' so clients connecting via IPv6 (Tailscale, modern browsers) reach the server. IPv4 still served via the dual-stack mapping. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ents Replaced legacy scope set (instagram_basic + content_publish + publish_video) with the Meta Graph v18+ recommended set: - pages_show_list - pages_read_engagement - instagram_manage_insights - instagram_manage_comments Older scopes were rejected by the new Meta app review flow. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Provides sns_sms.py for SMS send (single + bulk via CSV), sandbox verification, and account status. Credentials loaded from .env (IAM user evonexus, SNSFullAccess + SESFullAccess). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ML frontmatter as flags fix(chat): make ticket picker filter optional when agent slug is empty Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ents Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… fixes - workspace.py: skip symlinks pointing outside REPO_ROOT to prevent traversal of large external directories (timeouts / multi-MB responses) - Workspace.tsx: add DirectoryView component — click-through folder browsing inside the file panel - ConfirmDialog.tsx: auto-cancel pending dialog on route navigation - FileTree.tsx: auto-expand when selectedPath equals node.path exactly (not only when it is a prefix) - uv.lock: regenerate after websocket-client bump Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Endpoint POST /api/aurora/bot-control?action=pause|unpause receives EvoCRM automation webhook payloads and toggles Aurora's pause state via Partenon API. Integrated with EvoCRM automations (aurora-pausar / aurora-retomar labels) to give agents a one-click way to silence and resume the Aurora n8n bot per conversation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… MCP - Remove dynamic context block that called `gog calendar events --today` - Drop `allowed-tools: Bash(gog:*)` and `compatibility: gog CLI` frontmatter - Add MCP integration note pointing to `mcp__claude_ai_Google_Calendar__*` tools - Bump version 1.0 → 1.1 The gog CLI is deprecated; the Google Calendar MCP is always available and requires no CLI setup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap `claude` invocation with `sh -c "PATH=$HOME/.bun/bin:$PATH exec claude ..."` - Ensures `claude` binary is found when bun is not on the default system PATH Without this, `make telegram` would fail silently when the screen session's environment lacks the bun bin directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…compare - Add /api/aurora/bot-control to PUBLIC_PATHS so it bypasses JWT middleware - Migrate auth from X-Aurora-Secret header to ?secret= query param (embedded directly in EvoCRM automation webhook URLs) - Replace string equality check with secrets.compare_digest (timing-safe) - Make secret mandatory: falls back to hardcoded default if env var unset - Add inline comment identifying CHATWOOT_ACCOUNT_ID=99 as Aurora's account Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… skills New ADW routines: - ADWs/routines/fin_email_monitor.py — monitors financial emails (Nubank/Asaas) - ADWs/routines/vps_health.py — daily health check across 6 VPS instances New skills: - .claude/skills/fin-email-monitor/ — skill wrapper for financial email monitoring - .claude/skills/int-kommo/ — Kommo CRM integration skill with scripts - .claude/skills/video-edit/ — video editing skill (assets, config, models, templates) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fin-email-monitor - weekly_review.py (single mode): append instruction to send Telegram summary on completion (5-8 lines: wins, pending items, next week, financial highlights) - fin_email_monitor.py: flip notify_telegram from False → True Closes the feedback loop so Daniel receives proactive digests via Telegram after each routine run without needing to open the dashboard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Patch 20 — ConditionsFilterService query_operator (bug 20) EvoAI CRM stores query_operator on the RECEIVING condition (leading format) but upstream code appended it TRAILING, producing invalid SQL: "assignee_id IN (:v0) NOT EXISTS(...)" -> PG::SyntaxError missing AND. All 11,574 AutomationRuleRun records were no_match due to this silent error. Fix: override build_query_string to extract q_op and prepend it. Patch 21 — PermissionFilterService nil user (PR #143, bug 21) Service-token callers (evo-ai-processor) never set Current.user, causing NoMethodError on nil.role -> 500 on GET /contacts/:id/conversations, breaking transfer_to_human. Patch 22 — LabelConcern 204->200 (PR #145, bug 22) LabelConcern#index and #create had no render call, returning 204 No Content. manage_conversation_labels saw empty body -> concluded 0 labels -> deleted ALL labels including atendimento_ia on every AI update. index.html — right-click fix v3 v2 blocked all contextmenu events globally (broke label/agent menu). v3 allows contextmenu to propagate so Radix menu opens, but absorbs the first pointerup that follows, preventing auto-selection of Priority Low. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the Kiwify post-sale orchestrator that replaces 4 n8n RXP flows (KOMMOSYNC, WHATSAPP, MAUTIC, DIRECTUS) with a single Python pipeline triggered by /api/kiwify/webhook. Pipeline runs 4 sub-steps in order (EvoCRM sync, WhatsApp confirm, Mautic tag, Directus provision) with idempotency via kiwify_post_sale_runs table and structured Telegram notifications on success/failure. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…utils Adds shared backend helpers consumed by the Kiwify post-sale pipeline, the EvoHub→Kommo Nogueira bridge, and Aurora recovery routines: - integrations/aurora_db.py: PostgreSQL client for Aurora schema - integrations/cnpja_office.py: CNPJ lookup against CNPJa Office API - integrations/kommo_nogueira.py: typed client for the Nogueira Kommo - utils/email.py: email normalization helpers - utils/phone.py: BR phone parsing/normalization helpers - migrations/aurora_recovery_attempts.sql: schema for recovery tracking Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the EvoHub→Kommo bridge route that mirrors WhatsApp messages received in EvoHub (Nogueira) as private notes on the matching Kommo lead. Idempotency is guaranteed by the new evohub_kommo_bridge_events table (UNIQUE on conversation_id + message_id). Bridge is exposed at os.nogueiraresolve.com.br and waits for webhook registration once the WABA channel is connected. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug 20 v1 prepended qop unconditionally, causing PG::SyntaxError "syntax error at or near 'AND'" for single-condition rules where @query_string is still empty when the first condition is processed. Fix: only prepend qop when @query_string is not empty. Verified: 0 errors in automation_rule_runs over last 24h, "Criação de Oportunidade Aurora" now returning matched correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…6-06-20)
Block untracked working-tree paths that contain PII or ad-hoc operational
scripts that should never enter the repo:
- /logs, /projects, /meetings, /finance, /daily-logs, /community,
/courses, /social, /strategy — personal/client data dirs
- /scripts/aurora_recovery, /scripts/test — local ad-hoc tooling
- /scripts/routines/aurora_company_enrichment{,_vps}.py and
/scripts/routines/rxp_outbound_*.py — RXP-specific routines that
carry credentials in env and should not be tracked here
- *.pkl and yolov8n.pt — model/weights binaries
- /))}* and /=1.9' — bash-escape junk files in working tree
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…OK_SECRET, remove hardcoded fallback Both secrets are XMACNA-side (Partenon API at labs.xmacna.ai and the webhook auth secret shared with EvoCRM automations). Hardcoded fallbacks in source mean the live values are versioned. Switch to os.environ[X] so import fails fast if the env var is missing — no silent fallback to a known-leaked literal. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…emove hardcoded fallbacks aurora_db.py used os.environ.get(..., DEFAULT) for all 7 transport settings (host, port, user, key path, container, pg user, pg db). The defaults carried the live RXP VPS IP, port, ssh key path, and the exact Docker Swarm container name — versioning production topology. Switch to os.environ[X] so import fails fast if any of the 7 RXP_* env vars is missing. Operational impact: callers (kiwify_webhook.py, kiwify_post_sale/*) now require RXP_SSH_HOST, RXP_SSH_PORT, RXP_SSH_USER, RXP_SSH_KEY, RXP_PG_CONTAINER, RXP_PG_USER, RXP_PG_DB in .env. To be populated together with credential rotation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ove hardcoded fallback Account ID 35241960 was versioned as a default literal. Although not a secret by itself, hardcoding any per-client identifier is a smell that makes it easier for a misconfigured environment to silently target the wrong Kommo account. Switch to os.environ[X] — fail fast on import. NOGUEIRA_KOMMO_BASE_URL keeps its default (public URL, not sensitive). NOGUEIRA_KOMMO_TOKEN keeps "" default (already gated by send check). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…oded fallback Chat ID 8860803037 (Daniel's personal Telegram chat) was hardcoded as fallback in Settings.load(). Use req() so missing TELEGRAM_CHAT_ID fails fast instead of silently routing notifications to a fixed chat. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a 2-layer secret-scanning setup to prevent recurrence of the 2026-06-20 leak (9 credentials found in tracked source by Vault audit): 1. .gitleaks.toml — extends the upstream gitleaks default ruleset with EvoNexus-specific patterns identified in the audit: - Meta Graph access tokens (EAA prefix) - Stripe live keys - KIWIFY_*/WABA_*/DIRECTUS_*/EVOCRM_*/RXP_PG_* secret assignments - AURORA_WEBHOOK_SECRET, PARTENON_SECRET literals - JWT triples, GitHub PATs, Claude MCP tokens, Bearer literals Regex tuned to require *_TOKEN/_SECRET/_KEY/_PASSWORD suffix so that public IDs (pipeline UUIDs, inbox IDs, template names) do not trigger false positives. 2. scripts/git-hooks/pre-commit + install.sh — drop-in git hook that runs `gitleaks protect --staged` against every commit. Installed manually via `bash scripts/git-hooks/install.sh` (core.hooksPath is set locally, blocking the python pre-commit framework's auto- install). Hook is permissive when gitleaks is absent (warns) so it never fully blocks development environments without the binary. 3. .pre-commit-config.yaml — optional config for the upstream pre-commit framework when core.hooksPath is unset. Validation: `gitleaks detect` against the full git history found 7 known historical leaks (PARTENON_SECRET, Kommo SKILL.md sample tokens, Bearer literals, etc.) at the SHAs flagged by the Vault audit. These will be scrubbed in the upcoming git-filter-repo pass. The hook correctly does NOT flag the four EVO_CRM_*_ID public UUIDs in scripts/routines/kiwify_post_sale/config.py (refined regex). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Canonical secrets policy at docs/secrets-policy.md, written after the 2026-06-20 leak (9 credentials found in tracked source by Vault). Codifies five hard rules for every engineering agent: 1. Never hardcode credentials — use os.environ[X] bracket access, never os.getenv(..., "literal-default") 2. Never commit .env (or any .env.* variant) 3. Run gitleaks before opening a PR (pre-commit hook handles staging) 4. Brain Repo deny-list (workspace/data, workspace/audit, raw chat logs, anything matching .gitleaks.toml) 5. Fork-network awareness: a commit pushed to a fork of a public repo leaks the secret to the upstream's object DB even if the fork is private. Rotation is the only durable fix; filter-repo + GitHub support only reduces the window. Includes the incident workflow (rotate first, audit second, add regex to .gitleaks.toml so the class is blocked next time). Originally intended location was .claude/rules/secrets-policy.md but that directory is read-only in this environment. The doc is referenced from the engineering agents' workflow via docs/ instead. Will move to .claude/rules/ when access permits. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…:FilterService filter_keys.yml doesn't include assignee_type, causing InvalidAttribute (400) when frontend filter modal sends assignee_type=[me/assigned/unassigned/all]. Override build_condition_query to intercept assignee_type before delegating to the original method, mapping values to proper SQL clauses. Verified on VPS: me=30, assigned=183, unassigned=154 conversations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The real root cause was _o() in ChatPage-BV93Mg_x.js missing a case for "assignee_type" -- the filter value was silently discarded. jo() routes single assignee_type filters to GET /conversations, so _o() must emit ?assignee_type=value for ConversationFinder to pick it up. Frontend fix applied directly to bind-mounted bundle on VPS: /opt/evocrm-patches/assets/ChatPage-BV93Mg_x.js -- added case"assignee_type":r.length===1&&(e.assignee_type=r[0]);break Backend patch (Bug 23) still valid for multi-filter POST scenarios. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EvoGo implemented a LID->JID swap: Sender = JID, SenderAlt = LID. determine_source_id used SenderAlt unconditionally, storing @lid as contact_inbox source_id and contact.identifier. Frontend could not parse @lid as phone number -> "sem canal" in UI. set_contact_for_outgoing also failed to match outgoing echo messages since identifier stored LID while Chat field was JID. Fix: if SenderAlt contains @lid, fall back to JID-derived phone_number for source_id and identifier. Patches determine_source_id, build_contact_attributes, update_contact_information. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ntact labels)
Three root causes blocking all Puma threads (3-5s per request with 873 items):
1. PipelineItem#days_in_current_stage called stage_movements.order(:created_at).last
which adds ORDER BY and bypasses the preloaded association scope -- one query per item.
Fix: sort in-memory with max_by(&:created_at) when association(:stage_movements).loaded?
2. Lead-based pipeline items (contact_id direct, no conversation) were not covered by
the conversation:[:contact] includes path -- one contact query per lead item.
Fix: add { contact: [:labels, {avatar_attachment: :blob}] } at the top-level includes.
3. ContactSerializer.serialize called Label.find_by(title:) per tag (no batch), and
contact.labels fired one taggings JOIN query per contact.
Fix: preload :labels in includes (batch taggings+tags), load all Label records into
labels_by_title hash once per request, thread-local to ContactSerializer which uses
the hash directly instead of Label.find_by.
Result: ~5584 queries for 873 items -> ~70 queries (98% reduction).
WebSocket pings no longer time out -> ActionCable RoomChannel stays connected ->
filter state is not reset on navigation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: send_template_message silently returned nil when processable_channel_message_template returned name.blank? (no template available), without updating message status to :failed. Fix: prepend SendOnWhatsappService#send_template_message to call StatusUpdateService(failed) before returning when no template is found. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: loadMoreConversations always called GET /conversations?page=N without active filters even when initial load used POST /conversations/filter. Fix applied directly to frontend JS volume: /opt/evocrm-patches/assets/ChatPage-BV93Mg_x.js - filterConversations() stores filter body in window._rxpFilterBody - getConversations() when page>1 and _rxpFilterBody set redirects to POST /conversations/filter with page, preserving all active filters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: Chatwoot integration active on evo.xmacna.ai for the aurora
WABA instance was intercepting MESSAGES_UPDATE events and routing them via
Chatwoot API (/api/v1/accounts/{uuid}/...) which returned 404 on all calls.
The standard webhook (/webhooks/whatsapp/evolution) was never called for
status updates, so all 293 outgoing messages permanently stuck at :sent.
Fix: disabled Chatwoot integration at evo.xmacna.ai via API.
All events (MESSAGES_UPDATE, MESSAGES_UPSERT, SEND_MESSAGE) now flow through
the standard webhook which the CRM already handles correctly via
EvolutionHandlers::MessagesUpdate#update_status.
Verified: manual MESSAGES_UPDATE payload updated message status sent→delivered.
Backfill: 270 messages >7d updated to :delivered; 22 recent await real webhooks.
Remove wrong patch: send_template_message guard was unreachable for aurora
because provider=evolution is in free_text_providers (can_reply? always true,
should_send_template_message always false).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…S_UPDATE aurora) Root cause definitivo: helpers.rb#raw_message_id preferia :messageId (ID interno do Prisma do evo.xmacna.ai) sobre :keyId (wamid real = source_id no CRM). find_message_by_source_id nunca encontrava a mensagem, evento era descartado silenciosamente com "Message not found for update: cmqs7...". Fix: inverter prioridade -- @raw_message[:keyId] || @raw_message[:messageId]. Seguro para messages.upsert (nenhum dos dois existe, fallback :key.id ativo). Backfill: 21 mensagens recentes (<7d) atualizadas para delivered. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vo-crm skill - Cria [C]relatorio-bug26-aurora-messages-update.md com arquitetura completa do webhook chain, 4 hipoteses descartadas, root cause com codigo, backfill SQL e comandos de diagnostico via /int-evo-crm - Atualiza [C]bug-aurora-messages-update-2026-06-30.md com root cause definitivo (v2) - Adiciona secao "Contexto Operacional: Inbox Aurora" no int-evo-crm SKILL.md com inbox ID, comportamento esperado de status, threshold de alerta (30min) e referencia ao patch Bug 26 v2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rations route - pixel-social-media: expand agent capabilities for content strategy - int-evolution-go: full client rewrite with new endpoints - int-instagram/linkedin/youtube: skill updates and client improvements - social-auth/youtube: OAuth flow fix - ADWs/runner: minor runner patch - brain_repo: secrets scanner hardening + job runner fix - routes/integrations: new integrations route (156 lines) - blog-publish: new skill scaffold - scripts/migrate_pipeline_marketing: pipeline migration utility Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove Bug 22 (LabelConcern) — rc6 upstreamou fix superior (PR #145 + EVO-1928) - Adiciona rescue NameError no Bug 25b (ContactSerializer) — proteção contra ContactPiiMasker missing (rc6 adiciona classe no #serialize) Trail analysis: workspace/development/features/rxp-4-fluxos-fix/[C]trail-rc6-diff-analysis.md Probe rc5: ContactPiiMasker retorna nil (não definido no rc5) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @dvlexp, your pull request is larger than the review limit of 150000 diff characters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
create_connection(timeout=10) is intended as a connect deadline, but websocket-client keeps it as the socket timeout for every subsequent recv(). The notifications channel (subscribe_global) is idle by design, so a 10s silence raised WebSocketTimeoutException in the upstream pump and tore the client WS down, producing a reconnect loop every ~11s (observed as repeated "GET /terminal/ws" in the access log and a "WebSocket error" in the browser console). Clear the socket timeout after connect so idle recv() blocks instead of closing. Real disconnects still surface via ConnectionClosed, and the client-side receive loop already tolerates idle the same way. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q16fE83VtCSRcJiBBTgwoo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Prepares the
rxp_patchescustomization layer for EvoCRM rc6, applied and validated in production on VPS RXP (195.200.7.36) with zero rollbacks.incoming_label_tokens; keeping our custom patch would conflict with upstream logic.rescue NameErrorin Bug 25b (ContactSerializer) — safety net for environments where the referenced constant may not be loaded at serialization time. Defensive guard, no behavior change under normal conditions.Context
workspace/development/features/rxp-4-fluxos-fix/[C]bolt-rc6-upgrade-final.mdworkspace/development/features/rxp-4-fluxos-fix/[C]trail-rc6-diff-analysis.mdTest plan
incoming_label_tokensmechanism confirmed active in rc6rescue NameError— ContactSerializer serializes correctly; guard is silent under normal load