Elegir espacio

Dos espacios

¿Qué quieres consultar?

Elige el espacio al que quieres entrar.

Biblioteca FastAPIPráctica

Práctica · Bloque 4 · Unidades 4.1–4.4

Conserva datos, invariantes e historia

Un POST verde no demuestra persistencia y un PATCH 200 no demuestra que el cambio sea correcto. Aquí cada operación deja evidencia en HTTP, en el estado persistente y en el SQL real; cuando varias filas cambian, el fallo también debe demostrar que no quedó un resultado parcial. Finalmente, cada cambio de schema debe preservar significado desde una revisión poblada y declarar cómo se ejecuta y recupera.

Cómo trabajar esta unidad

Antes de editar: Antes de editar, clasifica qué debe vivir por proceso, por petición, por operación y más allá del proceso; después predice qué dato se perderá al recrear la app actual.

Antes de consultar o cambiar: Predice dos páginas y los tres estados de un PATCH antes de ejecutar; señala qué resultado cambiaría si faltara ORDER BY o exclude_unset.

Antes de relacionar o confirmar varias filas: Antes de editar, predice el DDL que debe impedir el estado inválido, las filas que sobrevivirán a un fallo tras el primer commit y cuántos SELECT emitirá una colección lazy.

Antes de migrar: Antes de editar, separa modelo deseado, schema desplegado, datos y revisión actual; marca cada drop, rename, backfill y recuperación que el cambio necesita.

Cada paquete tiene un baseline verde de continuidad y criterios de aceptación visibles que empiezan rojos. Registra ambos antes de cambiar código. Los checkpoints no incluyen pistas, solución ni una arquitectura prescrita.

Ver la reflexión guardada del ejercicio guiado

12 actividades disponibles.

Paso 7 · Apoyo gradual

Conecta una operación completa

Evidencia: La traza distingue engine, sesión y operación; POST confirma y refresca, GET demuestra persistencia y la respuesta no filtra campos internos.

EX-B4-02

Conectar modelo, sesión y contrato público

  • Respuesta redactada
  • Rebanada vertical guiada
  • Media

Una API de activos cumple su contrato con un diccionario por instancia. El POST y el GET pasan, pero una nueva aplicación ya no encuentra el recurso.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué objeto debe vivir por aplicación, cuál por petición, dónde se confirma la escritura y qué prueba demuestra una fila en lugar de otro diccionario?

Frontera de supervivencia

La misma ruta de SQLite se entrega a dos llamadas de create_app. La primera crea el activo; la segunda debe recuperarlo sin recibir el diccionario anterior.

Para ordenar tu razonamiento

  1. ¿Qué resultado esperas al crear dos apps sobre la misma ruta de archivo?
  2. ¿Qué campos pertenecen a AssetCreate, AssetTable y AssetPublic?
  3. ¿Qué observación distingue commit, refresh y close?

Trabajo en el workspace

  1. Registra el baseline y clasifica engine, Session, transacción y fila por ciclo de vida antes de editar.
  2. Define modelos distintos de creación, tabla y salida; deja table=True solo en el modelo persistente.
  3. Crea un engine estable para la app, registra metadata antes del bootstrap local y proporciona una Session nueva mediante yield.
  4. Reemplaza el POST por model_validate, add, commit y refresh; adapta el GET solo lo necesario para demostrar lectura por id.
  5. Añade una prueba o traza de apertura/cierre por petición y ejecuta baseline y aceptación hasta dejarlos verdes.

Entrega esperada

  • Código persistente y tests propios, sin incluir una base generada.
  • evidence.md con predicción, comandos, ciclos observados y límite de parada.
  • Salida de ambas suites e inspección breve de tabla, fila y contrato OpenAPI.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista 1 · Empieza por los tres contratos
  • Solo el modelo de tabla registra metadata y puede tener un id todavía ausente.
  • El modelo público debe exigir el id y omitir internal_note.
Pista 2 · Separa lifecycle de decisión
  • El `with Session(engine)` rodea a yield y garantiza close.
  • La operación que conoce la escritura ejecuta add, commit y refresh en ese orden observable.
Pista 3 · Prueba otra instancia
  • Construye dos apps con el mismo `tmp_path / assets.db`.
  • No pases el diccionario ni el objeto creado de una instancia a la otra; pasa solo el id público.
Profundización opcional

Reemplazar el estado efímero por SQLite y completar una creación con modelos separados, engine estable y Session por petición sin alterar la representación pública.

Contexto adicional

  • Ejecuta primero `pytest`: los tests de contrato suministrados deben estar verdes.
  • Ejecuta después `pytest tests/acceptance`: sus dos fallos iniciales son visibles y describen la propiedad pendiente.
  • Conserva método, path, status, body, 404 y OpenAPI; no añadas listados, PATCH, relaciones ni capas obligatorias.

Decisiones abiertas

  • Puedes conservar un solo módulo o separar modelos y base de datos; justifica el grafo de imports que resulte.
  • Puedes instrumentar el lifecycle con eventos, una factoría sustituible o un test unitario, siempre que no cambies el contrato HTTP.

Cómo revisar tu respuesta

  • Los cinco tests de contrato pasan antes y después; POST sigue en 201 y GET/404 conservan body y status.
  • Otra app construida sobre el mismo archivo recupera el activo y el archivo contiene una fila persistida.
  • AssetCreate no acepta id, AssetPublic exige id y ningún body u OpenAPI expone internal_note.
  • Existe un engine estable por app y una Session distinta por petición; no hay Session global mutable.
  • La operación de escritura hace commit y refresh explícitos; la dependencia con yield garantiza cierre en éxito y error.
  • create_all se usa solo como bootstrap local después de importar el modelo y la entrega declara que no migra esquemas.

