-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild_report_v3_pt.py
More file actions
774 lines (674 loc) · 33.7 KB
/
Copy pathbuild_report_v3_pt.py
File metadata and controls
774 lines (674 loc) · 33.7 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
"""Build Portuguese version of GEM ATS demo deliverable report — V3-PT."""
import os
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
BASE = r"C:\Users\adm_r\Clients\GEM-BOOM"
OUT = os.path.join(BASE, "GEM_ATS_Relatorio_Entrega_PT.docx")
IMG_DIR = os.path.join(BASE, "evidence_bordered")
doc = Document()
# Styles
style = doc.styles['Normal']
font = style.font
font.name = 'Calibri'
font.size = Pt(10)
def add_heading_styled(text, level=1):
h = doc.add_heading(text, level=level)
for run in h.runs:
run.font.color.rgb = RGBColor(0x1A, 0x1A, 0x2E)
return h
def add_goal_quote(text):
p = doc.add_paragraph()
p.paragraph_format.left_indent = Inches(0.3)
p.paragraph_format.space_before = Pt(6)
p.paragraph_format.space_after = Pt(4)
run = p.add_run(f'"{text}"')
run.font.italic = True
run.font.size = Pt(10)
run.font.color.rgb = RGBColor(0x55, 0x55, 0x55)
return p
def add_body(text):
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(6)
run = p.add_run(text)
run.font.size = Pt(10)
return p
def add_image(filename, width=6.0):
path = os.path.join(IMG_DIR, filename)
if os.path.exists(path):
doc.add_picture(path, width=Inches(width))
last = doc.paragraphs[-1]
last.alignment = WD_ALIGN_PARAGRAPH.CENTER
last.paragraph_format.space_after = Pt(8)
else:
p = doc.add_paragraph(f"[Imagem nao encontrada: {filename}]")
for run in p.runs:
run.font.color.rgb = RGBColor(0xFF, 0x00, 0x00)
print(f"AVISO: Imagem faltando: {filename}")
def add_click_path(text):
p = doc.add_paragraph()
run = p.add_run("Caminho no sistema: ")
run.font.bold = True
run.font.size = Pt(9)
run.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
run2 = p.add_run(text)
run2.font.size = Pt(9)
run2.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
p.paragraph_format.space_before = Pt(0)
p.paragraph_format.space_after = Pt(12)
def add_separator():
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(4)
p.paragraph_format.space_after = Pt(4)
run = p.add_run("\u2500" * 80)
run.font.size = Pt(6)
run.font.color.rgb = RGBColor(0xCC, 0xCC, 0xCC)
# ================================================================
# CAPA
# ================================================================
title = doc.add_heading('GEM ATS Demo \u2014 Relat\u00f3rio de Verifica\u00e7\u00e3o de Entregas', level=0)
for run in title.runs:
run.font.color.rgb = RGBColor(0x1A, 0x1A, 0x2E)
p = doc.add_paragraph()
run = p.add_run(
"Cliente: TestBox | Plataforma: GEM (www.gem.com) | Data: 8 de Fevereiro de 2026\n"
)
run.font.size = Pt(10)
run.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
run2 = p.add_run(
"Org: TestBox (thiago@testbox.com) | Ambiente: Somente ATS (sem depend\u00eancias CRM)"
)
run2.font.size = Pt(10)
run2.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
p2 = doc.add_paragraph()
run3 = p2.add_run("Status: TODAS AS 6 VALUE STORIES \u2014 CONFIGURADAS E VERIFICADAS")
run3.font.bold = True
run3.font.size = Pt(12)
run3.font.color.rgb = RGBColor(0x00, 0x7A, 0x33)
p2.paragraph_format.space_after = Pt(12)
p3 = doc.add_paragraph()
stats = (
"359 candidatos \u2022 9 vagas \u2022 7 fontes \u2022 "
"5 contrata\u00e7\u00f5es \u2022 31 screenshots \u2022 Zero depend\u00eancias CRM"
)
run4 = p3.add_run(stats)
run4.font.size = Pt(10)
run4.font.bold = True
p3.paragraph_format.space_after = Pt(8)
# Disclaimer
p_disc = doc.add_paragraph()
p_disc.paragraph_format.left_indent = Inches(0.3)
p_disc.paragraph_format.space_before = Pt(4)
p_disc.paragraph_format.space_after = Pt(12)
run_disc = p_disc.add_run(
"Nota: Este ambiente cont\u00e9m dados sint\u00e9ticos criados para fins de demonstra\u00e7\u00e3o. "
"Todos os nomes de candidatos, empresas e informa\u00e7\u00f5es de contato s\u00e3o fict\u00edcios. "
"Os volumes de pipeline e distribui\u00e7\u00f5es de etapas foram desenhados para demonstrar "
"fluxos t\u00edpicos de ATS em escala. Limita\u00e7\u00f5es conhecidas est\u00e3o documentadas no ap\u00eandice."
)
run_disc.font.italic = True
run_disc.font.size = Pt(9)
run_disc.font.color.rgb = RGBColor(0x88, 0x88, 0x88)
# ================================================================
# SUMARIO
# ================================================================
add_heading_styled("Sum\u00e1rio", level=1)
toc_items = [
"VS1 \u2014 Revis\u00e3o de Candidaturas com IA para Alto Volume",
"VS2 \u2014 Agendamento de Entrevistas em Escala",
"VS3 \u2014 Colabora\u00e7\u00e3o do Time de Contrata\u00e7\u00e3o e Experi\u00eancia do Candidato",
"VS4 \u2014 Visibilidade Executiva (Headcount / Sa\u00fade do Pipeline)",
"VS5 \u2014 Otimiza\u00e7\u00e3o de ROI de Fontes e Fornecedores",
"VS6 \u2014 Redescoberta de Talentos no ATS",
"Resumo da Auditoria",
"Ap\u00eandice: Limita\u00e7\u00f5es Conhecidas",
]
for i, item in enumerate(toc_items, 1):
p = doc.add_paragraph()
run = p.add_run(f"{i}. {item}")
run.font.size = Pt(10)
p.paragraph_format.space_before = Pt(1)
p.paragraph_format.space_after = Pt(1)
doc.add_page_break()
# ================================================================
# VS1: REVISAO DE CANDIDATURAS COM IA
# ================================================================
add_heading_styled("VS1 \u2014 Revis\u00e3o de Candidaturas com IA para Alto Volume", level=1)
add_heading_styled("Objetivo", level=2)
add_goal_quote("Mostrar recrutadores fazendo triagem eficiente de grandes volumes de candidaturas")
add_body(
'A vaga de Software Engineer tem 210 candidatos ativos (232 no total incluindo rejeitados) '
'com 139 esperando em Revis\u00e3o de Candidaturas. O bot\u00e3o "Start reviews (139)" na lista de '
"vagas abre uma interface de triagem com 3 pain\u00e9is: painel esquerdo lista candidatos, "
"centro mostra perfil/curr\u00edculo, painel direito tem informa\u00e7\u00f5es do candidato + a\u00e7\u00f5es."
)
add_image("VS1_D1_high_volume_210_candidates.png")
add_click_path('ATS > Jobs > Software Engineer (R1) > "Start reviews (139)"')
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("Vaga \u2192 Candidaturas \u2192 Fluxo de Revis\u00e3o")
add_body(
'A interface de revis\u00e3o mostra abas "Para revisar (139)" e "Revisados (0)". '
'O cabe\u00e7alho diz "Reviewing Software Engineer (ID: R1) in Application review". '
"Visualizador de curr\u00edculo com zoom/download. Aba de Perfil com Experi\u00eancia/Educa\u00e7\u00e3o."
)
add_image("VS1_D1_review_workflow_3panel.png")
add_click_path("ATS > Jobs > Software Engineer > Start reviews (139)")
add_goal_quote("Palavras-chave e Filtros")
add_body(
"O bot\u00e3o Keywords abre um modal com busca por palavras no curr\u00edculo, salvar/carregar "
'palavras-chave, e op\u00e7\u00f5es de filtro (1+ palavra / nenhuma / todas). Barra de busca: "Search '
'resumes (ex: excel AND accounting)". Filtro de fonte mostra 7 fontes com contagem de candidatos. '
"Filtros adicionais: Indica\u00e7\u00f5es (20), Contatados anteriormente (29), Visualizados (1), "
'Rejeitados recentemente, M\u00faltiplas candidaturas, Triados anteriormente. Bot\u00e3o "Ativar '
'ranking por IA" no cabe\u00e7alho da revis\u00e3o.'
)
add_image("VS1_D1_keywords_filter_modal.png")
add_image("VS1_D5_source_filter_7sources.png")
add_click_path('Dentro da revis\u00e3o > bot\u00e3o "Keywords" | dropdown "Source"')
add_goal_quote("Iniciar revis\u00f5es")
add_body(
'Cada vaga aberta mostra "Start reviews (N)" na lista de vagas. '
"Tamb\u00e9m acess\u00edvel pela p\u00e1gina de detalhes da vaga e dentro da vis\u00e3o de cards do pipeline."
)
add_image("VS1_D1_jobs_list_start_reviews.png")
add_goal_quote("Revis\u00e3o do perfil do candidato")
add_body(
"Perfis enriquecidos de candidatos incluem Experi\u00eancia, Educa\u00e7\u00e3o, empresa, cargo, "
"faculdade, localiza\u00e7\u00e3o, certifica\u00e7\u00f5es e links do LinkedIn. Abaixo: Mia Brown mostrando "
"6+ anos de experi\u00eancia (Data Scientist na Meta, ML Engineer no Google), Mestrado pelo MIT, "
"lembrete ativo e detalhes da candidatura."
)
add_image("vs3_candidate_profile_mia_brown.png")
add_click_path("ATS > Candidates > clicar no nome do candidato > aba Perfil")
add_goal_quote("Decis\u00f5es de avan\u00e7ar/rejeitar")
add_body(
'Bot\u00e3o verde "Avan\u00e7ar para Phone Screen" com dropdown para sele\u00e7\u00e3o de etapa. '
'Bot\u00e3o vermelho "Rejeitar com mensagem" com op\u00e7\u00f5es. Dropdown de etapa no cabe\u00e7alho: '
"Revis\u00e3o de candidatura \u2192 Phone Screen \u2192 Onsite \u2192 Oferta (4 etapas naveg\u00e1veis). "
"Setas esquerda/direita para navegar entre candidatos."
)
add_image("VS1_D1_stage_selector_dropdown.png")
add_goal_quote("Transi\u00e7\u00e3o para etapas de entrevista")
add_body(
"O bot\u00e3o Avan\u00e7ar move candidatos para Phone Screen (57 j\u00e1 est\u00e3o l\u00e1). "
"Plano de entrevista configurado: Phone Screen (30 min), Entrevista T\u00e9cnica (60 min), "
"Culture Fit (45 min). Pipeline completo em 4 etapas + resultado Contratado: "
"139 \u2192 57 \u2192 13 \u2192 1 oferta ativa \u2192 2 contratados."
)
add_image("VS1_D1_full_pipeline_all_stages.png")
add_click_path("Job > Talent pipeline > Card view > Stages: All")
# Dados Sinteticos
add_heading_styled("Dados Sint\u00e9ticos", level=2)
add_goal_quote(
"Vaga de alto volume com muitas candidaturas em diferentes n\u00edveis de qualidade"
)
add_body(
"Software Engineer: 210 ativos / 232 total. Candidatos variam de perfis b\u00e1sicos "
"at\u00e9 candidatos enriquecidos (Marcus Chen \u2013 Sr SW Eng na Stripe, "
"Mia Brown \u2013 Data Scientist na Meta com 6+ anos Meta/Google). Funil realista: "
"139 \u2192 57 \u2192 13 \u2192 1 oferta ativa \u2192 2 contratados. "
"6 vagas abertas para compara\u00e7\u00e3o."
)
add_goal_quote("Curr\u00edculos e anexos realistas")
add_body(
"Todo candidato tem um Curr\u00edculo Gerado. Marcus Chen tem curr\u00edculo PDF enviado "
"(via indica\u00e7\u00e3o). Visualizador de PDF integrado com zoom e download."
)
add_goal_quote("Tags e campos do candidato usados para filtragem")
add_body(
"7 fontes em 4 tipos: LinkedIn, Indeed, Github (Sourced); "
"LinkedIn Basic Jobs, Work at a Startup (Job board externo); "
"Indica\u00e7\u00e3o direta (Referral); Site de carreiras da empresa (Career site). "
"Campos enriquecidos: empresa, cargo, faculdade, localiza\u00e7\u00e3o, links LinkedIn. "
"1\u20134 notas internas por candidato principal."
)
add_goal_quote("Candidaturas distribu\u00eddas entre etapas")
add_body(
"4 etapas do pipeline + resultado Contratado: Revis\u00e3o (139) \u2192 "
"Phone Screen (57) \u2192 Onsite (13) \u2192 Oferta (1) \u2192 Contratado (2). "
"Funil realista com volume decrescente em cada etapa de sele\u00e7\u00e3o."
)
doc.add_page_break()
# ================================================================
# VS2: AGENDAMENTO DE ENTREVISTAS
# ================================================================
add_heading_styled("VS2 \u2014 Agendamento de Entrevistas em Escala", level=1)
add_heading_styled("Objetivo", level=2)
add_goal_quote(
"Demonstrar agendamento em volume \u2014 gest\u00e3o de fila, balanceamento de carga "
"de entrevistadores, solicita\u00e7\u00f5es de disponibilidade"
)
add_body(
"A Fila de Agendamento tem 154 candidatos em 7 p\u00e1ginas. 9 entrevistadores listados "
"com distribui\u00e7\u00e3o de carga. 1 entrevista agendada (Leila Robinson \u2013 "
"11 de Fev \u2013 Entrevista T\u00e9cnica Presencial). Programa de treinamento configurado "
"para integra\u00e7\u00e3o de novos entrevistadores."
)
add_image("VS2_D2_scheduling_queue_154.png")
add_click_path("Scheduling > Scheduling Queue")
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("Fila de agendamento com candidatos aguardando")
add_body(
"154 candidatos na fila com colunas: Candidato, Status, Vaga, Etapa, "
'Data(s) da entrevista. Bot\u00e3o "Solicitar disponibilidade" em cada card. '
"7 p\u00e1ginas de candidatos para agendar."
)
add_goal_quote("Gest\u00e3o de entrevistadores e balanceamento de carga")
add_body(
"9 membros na p\u00e1gina de Entrevistadores com email, treinamentos e tags."
)
add_image("VS2_D2_interviewers_9_members.png")
add_click_path("Scheduling > Interviewers")
add_goal_quote("Plano de entrevista por vaga (etapas, dura\u00e7\u00f5es, pain\u00e9is)")
add_body(
"Cada vaga tem plano de entrevista configurado: Phone Screen (30 min), Entrevista "
"T\u00e9cnica (60 min), Culture Fit (45 min). Vis\u00edvel na p\u00e1gina de detalhes da vaga "
"na aba Plano de Entrevista."
)
add_goal_quote("P\u00e1gina Minhas Entrevistas (pr\u00f3ximas + scorecards completados)")
add_body(
"Minhas Entrevistas mostra 1 pr\u00f3xima: Leila Robinson \u2013 11 de Fev \u2013 "
"Entrevista T\u00e9cnica Presencial \u2013 Product Manager R4. "
"1 scorecard submetido com recomenda\u00e7\u00e3o: Sim."
)
add_image("VS2_D2_my_interviews_upcoming.png")
add_click_path("ATS > My Interviews")
add_goal_quote("Programas de Treinamento para integra\u00e7\u00e3o de entrevistadores")
add_body(
'1 programa: "Entrevista T\u00e9cnica" com fases Shadow (2 sess\u00f5es) e '
"Reverse Shadow (1 sess\u00e3o). Colunas: Elegibilidade, Treinandos, "
"Formados, Fases de treinamento."
)
add_image("VS2_D2_training_programs.png")
add_click_path("Scheduling > Training Programs")
doc.add_page_break()
# ================================================================
# VS3: COLABORACAO DO TIME
# ================================================================
add_heading_styled(
"VS3 \u2014 Colabora\u00e7\u00e3o do Time de Contrata\u00e7\u00e3o e Experi\u00eancia do Candidato", level=1
)
add_heading_styled("Objetivo", level=2)
add_goal_quote(
"Mostrar scorecards, feedback estruturado e prontid\u00e3o para debrief"
)
add_body(
"13+ candidatos t\u00eam notas internas (1\u20134 cada) com capacidade de @men\u00e7\u00e3o. "
"Template de scorecard configurado e 1 scorecard submetido (Leila Robinson: "
'recomenda\u00e7\u00e3o "Sim"). 3 templates de respostas padr\u00e3o para comunica\u00e7\u00e3o '
"com candidatos. Template de carta-oferta com 3 ofertas ativas em rascunho. "
"4 lembretes configurados. 2 solicita\u00e7\u00f5es de revis\u00e3o entre membros do time."
)
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("Notas internas com @men\u00e7\u00f5es nos perfis dos candidatos")
add_body(
"O Feed de Atividades nos perfis dos candidatos mostra hist\u00f3rico cronol\u00f3gico de "
"todas as intera\u00e7\u00f5es: notas, emails, mudan\u00e7as de etapa, scorecards e candidaturas. "
"Abaixo: Feed de Atividades da Mia Brown com 4 entradas incluindo feedback detalhado "
"de entrevista, contexto de indica\u00e7\u00e3o e uma nota privada sobre discuss\u00f5es salariais."
)
add_image("vs3_activity_feed_mia_brown.png")
add_click_path("ATS > Candidates > Mia Brown > aba Feed de Atividades")
add_body(
'Se\u00e7\u00e3o de Notas em cada perfil com placeholder "@mencione algu\u00e9m para notific\u00e1-lo". '
"Toggle privado para notas sens\u00edveis. Bot\u00e3o Publicar. "
"Badges de contagem de notas vis\u00edveis nos cards dos candidatos (1\u20134 por candidato)."
)
add_goal_quote("Scorecard submetido com feedback estruturado")
add_body(
"Abaixo: etapa Onsite da Leila Robinson mostrando scorecard submetido pelo "
"Thiago Rodrigues com recomenda\u00e7\u00e3o \u201cSim\u201d na Entrevista T\u00e9cnica, "
"e entrevista de Culture Fit do Gabriel Taufer aguardando feedback. "
"Isso demonstra coordena\u00e7\u00e3o de painel com m\u00faltiplos entrevistadores."
)
add_image("vs3_scorecard_submitted.png")
add_click_path("ATS > My Interviews > Leila Robinson > painel da etapa Onsite")
add_goal_quote("Templates de scorecard para feedback estruturado")
add_body(
'"Technical Interview Scorecard" (Publicado). Escala de avalia\u00e7\u00e3o '
'personaliz\u00e1vel via bot\u00e3o "Personalizar avalia\u00e7\u00f5es do scorecard".'
)
add_image("vs3_scorecard_template.png")
add_click_path("Templates > Interviews & scheduling > Scorecards")
add_goal_quote("Templates de entrevista para processo padronizado")
add_body(
'"Technical Phone Screen" (Publicado, 45 min). '
"Vinculado aos planos de entrevista das vagas para avalia\u00e7\u00e3o consistente."
)
add_image("vs3_interview_template.png")
add_click_path("Templates > Interviews & scheduling > Interviews")
add_goal_quote("Respostas padr\u00e3o para comunica\u00e7\u00e3o com candidatos")
add_body(
"3 respostas padr\u00e3o configuradas com campos de personaliza\u00e7\u00e3o:\n"
'\u2022 "Interview Scheduling" \u2014 agendar entrevista com tokens {{first_name}} e {{job_opening}}\n'
'\u2022 "Application Received" \u2014 confirma\u00e7\u00e3o de recebimento da candidatura\n'
'\u2022 "Rejection \u2013 General" \u2014 rejei\u00e7\u00e3o padr\u00e3o com tom profissional'
)
add_image("vs3_canned_responses.png")
add_click_path("Templates > Messages > Canned responses")
add_goal_quote("Templates de carta-oferta")
add_body(
'"Standard Offer Letter" (Ativo, criado em 8 de Fev de 2026). '
"Template download\u00e1vel com configura\u00e7\u00f5es de oferta. "
"3 ofertas em rascunho ativas: $165K (SW Eng), $145K (UX Designer), $185K (DevOps). "
"Todas em San Francisco."
)
add_image("vs3_offer_letter_template.png")
add_click_path("Templates > Offers > Offer letters")
add_goal_quote("Lembretes para acompanhamento")
add_body(
"4 lembretes configurados: 1 vencendo hoje (Marcus Chen \u2014 \u201cRevisar "
"candidatura por indica\u00e7\u00e3o e agendar phone screen\u201d), 3 futuros (incluindo "
"Mia Brown \u2014 \u201cAcompanhar aceita\u00e7\u00e3o da oferta \u2014 oferta concorrente do Google de "
"$180K\u201d, vence 12 de Fev). P\u00e1gina de Tarefas mostra Lembretes (1 Vencido)."
)
add_goal_quote("Solicita\u00e7\u00f5es de revis\u00e3o entre membros do time")
add_body(
"2 solicita\u00e7\u00f5es enviadas: Drew Regitsky + Nick Bushak \u2192 Gabriel Taufer. "
"Permite feedback entre pares antes de decis\u00f5es cr\u00edticas de contrata\u00e7\u00e3o."
)
# Card do candidato com badges
add_heading_styled("Contexto do Card do Candidato", level=2)
add_body(
"Vis\u00e3o de cards do pipeline mostra badges de contagem de notas. Abaixo: "
"Mia Brown na etapa Oferta com badge de 4 notas internas, atribui\u00e7\u00e3o de fonte "
'(LinkedIn), e status "Oferta precisa ser enviada".'
)
add_image("VS1_D3_offer_stage_mia_brown.png")
doc.add_page_break()
# ================================================================
# VS4: VISIBILIDADE EXECUTIVA
# ================================================================
add_heading_styled(
"VS4 \u2014 Visibilidade Executiva (Headcount / Sa\u00fade do Pipeline)",
level=1,
)
add_heading_styled("Objetivo", level=2)
add_goal_quote(
"Dar aos stakeholders executivos visibilidade em tempo real sobre sa\u00fade do pipeline, "
"acompanhamento de headcount e progresso de contrata\u00e7\u00f5es"
)
add_body(
"2 dashboards com widgets de KPI ao vivo. Pipeline Analytics com funil completo: "
"425 \u2192 165 (39%) \u2192 52 (32%) \u2192 12 (23%) \u2192 5 (42%). "
"4 relat\u00f3rios pr\u00e9-constru\u00eddos. 8 vagas acompanhadas em 4 estados de ciclo de vida."
)
add_image("VS4_D4_recruiting_health_kpis.png")
add_click_path('Talent Compass > Dashboards > "Recruiting health"')
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("Dashboards com KPIs de recrutamento")
add_body(
'"Recruiting health" (favoritado): Total contratados = 5, '
"Tempo m\u00e9dio = 1 dia, Vagas abertas = 6. Se\u00e7\u00f5es: Vis\u00e3o geral, "
"Por recrutador, Por escrit\u00f3rio, KPIs, Indica\u00e7\u00f5es, M\u00e9tricas de pipeline. "
'"Hiring Overview Q1 2026" tamb\u00e9m dispon\u00edvel.'
)
add_image("VS4_D4_dashboards_list.png")
add_goal_quote("Pipeline Analytics com visualiza\u00e7\u00e3o de funil")
add_body(
"Gr\u00e1fico de funil completo: 425 \u2192 165 (39%) \u2192 52 (32%) \u2192 12 (23%) "
"\u2192 5 (42%). Detalhamento por vaga para todas as 6 vagas abertas."
)
add_image("VS4_D4_pipeline_analytics_funnel.png")
add_body(
"Taxas de passagem por etapa no dashboard: 7% sai da Revis\u00e3o, "
"100% Phone Screen, 100% Onsite, 100% Oferta."
)
add_image("VS4_D4_passthrough_rates.png")
add_click_path("Talent Compass > Pipeline Analytics")
add_goal_quote(
"Relat\u00f3rios (Taxa de Contrata\u00e7\u00e3o, Motivos de Rejei\u00e7\u00e3o, Atividade do Recrutador, Tempo de Contrata\u00e7\u00e3o)"
)
add_body(
"4 relat\u00f3rios dispon\u00edveis: Taxa de Contrata\u00e7\u00e3o por Fonte, Motivos de Rejei\u00e7\u00e3o, "
"Atividade do Recrutador, Tempo de Contrata\u00e7\u00e3o por Departamento."
)
add_image("VS4_D4_reports_4_prebuilt.png")
add_click_path("Talent Compass > Reports")
add_goal_quote("Vagas / acompanhamento de headcount")
add_body(
"8 vagas em 4 estados: Aberta (1), Rascunho (1), Preenchida (5), "
"Fechada/n\u00e3o preenchida (1)."
)
add_image("VS4_D4_openings_open_draft.png")
add_body(
"Vagas preenchidas mostram candidato designado: OP1 SW Eng \u2192 Sophia Brown, "
"OP2 SW Eng \u2192 Charlotte Miller, OP3 PM \u2192 Emma Nakamura, "
"OP5 UX \u2192 Kenji Thompson, OP6 DevOps \u2192 Andrew Moore."
)
add_image("VS4_D4_openings_filled_headcount.png")
add_click_path("ATS > Openings > alternar entre abas Aberta, Rascunho, Fechada")
doc.add_page_break()
# ================================================================
# VS5: ROI DE FONTES
# ================================================================
add_heading_styled("VS5 \u2014 Otimiza\u00e7\u00e3o de ROI de Fontes e Fornecedores", level=1)
add_heading_styled("Objetivo", level=2)
add_goal_quote(
"Ajudar opera\u00e7\u00f5es de recrutamento a medir e otimizar gastos em fontes e job boards"
)
add_body(
"Calculadora de ROI totalmente populada: US$2.127 custo total, "
'US$7/candidatura, US$532/contrata\u00e7\u00e3o. Gr\u00e1ficos "Menor custo por contrata\u00e7\u00e3o" e '
'"Maior custo total". Bot\u00e3o "Gerenciar despesas" para entrada de custos.'
)
add_image("VS5_D5_roi_calculator_full.png")
add_click_path("Talent Compass > ROI Calculator")
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("Calculadora de ROI com custo por contrata\u00e7\u00e3o e por candidatura")
add_body(
"Detalhamento por fonte:\n"
"\u2022 LinkedIn (Sourced): US$532, 141 candidaturas, US$4/cand., 3 contratados, US$177/contrata\u00e7\u00e3o\n"
"\u2022 Indeed (Sourced): US$266, 65 candidaturas, US$4/cand.\n"
"\u2022 Github (Sourced): US$53, 23 candidaturas, US$2/cand.\n"
"\u2022 LinkedIn Basic Jobs (Externo): US$128, 39 cand., US$3/cand., 1 contratado, US$128/contrata\u00e7\u00e3o\n"
"\u2022 Work at a Startup (Externo): US$85, 24 cand., US$4/cand.\n"
"\u2022 Indica\u00e7\u00e3o direta: 61 cand., 1 contratado (org\u00e2nico \u2014 sem custo)\n"
"\u2022 Site de carreiras: 72 cand. (org\u00e2nico \u2014 sem custo)\n\n"
"Total: US$2.127 em 292 candidaturas atribu\u00eddas (de 425 total). "
"Geral: US$7/cand., US$532/contrata\u00e7\u00e3o (4 contrata\u00e7\u00f5es com atribui\u00e7\u00e3o de custo)."
)
add_goal_quote("Distribui\u00e7\u00e3o de fontes e acompanhamento de efic\u00e1cia")
add_body(
"7 fontes distintas vis\u00edveis no filtro de fonte da revis\u00e3o e nos cards dos candidatos. "
"4 tipos de fonte: Sourced, Job board externo, Indica\u00e7\u00e3o, Site de carreiras. "
"Coluna de fonte na vis\u00e3o de tabela do pipeline. Pipeline Analytics mostra convers\u00e3o fonte-a-contrata\u00e7\u00e3o."
)
doc.add_page_break()
# ================================================================
# VS6: REDESCOBERTA DE TALENTOS
# ================================================================
add_heading_styled("VS6 \u2014 Redescoberta de Talentos no ATS", level=1)
add_heading_styled("Objetivo", level=2)
add_goal_quote(
"Permitir que recrutadores redescubram candidatos anteriores \u2014 silver medalists, "
"talentos j\u00e1 triados, candidatos anteriores"
)
add_body(
"P\u00e1gina de Candidatos mostra 359 candidatos pesquis\u00e1veis com filtros. "
'3 pastas curadas incluindo "Silver Medalists \u2013 Vagas Futuras" (2 itens). '
"Busca de curr\u00edculo com operadores booleanos. Vis\u00f5es Card/Compacta/Tabela. "
"Candidatos enriquecidos com hist\u00f3rico profissional completo para avalia\u00e7\u00e3o r\u00e1pida."
)
add_image("VS6_D6_candidates_359_all_stages.png")
add_click_path("ATS > Candidates")
add_heading_styled("Funcionalidades ATS", level=2)
add_goal_quote("P\u00e1gina de candidatos com base pesquis\u00e1vel")
add_body(
'"Mostrando 251 de 359 candidatos" com filtragem baseada em atividade (\u00faltimos 45 dias). '
"Filtrar por Status, Filtrar por Marcos, bot\u00e3o Adicionar filtro. "
'"Mostrar candidatos rejeitados". Vis\u00f5es Card, Compacta e Tabela.'
)
add_goal_quote("Pastas para organizar pools de talentos")
add_body(
"3 pastas:\n"
"\u2022 Top Engineering Candidates (3 itens) \u2014 lista curada dos melhores talentos t\u00e9cnicos\n"
"\u2022 Q1 2026 Hiring Pipeline (3 itens) \u2014 candidatos priorit\u00e1rios para o trimestre atual\n"
"\u2022 Silver Medalists \u2013 Vagas Futuras (2 itens) \u2014 candidatos fortes n\u00e3o selecionados "
"para a vaga original, marcados para oportunidades futuras"
)
add_image("VS6_D6_folders_silver_medalists.png")
add_click_path("Home > Folders")
add_goal_quote("Busca de curr\u00edculo e filtros para redescoberta")
add_body(
'Busca de curr\u00edculo: "Search resumes (ex: excel AND accounting)" na interface de revis\u00e3o. '
"Filtros: Contatados anteriormente (29), Triados anteriormente, M\u00faltiplas candidaturas, Fonte, "
"Indica\u00e7\u00f5es (20), Rejeitados recentemente, Visualizados. Op\u00e7\u00f5es de ordena\u00e7\u00e3o. A\u00e7\u00e3o em massa."
)
add_goal_quote("Perfis enriquecidos para avalia\u00e7\u00e3o de candidatos")
add_body(
"Candidatos principais com perfis completos para avalia\u00e7\u00e3o r\u00e1pida de redescoberta:\n"
"\u2022 Marcus Chen \u2014 Sr Software Engineer na Stripe, certifica\u00e7\u00f5es AWS/Oracle\n"
"\u2022 Mia Brown \u2014 Data Scientist na Meta (ant. Google), Mestrado MIT em Ci\u00eancia da Computa\u00e7\u00e3o\n"
"\u2022 Charlotte Miller \u2014 Software Engineer na Airbnb\n"
"\u2022 Sophia Brown \u2014 Full Stack Developer na Adobe\n"
"\u2022 Ella Johnson \u2014 UX Designer na Uber\n"
"\u2022 Matthew Robinson \u2014 UX Designer na Meta\n"
"\u2022 Ava Taylor \u2014 Data Scientist na Salesforce\n"
"\u2022 Harper Davis \u2014 QA Engineer na Zoom\n\n"
"Links do LinkedIn nos cards. Vis\u00e3o de tabela do pipeline "
"com colunas empresa, cargo e etapa."
)
add_image("VS6_D6_pipeline_table_enriched.png")
add_click_path("Jobs > Software Engineer > Talent pipeline > Table view")
add_heading_styled("Cen\u00e1rio de Redescoberta", level=2)
add_body(
"Exemplo de fluxo de trabalho:\n"
"1. Recrutador abre a pasta Silver Medalists e encontra um candidato que chegou "
"at\u00e9 Onsite para Software Engineer mas n\u00e3o foi selecionado.\n"
"2. Com a nova vaga de Sr Software Engineer agora ativa, o recrutador visualiza "
"o hist\u00f3rico de candidaturas anteriores e as notas internas do painel de "
"entrevistas anterior.\n"
"3. O recrutador adiciona o candidato ao novo pipeline da vaga usando "
"\u201cCriar nova candidatura\u201d no perfil do candidato.\n"
"4. O candidato \u00e9 agendado para Phone Screen via Fila de Agendamento "
"\u2014 tudo dentro do ATS, sem sequ\u00eancias CRM ou campanhas de outreach.\n\n"
"Funcionalidades ATS de suporte: filtros Triados anteriormente e M\u00faltiplas candidaturas "
"no fluxo de revis\u00e3o identificam candidatos adicionais com engajamento pr\u00e9vio. "
"O Feed de Atividades preserva o hist\u00f3rico completo de intera\u00e7\u00f5es entre candidaturas."
)
doc.add_page_break()
# ================================================================
# RESUMO DA AUDITORIA
# ================================================================
add_heading_styled("Resumo da Auditoria", level=1)
# Tabela resumo
table = doc.add_table(rows=7, cols=3)
table.style = "Light Shading Accent 1"
headers = ["Value Story", "Status", "Evid\u00eancia Principal"]
for i, h in enumerate(headers):
table.rows[0].cells[i].text = h
for p in table.rows[0].cells[i].paragraphs:
for r in p.runs:
r.font.bold = True
r.font.size = Pt(9)
data = [
(
"VS1: Revis\u00e3o de Candidaturas com IA",
"VERIFICADO",
"210 candidatos ativos, 139 em revis\u00e3o, 7 fontes, filtros, pipeline completo",
),
(
"VS2: Agendamento de Entrevistas",
"VERIFICADO",
"154 na fila, 9 entrevistadores, 1 agendada, programa de treinamento, planos de entrevista",
),
(
"VS3: Colabora\u00e7\u00e3o do Time",
"VERIFICADO",
"13+ notas, 1 scorecard submetido, 3 respostas padr\u00e3o, template de oferta, 4 lembretes",
),
(
"VS4: Visibilidade Executiva",
"VERIFICADO",
"2 dashboards, funil 425\u21925, 8 vagas (4 estados), 4 relat\u00f3rios",
),
(
"VS5: ROI de Fontes e Fornecedores",
"VERIFICADO",
"US$2.127 total, 7 fontes em 4 tipos, custo por contrata\u00e7\u00e3o, gr\u00e1ficos ROI",
),
(
"VS6: Redescoberta de Talentos",
"VERIFICADO",
"359 candidatos, 3 pastas com Silver Medalists, busca de curr\u00edculo, perfis enriquecidos",
),
]
for i, (vs, status, evidence) in enumerate(data):
row = table.rows[i + 1]
row.cells[0].text = vs
row.cells[1].text = status
row.cells[2].text = evidence
for cell in row.cells:
for p in cell.paragraphs:
for r in p.runs:
r.font.size = Pt(9)
p_end = doc.add_paragraph()
p_end.paragraph_format.space_before = Pt(16)
run_end = p_end.add_run(
"Todas as 6 value stories configuradas e verificadas. "
"Ambiente de demonstra\u00e7\u00e3o pronto para apresenta\u00e7\u00e3o ao cliente."
)
run_end.font.bold = True
run_end.font.size = Pt(11)
doc.add_page_break()
# ================================================================
# APENDICE: LIMITACOES CONHECIDAS
# ================================================================
add_heading_styled("Ap\u00eandice: Limita\u00e7\u00f5es Conhecidas", level=1)
add_body(
"As seguintes s\u00e3o limita\u00e7\u00f5es de dados conhecidas inerentes ao ambiente de demonstra\u00e7\u00e3o "
"sint\u00e9tico. Est\u00e3o documentadas no SOW (se\u00e7\u00f5es 6.0 e 7.0) "
"e n\u00e3o afetam a completude funcional das 6 value stories."
)
add_heading_styled("Tempo M\u00e9dio de Contrata\u00e7\u00e3o (KPI)", level=2)
add_body(
"O tempo m\u00e9dio de contrata\u00e7\u00e3o mostra 1 dia (vs benchmark de 44 dias) porque "
"todos os candidatos sint\u00e9ticos foram processados em uma \u00fanica sess\u00e3o. Os timestamps "
"de transi\u00e7\u00e3o de etapa n\u00e3o podem ser retroagidos at\u00e9 a engenharia do Gem entregar "
"o endpoint comprometido. Uma vez dispon\u00edvel, este KPI refletir\u00e1 tempos realistas."
)
add_heading_styled("Taxas de Passagem do Dashboard", level=2)
add_body(
"As taxas de passagem do dashboard (7%, 100%, 100%, 100%) v\u00eam de um widget de "
"janela de tempo recente. Os 100% nas etapas intermedi\u00e1rias s\u00e3o um artefato do "
"processamento em lote: todos os candidatos foram movidos entre etapas em uma \u00fanica "
"sess\u00e3o. O funil do Pipeline Analytics (39%, 32%, 23%, 42%) mostra "
"convers\u00e3o acumulada e \u00e9 a m\u00e9trica oficial."
)
add_heading_styled("Mapeamento de Fontes na Calculadora de ROI", level=2)
add_body(
"A Calculadora de ROI do GEM casa automaticamente despesas com tipos de fonte. Algumas "
'entradas aparecem como "(tipo de fonte n\u00e3o encontrado)" quando o GEM n\u00e3o consegue '
"resolver o mapeamento. Essas entradas n\u00e3o mapeadas representam US$1.063 dos US$2.127 totais. "
"As m\u00e9tricas por fonte (US$4/cand. LinkedIn, US$2/cand. Github, etc.) s\u00e3o "
"calculadas pelo GEM usando apenas as por\u00e7\u00f5es mapeadas."
)
add_heading_styled("Contagem de Fontes no Filtro", level=2)
add_body(
"As contagens no dropdown de filtro de fonte (LinkedIn 29, Career site 23, "
"Indeed 13, Indica\u00e7\u00e3o direta 13, LinkedIn Basic Jobs 11, Work at a Startup 7, "
"Github 4 = 100) refletem candidatos com atribui\u00e7\u00e3o de fonte na fila de "
"revis\u00e3o atual. Os 39 restantes dos 139 candidatos n\u00e3o t\u00eam fonte atribu\u00edda."
)
add_heading_styled("Volume de Scorecards", level=2)
add_body(
"1 scorecard submetido (Thiago Rodrigues \u2192 Leila Robinson, "
"recomenda\u00e7\u00e3o: Sim). Scorecards adicionais com avalia\u00e7\u00f5es variadas (Sim Forte "
"/ N\u00e3o / Talvez) requerem mais entrevistas completadas, que dependem de "
"configura\u00e7\u00e3o de integra\u00e7\u00e3o com calend\u00e1rio. O template de scorecard e o fluxo de "
"submiss\u00e3o s\u00e3o totalmente funcionais."
)
add_heading_styled("Experi\u00eancia/Educa\u00e7\u00e3o dos Candidatos", level=2)
add_body(
"Campos de Experi\u00eancia e Educa\u00e7\u00e3o est\u00e3o populados nos candidatos enriquecidos "
"(Mia Brown, Charlotte Miller, Sophia Brown, etc.) via dados de perfil do GEM. "
"Alguns candidatos mostram \u201cSem hist\u00f3rico profissional dispon\u00edvel\u201d porque o GEM "
"busca esses dados de perfis do LinkedIn, que nem sempre est\u00e3o totalmente sincronizados "
"no ambiente TestBox."
)
# Save
doc.save(OUT)
print(f"Relatorio salvo: {OUT}")
print(f"Total de imagens em evidence_bordered: {len(os.listdir(IMG_DIR))}")