Grok tiene un "modo Think" especializado en problemas matemáticos, de programación y demás. Además de su modo de trabajo interno, en lugar de contestarte inmediatamente se toma su tiempo para analizar a fondo lo que le pidas y seguir un hilo de pensamiento mucho más profundo y detallado.
Quería probar cómo funciona, así que le he pedido que me haga una aplicación. Pero van a ver a continuación que, incluso aunque aquí no hay nada de código de programación y es solo lenguaje en español, para que el resultado salga bien de verdad uno no puede pedirle las cosas de cualquier manera: hay que saber qué pedir y cómo pedirlo, y para eso hay que saber programar. Recuerden: programar no tiene nada que ver con la informática y los ordenadores: programar es pensar. Y a continuación van a ver cómo piensa un programador:
Quiero crear una web-app (frontend + backend, todo en JavaScript + Node) para hacer sorteos. A continuación te doy los detalles.
Debe haber dos tipos de usuarios: el usuario admin y el usuario participante. Ambos acceden a la misma url que lleva a la "zona del participante", y el admin tendrá un acceso a la zona admin que te describiré más abajo.
Antes de explicar cómo se ve la app y qué elementos tiene, te digo qué campos tiene (al menos) cada sorteo:
- Título: una descripción escrita por el admin.
- Fecha de expiración: día y hora concretas en las que ya no se admiten más inscripciones de participantes en el sorteo, y se elige a los ganadores (los eliges tú automáticamente al azar: lo haces cuando se cumple el momento de la expiración con lo que tienes que tener algún proceso atento a esto, y también lo haces si cuando se inicia la app hay algún sorteo que tiene fecha de expiración anterior al momento actual). Aunque tú lo guardes internamente como una timestamp, de cara a los usuarios tienen que ver el dato como fecha + hora para saber cuándo se cierra el sorteo.
- Premios: una lista de elementos (los premios). Importante: cuando el admin crea los premios, en su interfaz puede asignar cantidades (ejemplo: 1 bufanda y 3 camisetas) y los usuarios también lo verán así. Pero aunque la interfaz lo muestre así, internamente la lista de premios estará constituida por elementos individuales (bufanda, camiseta, camiseta, camiseta). Cada uno de estos elementos tendrá, además de el/los campo/s necesarios para identificarlo, un campo "ganador" que estará vacío hasta que el sorteo expire y se asigne un ganador de entre los participantes. Cada participante solo puede ganar un premio en cada sorteo.
- Participantes: lista de participantes inscritos en ese sorteo. Cada participante tendrá al menos dos campos: nombre/alias, y email. El campo email será único: un usuario (un email) podrá participar en distintos sorteos, pero no podrá haber dos emails iguales entre los inscritos para un sorteo.
Si tú quieres añadir más campos internos a estos (por ejemplo, un "id") haz lo que te parezca mejor, a mí solo me interesa que la app funcione bien de acuerdo a los parámetros que te explico aquí.
A continuación te explico las distintas zonas y funcionalidades a las que acceden los usuarios.
Frontend: zona admin. En ella el admin gestiona los sorteos: crea uno nuevo, edita los que hay o borra los que quiere que desaparezcan de la aplicación.
Al acceder a la zona admin, el admin ve una lista de los sorteos existentes ordenada de sorteo más reciente creado a más antiguo creado (y si no hay ninguno un mensaje diciendo que no hay sorteos que mostrar).
Sobre la lista hay un botón para crear un nuevo sorteo, y en cada elemento de la lista hay un icono para editar y otro para borrar el elemento. Si se hace click en el de borrar aparece un popup de confirmación (pudiendo confirmar o cancelar), y si se confirma el elemento se borra y ese sorteo deja de existir en la aplicación irreversiblemente.
El icono de editar un sorteo de la lista, al igual que el botón para crear un nuevo sorteo, hace que aparezca un popup con un formulario para crear/editar: si se está editando los campos del popup contienen los datos editables del elemento, si se está creando uno nuevo los campos aparecen en blanco. En ambos casos, si se cancela (o se pincha fuera del popup) la operación de creación o edición se cancela; y si se acepta con el botón de confirmación la lista se actualiza con el nuevo elemento como haya sido creado/actualizado.
El admin ve cada sorteo con los siguientes campos: título, fecha de expiración y lista de premios. Cuando está creando/editando un sorteo, esta lista de premios la ve con dos campos para cada premio: cantidad y descripción. Cada sorteo aparece por defecto con campos para un premio (no se pueden crear sorteos sin premio), pudiéndose añadir más premios sin límite. Como te he explicado antes, la cantidad dará lugar internamente a tantos ítems en la lista de premios como haya definido o editado el admin en su popup de creación/edición del sorteo.
Por otra parte, en algún sitio donde no moleste al trabajo general, el admin tendrá un texto o botón que permita cambiar la contraseña admin. Al pulsar ahí aparecerá un popup que tendrá tres campos de texto para las contraseñas: 1) contraseña actual, 2) contraseña nueva, 3) repetición de contraseña nueva. Además habrá un botón de cancelar (pulsando fuera del popup se cancela también) que limpiará los campos y cerrará el popup, y un botón de enviar. Pulsando este botón se enviará la petición al servidor: si algo ha ido mal se recibirá el "mensaje de error interno" que disparará el correspondiente alert, y si todo ha ido bien junto al botón o texto de cambio de contraseña aparecerá un icono de tick verde.
Además de todos los elementos descritos hasta ahora, en la zona admin podrá haber un elemento que no existirá en el DOM hasta que se reciba desde el backend un "mensaje de error interno". En este caso se creará este elemento, que aparecerá como alert en la parte superior de la página y que contendrá el texto del mensaje enviado por el backend.
Frontend: zona participante. Es la página a la que se accede con la url general de la app.
Además de los elementos que te describo en los siguientes párrafos, en esta zona hay un link/botón para hacer login como administrador. Pulsar ahí genera un pop-up de login en el que se pide la contraseña de admin. Si el login es correcto el admin entra a la zona admin, y si es incorrecto el campo de la contraseña admin se limpia y aparece un mensaje de login incorrecto. Este popup debe tener un botón de cancelar que limpia los campos y cierra el popup, y además pulsando fuera del popup se cancela la operación igualmente.
En esta página el usuario (que no ha hecho login como admin) ve una lista de sorteos: primero los sorteos abiertos y debajo los sorteos expirados. Importante: esta lista (con los sorteos aún abiertos y sorteos expirados) solo incluye los sorteos que el admin mantiene como existentes en la app. Cuando un admin borra un sorteo en la lista de su zona admin, este sorteo deja de aparecer en la zona de participantes también.
En cada uno de los sorteos abiertos (ordenados de más reciente a más antiguo) se muestra: el título, la lista de premios y la fecha de expiración (indicando que el sorteo se cerrará en esa fecha: día y hora). En la lista de premios aparece cada premio con su cantidad y descripción. Además en cada ítem hay un botón para participar. Al pulsar este botón el usuario ve un popup en el que se le pide su nombre y su email (campos obligatorios) con un botón de confirmación: si todo está ok al pulsar este botón se envía el mensaje al backend (explicado más abajo) y se cierra el popup, si el email ya existe aparece un pequeño mensaje en el popup diciendo que el usuario ya está inscrito en este concurso, y si se pulsa el botón de cancelar o se hace click fuera del popup los campos se limpian y el popup se cierra. Si la respuesta del backend es positiva (el usuario ha sido correctamente inscrito en ese concurso), bajo el título del concurso aparecerá un texto de color verde y con tamaño pequeño que dirá "INSCRITO".
En cada uno de los sorteos expirados (ordenados de más reciente a más antiguo) se muestra: el título, la lista de ganadores (nombre y email) y para cada uno de ellos la descripción de lo que han ganado. Por ejemplo, si un premio estaba definido (por el admin) con 1 bufanda y 3 camisetas, al asignarse ganadores (en el momento de la expiración del sorteo) aparecerán cuatro ganadores, uno asociado a una bufanda y tres a una camiseta cada uno. Los sorteos expirados no aparecerán en esta zona como elementos con los que se pueda interactuar, no habrá botones que pulsar para inscribirse ni nada más que la información.
Además de todos los elementos descritos hasta ahora, en la zona participante podrá haber un elemento que no existirá en el DOM hasta que se reciba desde el backend un "mensaje de error interno". En este caso se creará este elemento, que aparecerá como alert en la parte superior de la página y que contendrá el texto del mensaje enviado por el backend.
Comunicación frontend-backend:
- Cuando un usuario entra a la url de entrada a la app front (la zona de participante), envía una petición al backend y este le devuelve la lista de sorteos preparados para mostrar.
- Cuando un usuario participante se inscribe en un sorteo, el front envía al backend el objeto con su información y el sorteo en el que se quiere inscribir, y el backend envía: si todo está ok, la lista actualizada de sorteos para que el front refresque los datos que tenía hasta ahora; si el usuario ya existía como inscrito en este sorteo, un mensaje informando de ello; y si hay algún otro tipo de error, un "mensaje de error interno" que el front pueda mostrar al usuario en su alert.
- Cuando el admin hace login para entrar a la zona admin, el frontend envía las credenciales al backend para su validación y recibe respuesta de este, para saber si son correctas o no.
- Cuando el admin entra a la zona admin, envía una petición al backend para recibir la lista completa de sorteos con la que rellenará su página para que la vea el usuario admin.
- Cuando el admin hace algún cambio en la lista de sorteos (añadiendo, modificando o eliminando) envía al backend la lista completa actualizada y recibe del backend la confirmación de que todo está ok, o bien un "mensaje de error interno" diciendo que algo ha ido mal y explicando brevemente cuál es el error ocurrido (para que el frontend del admin pueda mostrarlo al usuario en su alert).
- Cuando el admin quiere cambiar su contraseña envía al backend los tres campos de contraseñas: contraseña actual, contraseña nueva y repetición de contraseña nueva. Si la contraseña actual no es correcta o la contraseña nueva y la repetición de contraseña nueva no coinciden se enviará de vuelta un "mensaje de error interno" con el texto explicativo que se usará en el alert en el front del admin, y si todo está ok se enviará una respuesta positiva que es la que disparará en el front del admin la aparición del tick verde de confirmación.
Backend:
El backend tendrá que tener como mínimo estos elementos:
- Un servidor que se comunicará con el frontend y (cuando sea necesario) redirigirá las peticiones.
- Un gestor de la base de datos (el único que interactuará con ella directamente). Para hacer esto, y dado que la base de datos será un archivo de texto (en formato .json), este módulo hará uso de alguna función o módulo de NODE que permita leer y escribir archivos en el ordenador donde se esté ejecutando.
- Una base de datos: será un documento JSON, que contendrá toda la información necesaria para el funcionamiento de la aplicación: contraseña de admin, lista de sorteos y cualquier otra información que consideres conveniente.
Notas:
- La app gestionará la información y los valores que necesita para funcionar (las credenciales del admin y la lista de los sorteos y demás objetos que puedas considerar convenientes si es así) directamente en su memoria, usando el fichero .json solo como respaldo. Cada 5 minutos se asegurará de que el fichero existe, eliminará todo su contenido, y guardará en formato JSON toda la información que tenga en la memoria que deba ser almacenada en el fichero de respaldo para recuperarlo al iniciar.
- Al iniciarse la app, esta buscará el fichero .json y recuperará la información que haya en él. En caso de que el fichero no exista, la información que hay en él no tenga el formato o la estructura correcta o hubiera cualquier otro problema, la app hará lo siguiente: se asegurará de que el fichero existe, en caso de que existiera ya borrará todo su contenido, y escribirá en él los datos mínimos para iniciar la app. La lista de sorteos y eventualmente otros objetos estará inicialmente vacía, pero en el admin vas a poner por defecto las siguiente contraseña admin: "mandelrot".
- La contraseña admin NO se guarda encriptada, esta app no requiere seguridad. Si es necesario cambiar a mano la contraseña directamente en el .json quiero poder hacerlo fácilmente.
- Quiero que uses un css sencillo y elegante, con fondo claros y colores sin estridencias pero con un diseño en el que se vean los elementos claramente diferenciados (sea por colores, por bordes o por los espacios entre ellos). Usa algún framework pequeño como Pure CSS o Spectre CSS (el que tenga algún CDN que se pueda enlazar online).
- Voy a tener instalado Node en el servidor, y en la carpeta de la app voy a hacer npm init y a partir de ahí haré npm install + las dependencias que tú me digas.
Si necesitas alguna información que no te haya dado dímelo, y si ya tienes todo ponte a trabajar y en tu respuesta quiero que me des solo estas cuatro cosas:
1) La estructura de ficheros que debo crear en la carpeta de la aplicación.
2) El contenido de cada fichero, para copiar y pegar en cada uno de ellos.
3) Las dependencias que tengo que instalar con npm (después de hacer npm init).
4) Cómo arrancar la aplicación para levantar el servidor, y cómo acceder a ella como usuario mediante el navegador.
Lo que han visto hasta aquí es lo que yo le he dicho a Grok, y el resultado ha sido que me ha dado la app completa en menos de 3 minutos:
Normalmente yo habría tardado quizá 3 días en hacer esta app; y de ese plazo una gran parte se me habría ido en detalles chorra que no te hacen avanzar casi nada pero que no puedes evitar y que se te comen un montón de tiempo molesto y tedioso. En este caso estuve más o menos una hora pensando y escribiéndole a Grok lo que quería, a lo que sumándole los 3 minutos de trabajo de la IA nos da un resultado ridículamente corto para tener una aplicación totalmente funcional (de hecho el propósito de esto es usarlo para un caso real que se me ha presentado recientemente).
Por supuesto esto ha sido solo un ejercicio pequeño y no es extrapolable al nivel "pro" de verdad en ecosistemas de aplicaciones grandes, que llevaría otra planificación y aspectos a considerar. Pero esto muestra lo que quería compartir con ustedes: programar es pensar (es lo que hice yo), y lo de ponerse a generar ficheros con código (lo que hizo Grok) es simplemente trabajo mecánico equivalente a poner ladrillos donde ha dicho el arquitecto que hay que ponerlos. Estamos entrando en tiempos interesantes.