Evidencia, revisión y reinicio

  • Predicción de los cuatro ciclos de vida antes del cambio.
  • Baseline verde, aceptación roja inicial y aceptación verde final.
  • Traza o test propio de Session por petición y cierre en éxito y error.
  • Inspección del archivo SQLite y respuesta pública después de recrear la app.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-02-assets.zip y borrar solo los archivos SQLite creados dentro de ese workspace temporal.

Material descargable opcional

  • Starter de activos efímerosAPI en memoria, cinco tests de contrato verdes, dos criterios ejecutables inicialmente rojos y plantilla de evidencia; sin SQLModel ni solución.

Checkpoint independiente · EX-B4-S01-01

Transfiere el mecanismo a facturas

En el dominio de facturas, haces persistente una creación sin copiar la estructura guiada y pruebas supervivencia entre dos instancias de aplicación.

EX-B4-S01

Importación de facturas

  • Práctica extendida
  • Checkpoint acumulativo
  • Media-alta
  • Apoyo autónomo; criterios visibles, sin pistas ni estructura prescrita
  • M-MIN

Una API distinta evoluciona desde una factura plana hasta operaciones persistentes y una factura con líneas que debe guardarse como una sola unidad.

Abrir práctica extendida: base común y 1 parte

Base común

  • Cada starter conserva cinco tests de continuidad verdes y expone criterios de aceptación inicialmente rojos.
  • No contiene SQLModel, solución, pistas escalonadas ni una arquitectura de carpetas prescrita.
  • Las partes 01–03 avanzan de persistencia plana a operaciones y después a cabecera, líneas e integridad transaccional.
  • Cada parte parte de la evidencia anterior, pero llega como paquete independiente para que el estado local no falsee el resultado.

Paquete de trabajo

  • Checkpoint de facturasDominio nuevo con estado efímero, contrato probado, aceptación visible y plantilla de evidencia; sin solución ni pistas.

Entorno, evidencia y reinicio

Entorno: Python 3.10+ en un workspace temporal; FastAPI 0.141, SQLModel 0.0.39, pytest y httpx2 instalados por el paquete con uv.

  • Predicción independiente de ciclos de vida, contrato y frontera transaccional.
  • Resultados del baseline y de los criterios ejecutables de cada parte.
  • Pruebas propias de Session, consultas y ausencia de estado parcial.

Revisión: con Codex, utilizando los artefactos y criterios de cada parte; no se publica una solución oficial.

Reinicio: Volver a descomprimir el paquete de la parte activa en otro directorio y eliminar solo los SQLite creados por ese intento.

Parte 1 · Apoyo autónomo

EX-B4-S01-01 · Hacer persistente una factura

Transferir la primera frontera persistente a otro dominio y demostrar contrato, lifecycle y supervivencia sin copiar la secuencia guiada.

Qué debes hacer
  1. Sin abrir el starter guiado, predice qué debe vivir por app, petición, operación y más allá del proceso.
  2. Ejecuta y registra la suite de contrato y los criterios de aceptación antes de editar.
  3. Haz persistente el POST y el GET por id con tres modelos y una Session por petición.
  4. Añade la evidencia de lifecycle que consideres más directa y prueba una segunda app sobre el mismo archivo.
  5. Documenta una decisión propia, una alternativa descartada y el punto exacto donde detuviste el alcance.
Entrega esperada
  • Repositorio del checkpoint, tests añadidos y ningún archivo SQLite versionado.
  • evidence.md completo con comandos, resultados, matriz y decisión.
  • Una inspección de tabla/fila y un fingerprint del contrato público final.
Criterios de aceptación
  • Los cinco tests suministrados pasan antes y después y el contrato conserva método, path, 201, 404 y body.
  • Una factura creada por la primera app se recupera desde otra app que solo comparte la ruta SQLite.
  • La base contiene una tabla de dominio y la fila con supplier_reference, subtotal_cents y currency.
  • Creación, tabla y salida tienen responsabilidades distintas; storage_note no aparece en respuesta ni OpenAPI.
  • Un engine estable sirve a sesiones distintas y cerradas por petición; la escritura confirma y refresca explícitamente.
  • No se anticipan importaciones por lotes, unicidad, relaciones, PATCH, repositorios, migraciones o PostgreSQL.
Evidencia para revisión
  • Matriz de ciclos de vida y modelos escrita antes del cambio.
  • Baseline verde, aceptación roja inicial y todas las pruebas verdes al finalizar.
  • Inspección de SQLite y prueba propia de lifecycle de Session.

Reinicio de esta parte: Descomprimir de nuevo el checkpoint y borrar solo la base local del intento; no reutilizar el código del ejercicio de activos.

Transferencia: Ante otro recurso plano, puedes separar modelos de creación, tabla y salida, ubicar la transacción y demostrar cuándo se abre y se cierra cada sesión.

Paso 8 · Retirada gradual del apoyo

Separa presencia de valor y consulta de ventana

Evidencia: Los ensayos separan la matriz omitido/null/valor de la ventana SQL con filtro, orden, count, limit y offset observables.

EX-B4-04

Reparar un PATCH que confunde ausencia con null

  • Respuesta redactada
  • Debugging de intención
  • Media

Una API persistente de activos admite PATCH. Enviar un body vacío responde 200, pero borra la ubicación porque el código serializa también el default no enviado.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué información de presencia conserva Pydantic antes del dump y qué conjunto exacto debe recibir sqlmodel_update?

Matriz de presencia

Estado inicial location=Madrid. PATCH {} conserva Madrid; PATCH con null deja null; PATCH con Bilbao deja Bilbao.

Para ordenar tu razonamiento

  1. ¿Qué valor esperas después de PATCH {}?
  2. ¿Qué debe ocurrir con location: null si el campo es nullable?
  3. ¿Qué cambia entre model_dump() y model_dump(exclude_unset=True)?

