Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); fix: confirm link_user contact creation by michaelmwu · Pull Request #88 · 508-dev/508-workflows · GitHub
Skip to content

fix: confirm link_user contact creation - #88

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix
Mar 2, 2026
Merged

fix: confirm link_user contact creation#88
michaelmwu merged 1 commit into
mainfrom
michaelmwu/resume-contact-fix

Conversation

@michaelmwu

@michaelmwumichaelmwu commented Mar 2, 2026

Copy link
Copy Markdown
Member

Description

This updates /upload-resume so when link_user is provided but not linked to a CRM contact, the bot shows a confirmation button before creating a new contact from resume + Discord details.
It also reuses the same create-contact view for this flow, adds payload override support for that view, and adds structured debug/audit metadata (status_code, payload keys) when contact creation fails.
Additionally, resume contact payload generation now maps email to either emailAddress or c508Email based on domain and uses a safer fallback contact name.

Related Issue

N/A

How Has This Been Tested?

  • uv run pytest tests/unit/test_crm.py
  • uv run ruff check apps/discord_bot/src/five08/discord_bot/cogs/crm.py tests/unit/test_crm.py

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced resume-to-contact creation with automatic contact name defaults
    • Improved Discord user linking integration during contact creation
    • Smarter email field mapping for resume-based contacts
  • Bug Fixes

    • Strengthened error handling and logging for contact creation failures with detailed diagnostics

@coderabbitai

coderabbitaiBot commented Mar 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes extend the CRM cog to support payload override and custom target scope when creating contacts from resumes, add four helper methods for Discord user linkage integration, and enhance resume-based contact creation with Discord linkage support and richer error handling.

Changes

Cohort / File(s)Summary
CRM Cog Implementation
apps/discord_bot/src/five08/discord_bot/cogs/crm.py
Added create_payload_override and created_target_scope parameters to ResumeCreateContactView. Introduced four new helper methods (_discord_display_name, _discord_link_fields, _fallback_contact_name_for_discord_user, _build_contact_payload_for_link_user) for Discord linkage integration. Updated confirm_create to use override payload when provided, improved contact name defaults to "Resume Candidate", enhanced email field mapping logic (c508Email vs emailAddress based on domain), and integrated Discord linkage support in upload_resume flow with richer error auditing.
CRM Tests
tests/unit/test_crm.py
Exported ResumeCreateContactView in public imports. Added three new test cases: email domain-based field selection verification, resume upload with Discord link confirmation and contact creation flow, and error logging during contact creation failures.

Sequence Diagram

sequenceDiagram
participant User as Discord User
participant Bot as Discord Bot
participant CRM as CRM Service
participant API as CRM API
participant View as Resume View
User->>Bot: Upload resume
Bot->>CRM: Check if user linked
alt User Linked
CRM->>View: Show confirmation
User->>View: Confirm create
View->>API: Create contact with payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
else User Not Linked
Bot->>CRM: Build contact payload for link
CRM->>View: Show creation prompt
User->>View: Confirm create
View->>API: Create contact with override payload
API-->>View: Contact created
View->>API: Upload resume attachment
API-->>View: Attachment uploaded
end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A resume floats down from Discord's blue sky,
New payloads override as helpers fly by,
Discord users link with a magical "other_autocreated" scope,
Contact creation flourishes—here's to fresh hope! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main change: adding confirmation before creating a contact when link_user is provided but not already linked to a CRM contact.
Docstring Coverage✅ PassedDocstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch michaelmwu/resume-contact-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 874-881: The logger.exception call currently logs the entire
create_payload (via payload=%s) which may contain PII; update the logging in the
failure path that calls logger.exception (the call using self.filename,
self.target_scope, self.inferred_contact_meta, status_code, create_payload) to
avoid emitting full payload contents—instead log a redacted shape or just the
keys and any non-sensitive summary (e.g., list(create_payload.keys()) or a dict
with sensitive fields like "email" and "discord_id" replaced with "<redacted>")
so filename, target_scope, inferred_contact_meta and status_code remain logged
but actual PII from create_payload is not.
- Around line 838-840: The code currently treats falsy values like {} as "no
override"; change the conditional in the block that sets create_payload to
explicitly check create_payload_override is not None so empty dicts are
respected as valid overrides—locate the branch around the symbol
create_payload_override and the assignment to create_payload and replace the
truthy check with an explicit "is not None" check so that create_payload =
dict(self.create_payload_override) runs when an empty dict is provided.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5910973 and 2c726f8.

📒 Files selected for processing (2)
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • tests/unit/test_crm.py

Comment on lines +838 to +840
if self.create_payload_override:
create_payload = dict(self.create_payload_override)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use an explicit None check for payload override.

Line 838 currently treats {} as “no override” and silently falls back to rebuilt payload. If override support is explicit, this should branch on is not None.

Suggested fix
- if self.create_payload_override:+ if self.create_payload_override is not None:
create_payload = dict(self.create_payload_override)
else:
create_payload = self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ifself.create_payload_override:
create_payload=dict(self.create_payload_override)
else:
ifself.create_payload_overrideisnotNone:
create_payload=dict(self.create_payload_override)
else:
create_payload=self.crm_cog._build_resume_create_contact_payload(
file_content=self.file_content
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 838 - 840,
The code currently treats falsy values like {} as "no override"; change the
conditional in the block that sets create_payload to explicitly check
create_payload_override is not None so empty dicts are respected as valid
overrides—locate the branch around the symbol create_payload_override and the
assignment to create_payload and replace the truthy check with an explicit "is
not None" check so that create_payload = dict(self.create_payload_override) runs
when an empty dict is provided.

Comment on lines +874 to +881
logger.exception(
"Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",
self.filename,
self.target_scope,
self.inferred_contact_meta,
status_code,
create_payload,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full contact payload on create failures.

Line 875 logs payload=%s, which can include email and Discord identifiers. Log keys (or a redacted shape) instead to reduce PII exposure in logs.

Suggested fix
- logger.exception(- "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload=%s",- self.filename,- self.target_scope,- self.inferred_contact_meta,- status_code,- create_payload,- )+ payload_keys = sorted(create_payload.keys()) if create_payload else None+ logger.exception(+ "Failed to create contact from resume filename=%s target_scope=%s inferred_meta=%s status_code=%s payload_keys=%s",+ self.filename,+ self.target_scope,+ self.inferred_contact_meta,+ status_code,+ payload_keys,+ )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py` around lines 874 - 881,
The logger.exception call currently logs the entire create_payload (via
payload=%s) which may contain PII; update the logging in the failure path that
calls logger.exception (the call using self.filename, self.target_scope,
self.inferred_contact_meta, status_code, create_payload) to avoid emitting full
payload contents—instead log a redacted shape or just the keys and any
non-sensitive summary (e.g., list(create_payload.keys()) or a dict with
sensitive fields like "email" and "discord_id" replaced with "<redacted>") so
filename, target_scope, inferred_contact_meta and status_code remain logged but
actual PII from create_payload is not.

@michaelmwu
michaelmwu merged commit 984b333 into mainMar 2, 2026
5 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/resume-contact-fix branch March 2, 2026 15:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@michaelmwu