Abimael Torcate Claude commited on
Commit
2e30dbb
·
1 Parent(s): 3d7739f

Fix PostgreSQL compatibility in get_comprehensive_analysis_data

Browse files

- Replace complex CTE with separate simple queries
- Eliminate potential window function conflicts
- Split data retrieval into basic process data and interactions
- Combine results in Python for better PostgreSQL compatibility
- Maintain same functionality with improved database compatibility
- Should resolve aggregate function calls cannot contain window function calls error

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (1) hide show
  1. utils/database.py +57 -62
utils/database.py CHANGED
@@ -530,75 +530,70 @@ def get_comprehensive_analysis_data():
530
  """Retorna dados completos para análise com IA"""
531
  with get_db_connection() as conn:
532
  with conn.cursor(cursor_factory=RealDictCursor) as cur:
533
- # Dados gerais dos processos
534
  cur.execute("""
535
- WITH checklist_progress AS (
536
- SELECT
537
- c.id,
538
- c.numero_processo,
539
- c.created_at,
540
- COUNT(ci.id) as total_items,
541
- COUNT(CASE WHEN cis.is_checked THEN 1 END) as completed_items,
542
- CASE
543
- WHEN COUNT(ci.id) > 0 THEN
544
- ROUND((COUNT(CASE WHEN cis.is_checked THEN 1 END)::decimal / COUNT(ci.id)) * 100, 1)
545
- ELSE 0
546
- END as progress_percentage
547
- FROM checklists c
548
- LEFT JOIN checklist_items ci ON c.id = ci.checklist_id
549
- LEFT JOIN current_item_states cis ON ci.id = cis.item_id
550
- WHERE c.numero_processo IS NOT NULL
551
- GROUP BY c.id, c.numero_processo, c.created_at
552
- ),
553
- process_stats AS (
554
- SELECT
555
- cp.numero_processo,
556
- COUNT(cp.id) as total_checklists,
557
- MIN(cp.created_at) as process_start_date,
558
- MAX(cp.created_at) as latest_checklist_date,
559
- SUM(cp.total_items) as total_items,
560
- SUM(cp.completed_items) as completed_items,
561
- ROUND(AVG(cp.progress_percentage), 1) as avg_progress_percentage,
562
- COUNT(ii.id) as total_interactions,
563
- MIN(ii.timestamp) as first_interaction,
564
- MAX(ii.timestamp) as last_interaction,
565
- CURRENT_DATE - MIN(cp.created_at)::date as days_elapsed,
566
- (MIN(cp.created_at) + INTERVAL '180 days')::date - CURRENT_DATE as days_remaining_to_deadline
567
- FROM checklist_progress cp
568
- LEFT JOIN item_interactions ii ON cp.id = ii.checklist_id
569
- GROUP BY cp.numero_processo
570
- )
571
  SELECT
572
- numero_processo,
573
- total_checklists,
574
- process_start_date,
575
- latest_checklist_date,
576
- total_items,
577
- completed_items,
578
- avg_progress_percentage,
579
- total_interactions,
580
- first_interaction,
581
- last_interaction,
582
- days_elapsed,
583
- days_remaining_to_deadline,
584
- CASE
585
- WHEN avg_progress_percentage = 100 THEN 'CONCLUIDO'
586
- WHEN days_remaining_to_deadline < 0 THEN 'ATRASADO'
587
- WHEN days_remaining_to_deadline < 30 THEN 'EM_RISCO'
588
- ELSE 'NO_PRAZO'
589
- END as status_prazo,
590
  CASE
591
- WHEN days_elapsed > 0 AND avg_progress_percentage > 0 THEN
592
- ROUND((avg_progress_percentage / days_elapsed) * (100 - avg_progress_percentage), 0)
593
- ELSE NULL
594
- END as projected_days_to_complete
595
- FROM process_stats
 
 
 
 
 
 
596
  ORDER BY days_remaining_to_deadline ASC
597
  """)
598
 
599
- process_data = cur.fetchall()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
600
 
601
- # Estatísticas globais
602
  cur.execute("""
603
  SELECT
604
  COUNT(DISTINCT c.id) as total_checklists_global,
 
530
  """Retorna dados completos para análise com IA"""
531
  with get_db_connection() as conn:
532
  with conn.cursor(cursor_factory=RealDictCursor) as cur:
533
+ # Primeira query: dados básicos dos processos
534
  cur.execute("""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  SELECT
536
+ c.numero_processo,
537
+ COUNT(DISTINCT c.id) as total_checklists,
538
+ MIN(c.created_at) as process_start_date,
539
+ MAX(c.created_at) as latest_checklist_date,
540
+ COUNT(ci.id) as total_items,
541
+ COUNT(CASE WHEN cis.is_checked THEN 1 END) as completed_items,
 
 
 
 
 
 
 
 
 
 
 
 
542
  CASE
543
+ WHEN COUNT(ci.id) > 0 THEN
544
+ ROUND((COUNT(CASE WHEN cis.is_checked THEN 1 END)::decimal / COUNT(ci.id)) * 100, 1)
545
+ ELSE 0
546
+ END as avg_progress_percentage,
547
+ CURRENT_DATE - MIN(c.created_at)::date as days_elapsed,
548
+ (MIN(c.created_at) + INTERVAL '180 days')::date - CURRENT_DATE as days_remaining_to_deadline
549
+ FROM checklists c
550
+ LEFT JOIN checklist_items ci ON c.id = ci.checklist_id
551
+ LEFT JOIN current_item_states cis ON ci.id = cis.item_id
552
+ WHERE c.numero_processo IS NOT NULL
553
+ GROUP BY c.numero_processo
554
  ORDER BY days_remaining_to_deadline ASC
555
  """)
556
 
557
+ basic_process_data = cur.fetchall()
558
+
559
+ # Segunda query: dados de interações por processo
560
+ process_data = []
561
+ for process in basic_process_data:
562
+ cur.execute("""
563
+ SELECT
564
+ COUNT(ii.id) as total_interactions,
565
+ MIN(ii.timestamp) as first_interaction,
566
+ MAX(ii.timestamp) as last_interaction
567
+ FROM checklists c
568
+ LEFT JOIN item_interactions ii ON c.id = ii.checklist_id
569
+ WHERE c.numero_processo = %s
570
+ """, (process['numero_processo'],))
571
+
572
+ interaction_data = cur.fetchone()
573
+
574
+ # Combinar dados
575
+ combined_process = dict(process)
576
+ combined_process.update(interaction_data)
577
+
578
+ # Adicionar campos calculados
579
+ combined_process['status_prazo'] = (
580
+ 'CONCLUIDO' if combined_process['avg_progress_percentage'] == 100
581
+ else 'ATRASADO' if combined_process['days_remaining_to_deadline'] < 0
582
+ else 'EM_RISCO' if combined_process['days_remaining_to_deadline'] < 30
583
+ else 'NO_PRAZO'
584
+ )
585
+
586
+ if combined_process['days_elapsed'] > 0 and combined_process['avg_progress_percentage'] > 0:
587
+ combined_process['projected_days_to_complete'] = round(
588
+ (combined_process['avg_progress_percentage'] / combined_process['days_elapsed']) *
589
+ (100 - combined_process['avg_progress_percentage'])
590
+ )
591
+ else:
592
+ combined_process['projected_days_to_complete'] = None
593
+
594
+ process_data.append(combined_process)
595
 
596
+ # Estatísticas globais - query simples
597
  cur.execute("""
598
  SELECT
599
  COUNT(DISTINCT c.id) as total_checklists_global,