Trabajo en el workspace

  1. Predice los tres resultados y ejecuta baseline y aceptación sin editar.
  2. Inspecciona el conjunto de campos explícitos que Pydantic conserva para cada body.
  3. Aplica únicamente esos cambios a la fila y conserva commit y refresh observables.
  4. Repite las suites y registra por qué null sigue siendo un cambio válido.

Entrega esperada

  • Corrección mínima y pruebas finales.
  • Matriz prevista/observada para omitido, null y valor.
  • Fingerprint de POST, GET, PATCH y 404 antes y después.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista 1 · Observa antes de mutar
  • Imprime o prueba payload.model_fields_set para {} y para {location: null}.
  • El valor None no dice por sí solo si el cliente envió el campo.
Pista 2 · Conserva solo lo explícito
  • model_dump(exclude_unset=True) produce el parche, no el estado completo.
  • sqlmodel_update aplica ese conjunto, pero no decide permisos ni confirma la transacción.
Profundización opcional

Distinguir campo omitido, null explícito y valor antes de mutar la fila, sin cambiar el contrato de creación, lectura o ausencia.

Contexto adicional

  • Ejecuta primero el baseline verde y después los tres casos de aceptación.
  • Repara solo la extracción y aplicación de cambios explícitos; no amplíes el modelo update.
  • Conserva POST 201, GET/404, response_model y la ausencia de internal_note en HTTP y OpenAPI.

Decisiones abiertas

  • Puedes inspeccionar model_fields_set o el dump con exclusión; compara ambas opciones antes de elegir.

Cómo revisar tu respuesta

  • Los cinco tests de continuidad permanecen verdes y los tres criterios de presencia terminan verdes.
  • Un body vacío no modifica location; null explícito la borra y un valor explícito la sustituye.
  • El conjunto entregado a sqlmodel_update procede de model_dump(exclude_unset=True) o una técnica equivalente demostrable.
  • PATCH sobre un id ausente conserva 404 y no crea una fila.
  • internal_note no se puede asignar desde el body ni aparece en la representación pública.

Evidencia, revisión y reinicio

  • Matriz omitido, null y valor predicha antes de ejecutar.
  • Cinco pruebas de continuidad verdes y un criterio focalizado inicialmente rojo.
  • Diff mínimo y respuestas observadas para los tres estados de presencia.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-04-patch-intent.zip y eliminar solo la base SQLite creada dentro de ese workspace.

Material descargable opcional

  • Starter con PATCH defectuosoAPI SQLModel ya persistente, cinco pruebas de continuidad verdes y tres casos de presencia visibles; uno empieza rojo.

EX-B4-05

Construir una ventana de consulta coherente

  • Respuesta redactada
  • Implementación y diagnóstico SQL
  • Media

El listado de activos publica filtros, orden, offset y limit, pero ignora casi todos los parámetros y calcula total con len(items).

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿En qué orden lógico aplicas filtros, count, orden total, offset y limit para que la respuesta y la traza cuenten la misma historia?

Consulta contractual

Con dos activos network y orden name desc, offset=1 y limit=1, la ventana contiene Router y total sigue siendo 2.

Para ordenar tu razonamiento

  1. ¿El total describe toda la tabla, el conjunto filtrado o la página?
  2. ¿Qué desempate vuelve total el orden solicitado?
  3. ¿Qué cláusulas deben aparecer realmente en SQL?

Trabajo en el workspace

  1. Calcula a mano la página esperada del fixture y ejecuta ambas suites.
  2. Construye un statement base y aplica el filtro con atributos del modelo.
  3. Obtén el total filtrado antes de la ventana y añade un orden total mediante una allowlist.
  4. Aplica offset y limit en SQL, repite la traza y reconcilia cada cláusula con el body.

Entrega esperada

  • Listado corregido y pruebas finales.
  • Página prevista/observada y traza SELECT relevante.
  • Explicación de la clave de desempate y del significado de total.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista única · Dos statements, un predicado
  • El count no necesita ORDER BY, OFFSET ni LIMIT.
  • La consulta de items sí necesita orden total antes de recortar la ventana.
Profundización opcional

Construir filtro, orden allowlisted, total y ventana como una intención coherente y demostrarla tanto en HTTP como en el SQL ejecutado.

Contexto adicional

  • Conserva el wrapper items/total/offset/limit y los límites públicos ya declarados.
  • Solo name y category son claves de orden admitidas; no interpoles nombres recibidos por el cliente.
  • No sustituyas el count por cargar todas las filas ni implementes cursores o búsqueda libre.

Decisiones abiertas

  • Puedes construir el count desde el mismo predicado o factorizar una función pequeña; demuestra que ambos statements comparten filtros.

Cómo revisar tu respuesta

  • Los cinco tests de continuidad y los dos criterios de consulta pasan.
  • category filtra antes del count; total representa todas las coincidencias y no solo items.
  • La ventana respeta offset y limit en SQL y nunca devuelve más filas que limit.
  • El orden solicitado usa una allowlist y añade id como desempate determinista.
  • La traza SELECT contiene WHERE, ORDER BY, LIMIT, OFFSET y una consulta COUNT coherente.
  • Los parámetros inválidos conservan la validación 422 publicada por FastAPI.

Evidencia, revisión y reinicio

  • Página esperada calculada antes del cambio.
  • Comportamiento HTTP y traza SQL para filtro, orden total, count y ventana.
  • Cinco pruebas de continuidad verdes y dos criterios focalizados inicialmente rojos.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-05-query-window.zip y borrar solo el SQLite creado dentro del workspace temporal.

Material descargable opcional

  • Starter de ventana incompletaAPI persistente con contrato público y baseline verdes; comportamiento y traza SQL exponen dos criterios inicialmente rojos.

Checkpoint independiente · EX-B4-S01-02

