695401f237
- Reemplaza Netlify Functions con servidor Python/Flask (server.py) - Adapta dashboard para contar tickets en lugar de Story Points - Conecta al proyecto IO (Infra) de Jira - Elimina secciones de QA y Code Review - Agrega métricas de solicitudes semanales y reporters - Excluye devs inactivos y unifica nombres duplicados Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""
|
|
debug_fields.py — Lista todas las personas asignadas en el proyecto
|
|
"""
|
|
|
|
import requests
|
|
import base64
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
email = os.getenv('JIRA_EMAIL')
|
|
token = os.getenv('JIRA_TOKEN')
|
|
host = os.getenv('JIRA_HOST', 'invera.atlassian.net')
|
|
project = os.getenv('JIRA_PROJECT', 'Infra')
|
|
|
|
credentials = base64.b64encode(f"{email}:{token}".encode()).decode()
|
|
headers = { 'Authorization': f'Basic {credentials}', 'Accept': 'application/json' }
|
|
|
|
print(f"🔍 Conectando a {host} — Proyecto: {project}\n")
|
|
|
|
jql = f'project = {project} AND issuetype not in (Epic, "Sub-task", Subtask) AND created >= "2026-01-01" ORDER BY updated DESC'
|
|
url = f"https://{host}/rest/api/3/search/jql?jql={requests.utils.quote(jql)}&maxResults=500&fields=summary,status,assignee"
|
|
res = requests.get(url, headers=headers)
|
|
|
|
if not res.ok:
|
|
print(f"❌ Error {res.status_code}: {res.text[:300]}")
|
|
exit(1)
|
|
|
|
issues = res.json().get('issues', [])
|
|
print(f" → {len(issues)} tickets obtenidos\n")
|
|
|
|
assignees = {}
|
|
for issue in issues:
|
|
f = issue['fields']
|
|
name = (f.get('assignee') or {}).get('displayName', 'Sin asignar')
|
|
status_cat = (f.get('status') or {}).get('statusCategory', {}).get('key', '')
|
|
if name not in assignees:
|
|
assignees[name] = {'done': 0, 'pending': 0}
|
|
if status_cat == 'done':
|
|
assignees[name]['done'] += 1
|
|
else:
|
|
assignees[name]['pending'] += 1
|
|
|
|
print(f"{'─'*60}")
|
|
print(f"👥 TODAS LAS PERSONAS — {project} (desde 2026-01-01):")
|
|
print(f"{'─'*60}")
|
|
for name, counts in sorted(assignees.items()):
|
|
print(f" {name:35s} → {counts['done']:2} finalizados | {counts['pending']:2} pendientes")
|
|
print(f"{'─'*60}")
|