File size: 7,895 Bytes
4485b7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Verify Phase 3 hits >=90% on the hardest 2 JDs (Sumo Logic + Aditya Birla)."""
import os, sys, io, pdfplumber
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')


def read_pdf(p):
    text = ''
    with pdfplumber.open(p) as pdf:
        for page in pdf.pages:
            t = page.extract_text()
            if t:
                text += t + '\n'
    return text


orig = read_pdf(r'C:\Users\Nxtwave\Desktop\resume\Saiteja_Tirunagari_Resume A 26 - Copy.pdf')

from src.resume_customizer import ResumeCustomizer, _read_docx_text
from src.ats_scorer import score_resume
from src.resume_parser import ResumeParser

rc = ResumeCustomizer.__new__(ResumeCustomizer)
rc.resume_text = orig
rc.output_dir = 'data/output/resumes/_phase3_test'
os.makedirs(rc.output_dir, exist_ok=True)
rc.fast_model_cfg = None
parser = ResumeParser.__new__(ResumeParser)
parser.pdf_path = ''
contact = parser.get_contact_info(orig)


# ── Test 1: Sumo Logic (cybersecurity, hardest case) ────────────────────────
with open('tests/fixtures/jds/sumo_logic_pm.txt', encoding='utf-8') as f:
    jd_sumo = f.read()

sumo_response = {
    'professional_summary': (
        'Strong-fit candidate for Product Manager at Sumo Logic: 5+ years of B2B SaaS PM experience '
        'directly applicable to Threat Detection and Response, AI-driven SecOps, and intuitive dashboarding. '
        'Defined product vision, strategy, and roadmap across multi-tenant platforms while collaborating '
        'with engineering, customer success, sales, and product marketing to ship features that drive customer '
        'engagement and satisfaction. Partnered with cross-functional teams on dashboard functionality, '
        'go-to-market strategies, and sales enablement materials including whitepapers, blogs, presentations, '
        'and product demos. Brought a data-driven mindset to user experience, leveraging analytics to inform '
        'product decisions and prioritize roadmap. Worked adjacent to security operations (SIEM, SOAR, XDR, '
        'threat intelligence) through cross-functional product programs and platform-level integrations.'
    ),
    'rewritten_bullets': {
        '0:0': 'Defined vision, strategy, and roadmap for the NIAT Application Portal β€” partnering with engineering, customer success, and product marketing to drive customer engagement and satisfaction across a B2B SaaS platform.',
        '0:1': 'Maintained a detailed product roadmap supported by data analysis and competitive positioning; scaled to 141,269 verified users with 97% completion rate.',
        '0:3': 'Representing the voice of the customer to engineering teams, established KPIs and prioritization decisions for dashboard performance and reliability.',
        '0:5': 'Drove A/B experiments to validate threat-detection-style hypotheses; lifted conversion from 27.37% to 63.24% via data-driven prioritization.',
        '0:8': 'Partnered with cross-functional engineering and customer success to launch an AI-driven conversation engine β€” analogous to integrating threat intelligence sources into a unified detection workflow.',
    },
    'new_bullets': {
        '0': [
            'Productized AI-powered detection workflows with engineering, partnering on dashboarding solutions that were scalable, reliable, and performant.',
            'Contributed to go-to-market strategies and sales enablement, developing whitepapers, blogs, presentations, and product demos to showcase platform capabilities.',
            'Worked adjacent to security operations programs (SIEM/SOAR/XDR contexts) through product integrations, gaining exposure to threat detection and response workflows.',
        ],
    },
    'key_achievements': [
        'Scaled product platform to 141,269 verified users',
        'Lifted A/B-tested conversion +35.87 pp via data-driven prioritization',
        'Generated 6,776 leads via AI-driven conversational workflows',
    ],
}

filepath = os.path.join(rc.output_dir, 'SumoLogic_v3.docx')
job = {'title': 'Product Manager', 'company': 'Sumo Logic', 'relevance_score': 7}
rc._write_docx(filepath, job, sumo_response, contact)
rc._inject_missing_keywords(filepath, jd_sumo)

text = _read_docx_text(filepath)
r = score_resume(text, jd_sumo)
print(f'Sumo Logic (cybersecurity): ATS {r["ats_score"]}/100 | JD-match {r["jd_match_score"]} ({r["matched_count"]}/{r["total_jd_kw"]})')
print(f'  Missing: {r["missing_kw"][:10] or "none"}')
print(f'  Penalties: {r["penalties"] or "none"}')
print(f'  Words: {r["word_count"]}')


# ── Test 2: Aditya Birla (IT-BA role, wrong vocabulary) ─────────────────────
with open('tests/fixtures/jds/aditya_birla_apm.txt', encoding='utf-8') as f:
    jd_ab = f.read()

ab_response = {
    'professional_summary': (
        'Strong-fit candidate for Associate Product Manager at Aditya Birla Capital: 5+ years of '
        'experience in requirements elicitation, FSD authoring, UAT coordination, and end-to-end IT project '
        'delivery directly applicable to this role. Gathered and analysed user requirements through stakeholder '
        'meetings, integrated user needs with existing processes, and authored Functional Specification Documents '
        'for engineering teams. Evaluated requirements with development teams to identify gaps, published gap '
        'documents with customisation/development efforts, and assisted user teams in developing comprehensive '
        'test plans. Managed project closure and ensured system stability in production through SLA-driven '
        'application support and stakeholder management.'
    ),
    'rewritten_bullets': {
        '0:0': 'Led end-to-end requirement elicitation and FSD authoring for the NIAT Application Portal β€” managing user requirement gathering, stakeholder meetings, gap documentation, UAT coordination, and project closure within scope and time constraints.',
        '0:1': 'Gathered and analysed requirements across 141,269 users; managed UAT sign-off from business groups with full documentation and production stability monitoring.',
        '0:3': 'Coordinated with user groups for requirement integration and UAT documentation; ensured systems stability in production by managing issue resolution within agreed SLAs.',
        '0:5': 'Authored FSDs and gap documents covering customisation/development efforts with cost-time impact analysis; coordinated cross-functional development and testing teams.',
    },
    'new_bullets': {
        '0': [
            'Managed requirement elicitation, FSD authoring, and UAT documentation for IT projects across scope, time, and cost constraints.',
            'Provided applications support to users; managed mechanisms to record and resolve production issues and support queries within agreed SLAs.',
            'Coordinated with stakeholders on project closure, moving approved UAT to production and ensuring system stability post-launch.',
        ],
    },
}

filepath2 = os.path.join(rc.output_dir, 'AdityaBirla_v3.docx')
job = {'title': 'Associate Product Manager', 'company': 'Aditya Birla Capital', 'relevance_score': 6}
rc._write_docx(filepath2, job, ab_response, contact)
rc._inject_missing_keywords(filepath2, jd_ab)

text = _read_docx_text(filepath2)
r = score_resume(text, jd_ab)
print(f'\nAditya Birla (IT-BA):       ATS {r["ats_score"]}/100 | JD-match {r["jd_match_score"]} ({r["matched_count"]}/{r["total_jd_kw"]})')
print(f'  Missing: {r["missing_kw"][:10] or "none"}')
print(f'  Penalties: {r["penalties"] or "none"}')
print(f'  Words: {r["word_count"]}')

# Postcondition
print('\nPostcondition: no dump footer, no Core Competencies?')
try:
    rc._assert_no_dump_footer(filepath)
    rc._assert_no_dump_footer(filepath2)
    print('  βœ“ Both files pass')
except AssertionError as e:
    print(f'  βœ— {e}')