Diseña las operaciones de facturas

Sobre una base persistente de facturas, diseñas list, PATCH y DELETE desde criterios visibles sin copiar los ensayos ni añadir capas prescritas.

EX-B4-S01

Importación de facturas

  • Práctica extendida
  • Checkpoint acumulativo
  • Media-alta
  • Apoyo autónomo; criterios visibles, sin pistas ni estructura prescrita
  • M-MIN

Una API distinta evoluciona desde una factura plana hasta operaciones persistentes y una factura con líneas que debe guardarse como una sola unidad.

Abrir práctica extendida: base común y 1 parte

Base común

  • Cada starter conserva cinco tests de continuidad verdes y expone criterios de aceptación inicialmente rojos.
  • No contiene SQLModel, solución, pistas escalonadas ni una arquitectura de carpetas prescrita.
  • Las partes 01–03 avanzan de persistencia plana a operaciones y después a cabecera, líneas e integridad transaccional.
  • Cada parte parte de la evidencia anterior, pero llega como paquete independiente para que el estado local no falsee el resultado.

Paquete de trabajo

Entorno, evidencia y reinicio

Entorno: Python 3.10+ en un workspace temporal; FastAPI 0.141, SQLModel 0.0.39, pytest y httpx2 instalados por el paquete con uv.

  • Predicción independiente de ciclos de vida, contrato y frontera transaccional.
  • Resultados del baseline y de los criterios ejecutables de cada parte.
  • Pruebas propias de Session, consultas y ausencia de estado parcial.

Revisión: con Codex, utilizando los artefactos y criterios de cada parte; no se publica una solución oficial.

Reinicio: Volver a descomprimir el paquete de la parte activa en otro directorio y eliminar solo los SQLite creados por ese intento.

Parte 2 · Apoyo autónomo

EX-B4-S01-02 · Consultar y cambiar facturas

Transferir consulta acotada, PATCH con presencia explícita y DELETE 204 al dominio persistente de facturas sin copiar la implementación guiada.

Qué debes hacer
  1. Predice la página de aceptación y los resultados de PATCH omitido/null antes de editar.
  2. Ejecuta continuidad y aceptación, y diseña tus modelos de página y update desde el contrato visible.
  3. Implementa listado por currency con count filtrado, orden estable, offset y limit acotado.
  4. Implementa PATCH de note distinguiendo ausencia y null, y DELETE con commit y ausencia posterior.
  5. Añade una prueba o traza propia que haga visible una decisión estructural y documenta dónde detuviste el alcance.
Entrega esperada
  • Código y tests añadidos sin archivos SQLite generados.
  • evidence.md con predicciones, comandos, resultados y una decisión propia.
  • Fingerprint OpenAPI y evidencia de ventana, presencia y borrado.
Criterios de aceptación
  • Los cinco tests de continuidad permanecen verdes y los cuatro criterios nuevos terminan verdes.
  • GET /invoices filtra por currency, ordena de forma total, limita en SQL y devuelve total del conjunto filtrado.
  • PATCH vacío conserva note; null explícito la borra y los campos protegidos no son asignables.
  • DELETE confirma la eliminación, responde 204 sin body y el GET posterior devuelve el 404 existente.
  • GET y operaciones sobre ids ausentes conservan un contrato de error coherente.
  • No se anticipan lotes, unicidad, relaciones, rollback multioperación, migraciones, PostgreSQL o arquitectura obligatoria.
Evidencia para revisión
  • Página y matriz de presencia predichas antes de implementar.
  • Cinco pruebas de continuidad verdes y cuatro criterios inicialmente rojos que terminan verdes.
  • Traza o test propio del orden total, count filtrado y ausencia posterior al DELETE.

Reinicio de esta parte: Descomprimir de nuevo esta parte y borrar solo su base local; no copiar los starters guiados de activos.

Transferencia: Ante otra colección, puedes decidir get o select, fijar un orden total, limitar la ventana y aplicar solo cambios explícitos antes del commit.

Paso 9 · Evidencia del motor

Separa conflicto, coste y atomicidad

Evidencia: Los ensayos separan conflicto unique, presupuesto de carga y operación multirow; cada uno conserva evidencia del motor, no solo del body HTTP.

EX-B4-07

Recuperar la sesión después de un conflicto unique

  • Respuesta redactada
  • Debugging transaccional
  • Media

La base impide dos activos con el mismo tag, pero el endpoint intenta consultar con la misma Session justo después de IntegrityError y termina respondiendo 500.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué estado conserva la transacción tras fallar el flush o commit y qué debe ocurrir antes de cualquier consulta posterior con esa Session?

Conflicto y recuperación

El segundo POST con tag repetido responde 409 y una petición posterior lista el primer activo usando una Session válida.

Para ordenar tu razonamiento

  1. ¿Qué impide realmente dos tags iguales bajo concurrencia?
  2. ¿Por qué consultar antes de insertar no reemplaza UNIQUE?
  3. ¿Qué demuestra que rollback recuperó la Session y no solo ocultó el error?

Trabajo en el workspace

  1. Predice status, filas persistidas y resultado de una consulta posterior al conflicto.
  2. Ejecuta ambas suites e identifica la excepción de integridad y el error secundario de la Session.
  3. Haz rollback antes de reutilizar la Session y traduce solo el conflicto unique conocido a HTTP 409.
  4. Repite las pruebas e inspecciona la constraint y la fila conservada en SQLite.

Entrega esperada

  • Corrección focalizada y pruebas finales.
  • Secuencia observada de flush o commit, IntegrityError, rollback y consulta posterior.
  • Explicación breve de por qué el pre-check puede mejorar el mensaje pero no garantizar unicidad.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista 1 · El fallo cambia el estado
  • Capturar IntegrityError no restablece por sí solo la transacción lógica de la Session.
  • Haz rollback antes de consultar, añadir o confirmar de nuevo.
