Prompts listos para copiar y pegar en tu herramienta de IA generativa favorita. Cada uno construye, desde cero, una app funcional ya conectada a la API de SatGo.
Elige una plantilla y copia el texto completo con un clic.
Úsalo en Lovable, Claude, ChatGPT o tu asistente de código favorito, tal cual.
Genera tu API key en SatGo y úsala dentro de la app generada.
App con login propio, bóveda de RFCs (FIEL cifrada) y descarga masiva de Constancias de Situación Fiscal contra la API de SatGo, empacadas en un ZIP.
Crea una aplicación web con TanStack Start (React + TypeScript + Tailwind CSS) que sirva como herramienta para descargar constancias de situación fiscal (CSF) del SAT en batch mediante la API externa de SAT-GO.
Requisitos funcionales:
Autenticación: Implementa login y registro con email/contraseña usando Lovable Cloud (Supabase Auth). Las rutas protegidas deben estar bajo /_authenticated/, con un layout que redirija a /auth si no hay sesión. La página /auth debe tener formulario toggle entre login y registro.
Para el login muestra validaciones de usuario incorrecto, contraseña incorrecta, no registrado, etc.
Debe existir una forma tambien de recuperar la contraseña enviando un correo de verificacion y poder resetearla.
API externa: La app consume el endpoint POST https://api.sat-go.com/api/v2/Consultar/csffiel?api-version=2.0. Requiere headers RFC y Authorization (Bearer token). El body es multipart/form-data con campos: Certificado (archivo .cer), llavePrivada (archivo .key) y Contrasena. La respuesta es un PDF. El token SAT lo pega el usuario manualmente en la UI.
Proxy server: Dado que la API externa no permite CORS desde el navegador, implementa un proxy usando server functions (createServerFn) y/o server routes (createFileRoute con bloque server.handlers.POST) que reciba los datos del cliente, haga el forwarding al SAT-GO API, y devuelva el PDF o el error.
Almacenamiento seguro de credenciales: Los usuarios deben poder guardar múltiples RFCs con sus archivos .cer, .key y contraseña, correo electronico y alias Para ello:
Crea una tabla saved_rfcs en la base de datos con: id, user_id, rfc, label, cer_path, key_path, password_encrypted, created_at,email,alias
Usa un bucket privado de storage llamado csf-files para guardar los archivos .cer y .key.
La contraseña debe cifrarse con AES-GCM en el servidor usando una clave CSF_ENCRYPTION_KEY (generada como secreto del proyecto). Descifrarse solo cuando se vaya a hacer la petición a SAT-GO.
Aplica RLS (Row Level Security) para que cada usuario solo vea/modifique sus propios RFCs y archivos.
Agregar seccion llamada Credenciales con una opcion para agregar el JWT, aqui la primera vez que se ingrese el JWT, debe ejecutarse el endpoint de https://api.sat-go.com/swagger/index.html#/Users/post_api_v_version__Users_CreateKey
Aqui va un ejemplo de como se genera la key
Request:
POST /api/v1/Users/Createkey HTTP/1.1
Authorization: Bearer {TOKEN}
Reponse:
{
"key": "asdasd4fa="
}
Esto devolvera una llave que se debe guardar en una tabla protegida, esta llave al iniciar sesion debe ejecutar el endpoint> https://api.sat-go.com/swagger/index.html#/Auth/post_api_Auth_token_json que devolverá el jWT que será usado en la sesión actual.
este token deberás utilizarlo durante la sesión. Ejemplo decomo se hace:
POST /api/Auth/token-json HTTP/1.1
Content-Type: application/json
Host: api.sat-go.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 62
{
"key":"{KEY}"
}
Response:
{
"mode": "live",
"message": "OK",
"sessionId": "ec0945c8-94c5-45ce-8b9c-20e5f2813c42",
"tokens": {
"access": {
"value": "eyJhbGciOiJIUzI1NiIsI",
"cookieOptions": {
"secure": true,
"sameSite": "Lax",
"path": "/",
"expires": 1
}
},
"id": {
"value": "eyJhbGciOiJIUz0",
"cookieOptions": {
"secure": true,
"sameSite": "Lax",
"path": "/",
"expires": 1
}
},
"refresh": {
"value": "eyJhbGciOiJIUzI1",
"cookieOptions": {
"secure": true,
"sameSite": "Strict",
"path": "/",
"expires": 30
}
}
},
"nonce": "261acbc1-8709-47e4-b888-585c1a8615a5",
"redirectTo": ""
}
En la parte de login que vas a generar, debe ser descriptivo, mostras los erroes de validacion, como correo incorrecto, usuario no encontrado, contraseña incorrecta, etc, todas las validaciones deben ser visibles.
Agrega un menu con la opcion de mis rfcs:
a) Listar RFCs, buscar por RFC que contenga, no debe ser el RFC exacto
b) Una sección para agregar nuevos RFCs (input RFC, label opcional, upload .cer, upload .key, input contraseña, botón guardar).
c Permitir editar y eliminar RFCs
Funcionalidad batch de descarga:
En la página principal autenticada, muestra:
a) Una lista de RFCs guardados con checkboxes para seleccionar cuáles procesar.
Permite también agregar RFCs "ad-hoc" (sin guardar) para descargas puntuales.
Al iniciar el procesamiento, recorre todos los RFCs seleccionados (guardados y ad-hoc) y va consumiendo la API uno por uno.
Cada fila debe mostrar su estado: idle, processing, done, error.
Si alguna descarga falla, mostrar un botón de "Reintentar" individual para esa fila, sin reiniciar todo el batch.
Al finalizar, permite descargar un ZIP que contenga todos los PDFs exitosos. Usa jszip en el cliente para armar el ZIP a partir de los PDFs recibidos (base64 o blobs).
UI/UX: Diseño limpio y funcional con Tailwind. No uses colores hardcodeados; respeta el tema del proyecto. Usa componentes de shadcn/ui disponibles (button, input, card, checkbox, table, etc.). Incluye un botón de "Cerrar sesión" en el header de la página principal.
Seguridad: Nunca expongas SUPABASE_SERVICE_ROLE_KEY ni la clave de cifrado al cliente. Las operaciones de storage y cifrado deben hacerse en server functions protegidas con requireSupabaseAuth. El bucket csf-files debe ser privado.
Metadatos: En src/routes/__root.tsx y en la ruta /auth configura títulos y descripciones apropiados (ej. "Constancias SAT", "Iniciar sesión — Constancias SAT").
Stack: TanStack Start v1, React 19, Tailwind CSS v4, Supabase/Lovable Cloud para auth y base de datos, jszip para generar ZIPs en el cliente. Usa createServerFn con requireSupabaseAuth para todas las operaciones protegidas. Asegúrate de que src/start.ts registre el middleware attachSupabaseAuth para que las server functions reciban el bearer token del cliente.
Parte 2 Opcional (batch programado):
Agregar una sección llamada Admin, donde el usuario con el rol admin (necesitamos roles) pueda configurar un Cron Job que pueda configurar una tarea programada (cron diario, semanal o mensual)
que ejecute lógica de negocio en el backend, junto con un sistema de roles para que solo administradores puedan configurarla desde la UI.
El usuario puede configurar el dia de la semana, dia del mes y la hora y minuto UTC en que se puede ejecutar
Esta tarea debe generar un token con la key generada y consumir csffiel, debe mostrarse en una sección aparte de historial y permitir la descarga del PDF y/o mostrar el error.
El historial es visible para usuarios en sesión, no se requiere ser admin.
La descarga de esos PDFs haz que pasen por el server y se entregue como blob local, evitando el bloqueo.
Se debe permitir el reintento en el historial, en caso de algún error.App local de un solo usuario que lee un Excel con RFCs y sus FIEL, y descarga en lote las Opiniones de Cumplimiento contra la API de SatGo.
Quiero que construyas una aplicación web sencilla en Python (Flask), de un solo usuario, que corra en localhost y automatice consultas de opinión de cumplimiento vía FIEL contra la API de SAT-GO (https://api.sat-go.com), endpoint POST /api/v2/Consultar/ocfiel.
Objetivo funcional:
1. Página principal con un formulario simple: campo de texto tipo password (enmascarado) para pegar el JWT de SAT-GO, e input de archivo para subir un Excel (.xlsx) con una fila por contribuyente y estas columnas obligatorias: rfc, ruta_certificado (ruta local al .cer), ruta_llave (ruta local al .key) y contraseña (contraseña de la llave privada FIEL). Botón "Procesar".
2. Al enviar el formulario, el backend procesa cada fila del Excel: abre el .cer y el .key en modo binario (no se codifican en base64; se mandan tal cual como archivos del form-data) y llama al endpoint ocfiel como multipart/form-data con los headers RFC y Authorization: Bearer {jwt}. La respuesta 200 es el PDF directo en binario (Content-Type: application/pdf, con Content-Disposition: attachment; filename=OpionDeCumplimiento.pdf); se guarda tal cual, sin parsear JSON, en una carpeta salidas/ nombrado opinion_cumplimiento_{rfc}_{fecha}.pdf.
3. Página de resultados (misma página tras el submit, o vía JS/fetch mostrando progreso fila por fila): tabla con una fila por RFC procesado (RFC, estado OK/error, mensaje de error si aplica, botón/link para descargar el PDF de esa fila), botón "Descargar todo en ZIP" que junte todos los PDFs generados, y un resumen arriba de la tabla tipo "X de Y RFCs procesados correctamente".
4. El JWT nunca se guarda en disco ni queda en el Excel; solo vive en memoria durante esa ejecución del request.
Diseño visual: interfaz limpia y moderna (HTML + CSS simple, puede ser Bootstrap por CDN o CSS propio), indicador de "procesando..." mientras corre (puede tardar varios segundos por fila porque cada llamada implica login FIEL contra el SAT), colores claros para distinguir éxito (verde) y error (rojo) en la tabla de resultados.
Contrato del endpoint (ya confirmado con una petición real, no está sujeto a interpretación):
POST https://api.sat-go.com/api/v2/Consultar/ocfiel
Headers: RFC: {rfc}, Authorization: Bearer {jwt}, Content-Type: multipart/form-data (lo arma requests solo).
Body multipart/form-data con 3 partes: llavePrivada (archivo binario, el .key de la FIEL), Certificado (archivo binario, el .cer de la FIEL) y Contrasena (texto plano, contraseña de la llave privada).
Respuesta 200: Content-Type application/pdf, Content-Disposition attachment; filename=OpionDeCumplimiento.pdf — el body ES el PDF, guardar bytes directo a disco.
Respuesta 401: JWT inválido o vencido. Aún no está confirmado con la API el código o forma exacta de error si la contraseña de la FIEL es incorrecta o el .cer/.key no corresponden al RFC del header, así que el script debe capturar cualquier respuesta no-200/no-PDF como error y mostrar el body de la respuesta para diagnóstico.
Ejemplo equivalente con requests: files = {"llavePrivada": (nombre_key, open(ruta_llave, "rb")), "Certificado": (nombre_cer, open(ruta_certificado, "rb"))}, data = {"Contrasena": contrasena}, headers = {"RFC": rfc, "Authorization": f"Bearer {jwt}"}, resp = requests.post(url, headers=headers, files=files, data=data).
Requisitos técnicos: Python 3.10+, librerías flask, requests y pandas (o openpyxl) para leer el Excel. Debe existir un run.py (o lógica al inicio de app.py) que intente importar cada librería requerida y, si falta alguna, la instale automáticamente con subprocess.check_call([sys.executable, "-m", "pip", "install", paquete]) — usar siempre sys.executable, nunca pip a secas, para garantizar que se instale en el mismo intérprete que está corriendo la app. Si el pip install falla (sin internet, sin permisos, etc.), muestra un mensaje claro con el comando exacto que el usuario debe correr a mano, en vez de tronar con un traceback críptico. Incluye igualmente un requirements.txt para quien prefiera instalar todo antes con pip install -r requirements.txt. El JWT y las contraseñas de la FIEL nunca deben imprimirse en logs ni guardarse en disco. Maneja reintentos (2-3) solo para timeouts de red intermitentes; no reintentes en 401 (JWT vencido) — marca todas las filas restantes como error y muestra un mensaje pidiendo renovar el JWT. Valida antes de llamar a la API que las rutas de certificado y llave existen y son legibles; si falta un archivo, marca esa fila como error sin tronar el resto del proceso.
Estructura de archivos esperada: una carpeta app/ con run.py (arranca el servidor Flask en localhost:5000), app.py (rutas Flask / y /procesar), satgo_client.py (wrapper del endpoint ocfiel), excel_loader.py (lectura/validación del Excel), una subcarpeta templates/ con index.html (formulario JWT + Excel) y resultados.html (tabla de resultados + descargas), una subcarpeta static/ con style.css, una carpeta salidas/ para los PDFs generados (créala si no existe) y requirements.txt.
Muy importante para evitar el error jinja2.exceptions.TemplateNotFound: Flask necesita que index.html y resultados.html vivan físicamente dentro de una carpeta llamada templates/ (y style.css dentro de static/), al mismo nivel que app.py, no sueltos junto a él. Este es el error más común al entregar o copiar el proyecto, así que: crea las carpetas por código si no existen (os.makedirs("templates", exist_ok=True) y os.makedirs("static", exist_ok=True) al inicio de run.py) y escribe ahí los .html/.css si tu flujo de entrega los genera como archivos sueltos, para que la estructura quede garantizada aunque el usuario copie los archivos a mano. En el README.md incluye explícitamente el árbol de carpetas final esperado y, si entregas los archivos uno por uno en vez de una carpeta completa, los comandos de PowerShell para reacomodarlos (mkdir templates, static / move index.html templates\ / move resultados.html templates\ / move style.css static\). Menciona también en el README una verificación rápida (dir templates y dir static deben mostrar los archivos esperados) antes de correr py run.py.
Nota sobre OneDrive: si el usuario va a correr la app dentro de una carpeta sincronizada con OneDrive, menciona en el README que normalmente no da problema, pero que si aparecen errores raros de "archivo en uso" o de permisos al escribir los PDFs en salidas/, mueva la carpeta del proyecto fuera de OneDrive (por ejemplo a C:\Users\{usuario}\satgo-app) como primer paso de diagnóstico.
Incluye un requirements.txt y un README.md corto con instrucciones de uso: cómo instalar, cómo levantar el servidor, y cómo abrirlo en el navegador (http://localhost:5000). En Windows a veces el comando python no está registrado en el PATH aunque sí lo esté el launcher py (viene con el instalador oficial de Python), así que el README debe incluir ambos comandos como opción (python run.py, y si no se reconoce, py run.py), indicando que se use el que funcione en la máquina del usuario.
Entregable: código completo y funcional de la app Flask (backend + templates HTML + CSS básico), con manejo de errores legible y comentarios breves en español explicando cada función. Si la herramienta que lo genera comparte los archivos sueltos en vez de una carpeta o zip que respete las subcarpetas, di explícitamente al final cuáles archivos van dentro de templates/ y cuáles dentro de static/, para que no tenga que adivinarlo — esto es justo lo que causa el error TemplateNotFound cuando se pierde la estructura de carpetas al descargar.