Pista 2 · Clasifica con precisión
  • La constraint debe seguir en el DDL aunque exista una comprobación amigable.
  • Traduce la violación que conoces; deja visibles los defectos inesperados.
Profundización opcional

Traducir una violación UNIQUE conocida a 409 y recuperar explícitamente la Session antes de volver a usarla, sin sustituir la garantía del motor por un pre-check.

Contexto adicional

  • Ejecuta el baseline verde y después los dos criterios de aceptación sin editar.
  • Conserva la UniqueConstraint y cambia solo la recuperación y traducción del conflicto conocido.
  • No añadas un SELECT preventivo como garantía principal ni conviertas todo error de base en 409.

Decisiones abiertas

  • Puedes aislar la traducción en una función pequeña o mantenerla en la operación; demuestra que la frontera transaccional sigue siendo visible.

Cómo revisar tu respuesta

  • Los cinco tests de continuidad y los dos criterios transaccionales pasan.
  • SQLite conserva una UNIQUE sobre tag y solo existe una fila para el valor repetido.
  • El conflicto conocido responde 409 con un detalle estable; otros errores no se etiquetan automáticamente como duplicados.
  • La Session recibe rollback antes de cualquier operación posterior y vuelve a ejecutar una consulta válida.
  • No se usa un SELECT previo como sustituto de la constraint del motor.

Evidencia, revisión y reinicio

  • Dos POST con el mismo tag y el estado observado de la Session después de IntegrityError.
  • Cinco pruebas de continuidad verdes y dos criterios focalizados, uno inicialmente rojo.
  • Constraint UNIQUE inspeccionada en SQLite y una consulta válida después del rollback.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-07-unique-rollback.zip y borrar solo el SQLite generado dentro de ese workspace.

Material descargable opcional

EX-B4-10

Reducir un 1+N sin cambiar la respuesta

  • Respuesta redactada
  • Diagnóstico de carga
  • Media

El listado de organizaciones devuelve sus activos correctamente, pero acceder a cada colección lazy emite un SELECT adicional por organización.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Cuántos SELECT crecen con el número de organizaciones y qué carga conserva la forma de la respuesta con un coste acotado?

Presupuesto SQL

La respuesta contiene las mismas tres organizaciones y sus activos, mientras la traza pasa de cuatro SELECT a un máximo de dos.

Para ordenar tu razonamiento

  1. ¿Qué línea dispara cada consulta adicional?
  2. ¿La relación define integridad, navegación Python o ambas?
  3. ¿Por qué selectinload encaja con una colección en esta respuesta?

Trabajo en el workspace

  1. Predice 1+N para el fixture, ejecuta ambas suites y localiza la evaluación lazy.
  2. Captura o cuenta los SELECT emitidos por una sola petición.
  3. Añade una opción selectinload sobre la colección y conserva el orden y body publicados.
  4. Repite la traza y explica qué forma de cardinalidad justificaría otra estrategia.

Entrega esperada

  • Consulta corregida y pruebas finales.
  • Conteo y fragmentos de SQL antes y después.
  • Justificación de estrategia basada en la forma de la relación y la respuesta.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista única · Decide desde la forma
  • La consulta principal conoce que la respuesta recorrerá una colección.
  • selectinload agrupa las claves padre en una segunda consulta en lugar de consultar por cada fila.
Profundización opcional

Hacer explícito el presupuesto de consultas y seleccionar una estrategia de carga adecuada para una colección sin alterar el contrato HTTP.

Contexto adicional

  • Predice el número de SELECT para tres organizaciones y captura la traza antes de editar.
  • Conserva el body y la relación; cambia únicamente la estrategia de consulta.
  • No serialices consultas manuales por fila ni introduzcas paginación de hijos o arquitectura nueva.

Decisiones abiertas

  • Puedes instrumentar SQL con eventos o logs; conserva un conteo reproducible ligado a una petición.

Cómo revisar tu respuesta

  • Los cinco tests de continuidad y los dos criterios de carga pasan.
  • El body conserva organizaciones, activos y orden sin consultas desde el serializador.
  • Una petición con tres organizaciones ejecuta como máximo dos SELECT y la segunda consulta usa IN sobre las claves padre.
  • La solución usa una opción de carga explícita para la colección; no ejecuta un SELECT manual dentro del bucle.
  • El estudiante puede localizar por qué el coste anterior era 1+N y qué variable hacía crecer N.

Evidencia, revisión y reinicio

  • Número de SELECT previsto y observado para tres organizaciones.
  • Cinco pruebas de continuidad verdes y dos criterios de aceptación, uno inicialmente rojo.
  • Traza SQL antes y después con la misma representación HTTP.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-10-n-plus-one.zip y borrar solo el SQLite generado dentro de ese workspace.

Material descargable opcional

  • Starter con carga 1+NRelación uno-a-muchos funcional, cinco pruebas de continuidad y un criterio de presupuesto inicialmente rojo.

EX-B4-11

Hacer atómica una transferencia con dos apuntes

  • Respuesta redactada
  • Reparación de frontera transaccional
  • Media-alta

Una transferencia crea cabecera y apuntes, pero confirma cada fila por separado. Si el segundo apunte viola una constraint, quedan datos parciales.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué filas deben existir si cualquier apunte falla y para qué necesitas flush si todavía no quieres confirmar?

Todo o nada

Una transferencia válida guarda cabecera y dos apuntes con un commit; una inválida deja cero cabeceras y cero apuntes.

Para ordenar tu razonamiento

  1. ¿Cuántos commits observas hoy en el camino feliz?
  2. ¿Qué id puede asignar flush sin cerrar la transacción?
  3. ¿Quién debe decidir el commit del caso de uso completo?

Trabajo en el workspace

  1. Predice filas sobrevivientes y commits del camino feliz antes de ejecutar.
  2. Reproduce el fallo de la segunda línea e inspecciona cabeceras y apuntes persistidos.
  3. Sustituye commits interiores por add y flush cuando necesites el id de cabecera.
  4. Confirma una sola vez al final, revierte ante fallo y prueba éxito y error desde una base limpia.

Entrega esperada

  • Frontera transaccional corregida y pruebas finales.
  • Tabla comparativa de filas y commits antes y después.
  • Explicación de la diferencia observable entre flush, commit y rollback.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista única · La frontera sigue al caso de uso
  • Añade la cabecera y haz flush para obtener su id sin publicar todavía.
  • Añade ambos apuntes y reserva el único commit para cuando toda la invariante pueda cumplirse.
Profundización opcional

Alinear la unidad de trabajo con el caso de uso completo usando flush para obtener claves y un único commit para publicar el cambio.

Contexto adicional

  • Ejecuta continuidad y aceptación, e inspecciona la base tras el fallo intencional.
  • Conserva tablas, constraints y contrato HTTP; mueve la frontera, no el dominio.
  • No uses commits internos por repositorio ni conviertas la operación en éxito parcial.

Decisiones abiertas

  • Puedes usar try/except explícito o un contexto transaccional equivalente, siempre que la frontera y el rollback queden verificables.

Cómo revisar tu respuesta

  • Los cinco tests de continuidad y los dos criterios de atomicidad pasan.
  • El camino feliz publica una cabecera y dos apuntes con exactamente un commit.
  • El fallo de cualquier apunte responde con error y no deja cabecera ni apuntes persistidos.
  • flush se usa solo para sincronizar y obtener claves dentro de la transacción abierta.
  • La operación que conoce el caso de uso decide commit y rollback; ningún helper confirma parcialmente.

Evidencia, revisión y reinicio

  • Filas sobrevivientes y número de commits previstos antes de ejecutar.
  • Cinco pruebas de continuidad verdes y dos criterios de atomicidad inicialmente rojos.
  • Estado persistente tras éxito y tras fallo en la segunda línea.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-11-atomic-transfer.zip y borrar solo el SQLite generado dentro de ese workspace.

Material descargable opcional

  • Starter con commits interioresOperación multirow funcional en el camino feliz, cinco pruebas de continuidad y dos criterios rojos que exponen estado parcial y tres commits.

Checkpoint independiente · EX-B4-S01-03

Diseña la atomicidad de una factura con líneas

En facturas, diseñas cabecera, líneas, constraint y límite transaccional desde criterios visibles, sin copiar la transferencia guiada ni recibir pistas.

EX-B4-S01

Importación de facturas

  • Práctica extendida
  • Checkpoint acumulativo
  • Media-alta
  • Apoyo autónomo; criterios visibles, sin pistas ni estructura prescrita
  • M-MIN

Una API distinta evoluciona desde una factura plana hasta operaciones persistentes y una factura con líneas que debe guardarse como una sola unidad.

Abrir práctica extendida: base común y 1 parte

Base común

  • Cada starter conserva cinco tests de continuidad verdes y expone criterios de aceptación inicialmente rojos.
  • No contiene SQLModel, solución, pistas escalonadas ni una arquitectura de carpetas prescrita.
  • Las partes 01–03 avanzan de persistencia plana a operaciones y después a cabecera, líneas e integridad transaccional.
  • Cada parte parte de la evidencia anterior, pero llega como paquete independiente para que el estado local no falsee el resultado.

Paquete de trabajo

  • Checkpoint de atomicidad de facturasAPI de facturas planas equivalente a la parte 02 y cuatro criterios rojos para diseñar líneas, constraints y una creación atómica; sin pistas ni solución.

Entorno, evidencia y reinicio

Entorno: Python 3.10+ en un workspace temporal; FastAPI 0.141, SQLModel 0.0.39, pytest y httpx2 instalados por el paquete con uv.

  • Predicción independiente de ciclos de vida, contrato y frontera transaccional.
  • Resultados del baseline y de los criterios ejecutables de cada parte.
  • Pruebas propias de Session, consultas y ausencia de estado parcial.

Revisión: con Codex, utilizando los artefactos y criterios de cada parte; no se publica una solución oficial.

Reinicio: Volver a descomprimir el paquete de la parte activa en otro directorio y eliminar solo los SQLite creados por ese intento.

Parte 3 · Apoyo autónomo

EX-B4-S01-03 · Guardar una factura con sus líneas de forma atómica

Transferir relaciones, constraints y frontera transaccional al dominio de facturas, diseñando una creación de cabecera y líneas sin estado parcial.

Qué debes hacer
  1. Predice tablas, claves, constraints, subtotal y filas sobrevivientes antes de editar.
  2. Ejecuta continuidad y aceptación y diseña modelos de entrada, tabla, relación y salida desde los criterios visibles.
  3. Implementa POST /invoice-batches con posiciones únicas, cantidades y precios positivos, y subtotal calculado en servidor.
  4. Guarda cabecera y líneas como una sola unidad; demuestra rollback completo si una línea viola una invariante.
  5. Añade una prueba estructural o traza propia y documenta una decisión, una alternativa descartada y el límite del alcance.
Entrega esperada
  • Código y tests añadidos sin archivos SQLite generados.
  • evidence.md con DDL previsto/observado, comandos, resultados y frontera transaccional.
  • Estado persistente y respuesta HTTP de un caso válido y otro inválido.
Criterios de aceptación
  • Los cinco tests de continuidad permanecen verdes y los cuatro criterios nuevos terminan verdes.
  • invoice_lines tiene FK a invoices, UNIQUE compuesta por invoice_id y position, y checks positivos para quantity y unit_price_cents.
  • POST /invoice-batches crea una cabecera con dos líneas y devuelve subtotal_cents calculado en 12300.
  • Si una línea falla, la respuesta no es 201 y la base conserva cero cabeceras y cero líneas de esa operación.
  • La operación realiza un único commit; usa flush si necesita la clave y rollback antes de reutilizar la Session.
  • No se anticipan importación masiva, savepoints, aislamiento, reintentos, cascadas automáticas, migraciones o PostgreSQL.
Evidencia para revisión
  • DDL previsto para FK, UNIQUE(invoice_id, position) y checks monetarios.
  • Cinco pruebas de continuidad verdes y cuatro criterios inicialmente rojos que terminan verdes.
  • Conteo de filas tras creación válida y tras fallo de una línea intermedia.

Reinicio de esta parte: Descomprimir de nuevo esta parte y borrar solo su base local; no copiar los starters guiados de tags, organizaciones o transferencias.

Transferencia: Ante otro caso de uso puedes distinguir FK de Relationship, localizar commits interiores, recuperar la Session tras IntegrityError y elegir una carga por forma de respuesta.

Paso 10 · Evolución verificable

Preserva significado al cambiar el schema

Evidencia: Los ensayos comparan filas antes/después, revisión actual, roundtrip y convergencia; el checkpoint transfiere el mecanismo a un historial nuevo.

EX-B4-13

Reparar un rename que pierde datos

  • Respuesta redactada
  • Revisión de migración y código
  • Media-alta

Autogenerate representó name → display_name como add/drop. Upgrade termina y el schema parece correcto, pero dos activos pierden su nombre.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué evidencia distingue un rename de una eliminación y por qué el modelo final no puede responderla?

Roundtrip con significado

Router Madrid y Laptop Norte sobreviven a 0001 → head y head → 0001 con los nombres de columna esperados.

Para ordenar tu razonamiento

  1. ¿Qué revisión registra la base antes del cambio?
  2. ¿Qué valores sobreviven al candidato actual?
  3. ¿El downgrade restaura datos o solo una columna vacía?

Trabajo en el workspace

  1. Registra history, current, DDL y filas en 0001 antes de aplicar el candidato.
  2. Aplica head, identifica qué operación perdió valores y compara la intención con el diff.
  3. Sustituye drop/add por un rename reversible compatible con el entorno descartable.
  4. Ejecuta upgrade y downgrade desde una base v1 nueva y documenta el límite de recuperación.

Entrega esperada

  • Revisión 0002 corregida y pruebas finales.
  • Tabla de revisión, columnas y valores para cada estado.
  • evidence.md con intención, riesgo, alternativa y condición de parada.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista 1 · Revisa la intención
  • El par add/drop produce la forma final, pero no mueve el valor.
  • Busca una operación que cambie el nombre de la columna existente.
Pista 2 · Prueba ambos sentidos
  • Parte siempre de 0001 con filas nuevas.
  • El downgrade honesto invierte el rename, no crea una columna vacía.
Profundización opcional

Tratar la revisión como un candidato, recuperar la intención de rename y demostrar conservación de valores en ambos sentidos sobre una base v1 poblada.

Contexto adicional

  • Ejecuta baseline y aceptación y conserva la salida inicial.
  • Modifica únicamente la revisión 0002; no reescribas 0001 ni los fixtures.
  • Verifica schema, revisión y filas; un exit code cero no cierra la actividad.

Decisiones abiertas

  • Puedes usar alter_column o batch_alter_table; justifica la opción desde el dialecto y la prueba, no desde preferencia estética.

Cómo revisar tu respuesta

  • Las cinco pruebas baseline y los dos criterios de roundtrip pasan.
  • Upgrade conserva ambos nombres bajo display_name y registra 0002.
  • Downgrade restaura name con los mismos valores y registra 0001.
  • 0001 no se reescribe y no se usa create_all como sustituto de la revisión.
  • La evidencia explica por qué autogenerate no podía inferir la intención.

Evidencia, revisión y reinicio

  • History/current y filas v1 registrados antes del cambio.
  • Cinco pruebas baseline verdes y dos criterios de roundtrip inicialmente rojos.
  • Columnas y valores observados después de upgrade y downgrade.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-13-rename-review.zip y eliminar solo las bases SQLite creadas dentro de ese intento.

Material descargable opcional

  • Starter de rename destructivoEntorno Alembic real con dos revisiones, candidato drop/add, cinco comprobaciones baseline y dos criterios de conservación rojos.

EX-B4-14

Hacer converger un seed sin borrar datos ajenos

  • Respuesta redactada
  • Debugging de datos iniciales
  • Media

El seed del catálogo inserta tres categorías cada vez. Funciona sobre vacío, falla al repetirse y no corrige una etiqueta conocida obsoleta.

Pensar y responder en la web

Predice y guarda aquí tu razonamiento antes de abrir el material; después contrástalo en el workspace.

Pregunta central

¿Qué estado debe producir cualquier número de ejecuciones y cómo limita la clave estable qué filas puede modificar el seed?

Convergencia y propiedad

Dos ejecuciones dejan tres referencias; una ejecución posterior corrige network y conserva custom sin duplicar ni borrar.

Para ordenar tu razonamiento

  1. ¿Qué ocurre exactamente en la segunda ejecución?
  2. ¿Quién posee la fila custom?
  3. ¿Ignorar conflictos actualizaría una etiqueta obsoleta?

Trabajo en el workspace

  1. Predice claves poseídas, filas ajenas y estado tras dos ejecuciones.
  2. Reproduce la violación unique y el caso de etiqueta obsoleta más custom.
  3. Implementa insert/update por clave conocida dentro de una sola transacción.
  4. Repite ambas suites y registra conteos y filas ordenadas.

Entrega esperada

  • Seed convergente y pruebas finales.
  • Matriz antes/después de primera, segunda y ejecución con custom.
  • evidence.md con frontera de propiedad y alternativa descartada.

Escribe lo que piensas. Se guarda automáticamente en este navegador.

Sin respuesta guardada.

Pistas opcionales

Pista única · Converge por clave poseída
  • Para cada referencia, decide insert, update o no-op.
  • No iteres sobre toda la tabla para decidir qué borrar.
Profundización opcional

Convertir la ejecución en una convergencia transaccional sobre claves poseídas y conservar filas que pertenecen al usuario.

Contexto adicional

  • Ejecuta el seed una y dos veces antes de cambiarlo.
  • Conserva la constraint unique y una sola transacción.
  • No borres la tabla, no conviertas el seed en migración y no leas secretos de entorno.

Decisiones abiertas

  • Puedes usar select+insert/update o un upsert del dialecto; explica el coste de portabilidad de la segunda opción.

Cómo revisar tu respuesta

  • Las cinco pruebas baseline y los dos criterios de convergencia pasan.
  • Ejecutar dos veces no falla, no duplica y produce el mismo estado.
  • Una etiqueta de referencia obsoleta converge al valor declarado.
  • La fila custom permanece intacta y no se borra ninguna fila ajena.
  • Todas las modificaciones del seed forman una sola transacción.

Evidencia, revisión y reinicio

  • Claves de referencia y frontera de propiedad predichas antes de editar.
  • Cinco pruebas baseline verdes y dos criterios de convergencia inicialmente rojos.
  • Filas después de primera/segunda ejecución y con una categoría custom.

Revisión: con Codex, utilizando la evidencia y los criterios anteriores; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-14-idempotent-seed.zip y eliminar solo catalog.db si se creó dentro del intento.

Material descargable opcional

Checkpoint independiente · EX-B4-S02-04

Evoluciona asignaciones hacia un historial

Sobre asignaciones v1 pobladas, diseñas rename, status, eventos y backfill desde criterios visibles, sin una revisión resuelta ni pistas.

EX-B4-S02

Evolución del historial de asignaciones

  • Práctica extendida
  • Checkpoint acumulativo
  • Media-alta
  • Apoyo autónomo; criterios visibles, sin pistas ni revisión objetivo
  • M-DB

Una base v1 contiene dos asignaciones. El siguiente schema necesita un rename, estado derivado y eventos históricos sin perder quién recibió cada activo ni cuándo volvió.

Abrir práctica extendida: base común y 1 parte

Base común

  • La revisión 0001 y cinco pruebas de continuidad empiezan verdes; 0002 está vacía y cuatro criterios empiezan rojos.
  • El modelo objetivo y los criterios declaran forma e invariantes, pero no el orden de operaciones ni el código de migración.
  • La base SQLite es descartable; el SQL PostgreSQL offline solo permite leer el dialecto, no sustituye una prueba de servidor.
  • No se publican pistas, solución, API, contenedores, pipeline o estrategia universal sin parada.

Paquete de trabajo

Entorno, evidencia y reinicio

Entorno: Python 3.10+ en un workspace temporal; Alembic 1.18, SQLAlchemy 2, SQLite y pytest, sin servicios externos ni credenciales reales.

  • Grafo, orden de operaciones y filas destino predichos antes de editar.
  • Cinco pruebas de continuidad verdes y cuatro criterios inicialmente rojos.
  • DDL, current y filas después de upgrade y downgrade.

Revisión: con Codex, utilizando los artefactos y criterios de cada parte; no se publica una solución oficial.

Reinicio: Volver a descomprimir ex-b4-s02-04-assignment-history.zip y eliminar solo las bases SQLite creadas dentro de ese intento.

Parte 1 · Apoyo autónomo

EX-B4-S02-04 · Preservar asignaciones al crear su historial

Diseñar una revisión 0002 que preserve asignaciones v1, derive status, backfillee eventos y ofrezca un downgrade honesto sin una secuencia prescrita.

Qué debes hacer
  1. Predice el grafo, DDL, filas y orden de operaciones antes de ejecutar.
  2. Ejecuta continuidad y aceptación y examina metadata, v1 y la revisión vacía.
  3. Implementa rename, status/backfill, constraints, índice, tabla de eventos y tres eventos históricos.
  4. Implementa un downgrade que retire solo v2 y restaure holder_name y las dos filas v1.
  5. Prueba desde v1 poblada y desde vacío; documenta propietario de ejecución, recuperación y parada.
Entrega esperada
  • Revisión 0002 y pruebas propias sin bases SQLite generadas.
  • evidence.md con grafo, DDL, filas, current y SQL offline relevante.
  • Decisión autónoma, alternativa descartada y recuperación honesta.
Criterios de aceptación
  • Las cinco pruebas de continuidad permanecen verdes y los cuatro criterios nuevos pasan.
  • Upgrade preserva Alicia/Bruno, deriva assigned/returned y crea tres eventos con sus fechas.
  • El destino tiene checks nombrados, unique de evento, FK e índice de status.
  • Downgrade restaura el schema v1 y sus valores y elimina únicamente estructuras v2.
  • Una base vacía alcanza 0002 y current coincide con head.
  • No se añaden API, PostgreSQL real, contenedores, CI o ramas Alembic.
Evidencia para revisión
  • Predicción de rename, status, eventos, backfill y constraints.
  • Baseline verde, cuatro fallos iniciales y aceptación final verde.
  • Revisión actual, schema y filas verificados en ambos sentidos.

Reinicio de esta parte: Descomprimir de nuevo el checkpoint y borrar solo su base local; no copiar las revisiones de los ensayos guiados.

Transferencia: Ante otro cambio puedes distinguir estado de historia, revisar autogenerate, probar desde la revisión anterior y declarar un propietario único de ejecución.