Changelog
0.5.4 — 2026-08-11
- TODO: describe changes
0.5.3 — 2026-08-01
- TODO: describe changes
Todos los cambios importantes de fastapi-basekit serán documentados aquí.
El formato está basado en Keep a Changelog, y este proyecto adhiere a Semantic Versioning.
[0.5.2] - 2026-07-17
Corregido
actionresuelve al nombre del endpoint cuando no se llamóprepare_action.BaseController.actionpasó de ser unClassVar(defaultNone) a una@property: usa la acción fijada porprepare_actiony, si no la hay, cae al nombre de la función de endpoint activa (request.scope["endpoint"].__name__). Antes, un endpoint CUSTOM (create/update/… que no delega en el CRUD base y llamaformat_responsedirecto) teníaaction=None, así queget_schema_class()devolvía el schema por defecto (de lista) y la validación delresponse_modelde detalle fallaba conResponseValidationError. Sigue sin filtrarse como?action=(es property, no campo). Compat:self.action = "x"sigue permitido vía setter. NO cambia permisos (prepare_actionsigue siendo necesario paracheck_permissions).
[0.5.1] - 2026-07-17
Seguridad / hardening
- Visibilidad ante filtros de scoping descartados (los 3 ORMs). Cuando un
filtro no resuelve a ningún campo del modelo (typo, columna/relación
inexistente, o clave Mongo mal escrita), el repositorio lo descarta — pero
ahora emite un
logger.warning. Antes desaparecía en silencio: si esa clave venía deget_filters()(scoping por tenant/owner), el listado quedaba SIN ese filtro → fuga cross-tenant / IDOR invisible. El warning hace la pérdida visible en logs/Sentry sin cambiar el resultado de las queries válidas. Aplica abeanie,sqlalchemyysqlmodel. (El passthrough de claves Mongo$or/user.$iden Beanie ya existía desde 0.4.3.)
[0.5.0] - 2026-07-12
⚠️ BREAKING
JWTServiceahora FALLA si faltaJWT_SECRET. Antes caía a una clave pública por defecto (secret_dev_key) y firmaba tokens de producción con un secreto conocido por todo el mundo — cualquiera podía forjar tokens de cualquier usuario. AhoraJWTService()lanzaRuntimeErrorsiJWT_SECRETno está seteado. Migración: seteaJWT_SECRET(≥32 bytes aleatorios) en todos los entornos. Solo para desarrollo local podés setearJWT_ALLOW_INSECURE_DEV_SECRET=1para conservar el comportamiento anterior.
Agregado
- Tipos completos:
Generic[ModelT]+py.typed(PEP 561) en repos y services de los 3 ORMs (SQLAlchemy, SQLModel, Beanie). Parametrizáclass UserRepository(BaseRepository[User])y el CRUD queda tipado (get/create/update/list). Opcional: subclasear sin el parámetro genérico funciona igual (cero cambio en runtime). El marcadorpy.typedhace que los tipos inline lleguen a mypy/Pylance/IDE de los consumidores. Service.post_process_list(items)— hook para enriquecer los items de una página YA paginada (contador, campo derivado, +1await) sin reescribir la paginación ni overridearlist(). Default no-op.- Lectura por id unificada entre ORMs:
get(id)yget_by_id(id)funcionan en los 3 repos (aliases) — código portable entre backends. - Operadores de filtro en SQLModel (
__gte/__lte/__in/__ne/__like/__ilike) — portados desde el repo SQLAlchemy (antes SQLModel los descartaba en silencio y devolvía todo). - Handler de
DomainErrorenregister_exception_handlers— unDomainErrorque escapa del endpoint ahora se mapea a suSTATUS_CODE_MAP(antes caía al 500 genérico). fastapi_basekit/py.typedempaquetado (PEP 561).- Doc
docs/pagination-extension-points.md— referencia autoritativa de los puntos de extensión de listado/paginación (destilada de proyectos reales).
Cambiado
BaseController._paramssin introspección de stack-frames. Reconstruye los parámetros leyendorequest.query_paramsy coaccionándolos a los tipos DECLARADOS en la firma del endpoint (request.scope["endpoint"]), de forma determinista y cacheada por endpoint (~148x menos cómputo que recomputar la firma). Arregla listados vacíos/errores intermitentes en controllers cbv causados por elskip_framesmágico. Se conserva el parámetroskip_frames(deprecado, ignorado) para back-compat con mixins que overridean_params.- Coerción de query params por tipo completo: además de bool/int/float, los
tipos ricos (
date,datetime,UUID,Decimal,Enum) se coaccionan conpydantic.TypeAdapter— el mismo motor que FastAPI — para que un filtro por fecha/uuid reciba el objeto tipado y no el string. - Fix mutable-default por instancia portado a los services SQLAlchemy y
SQLModel (antes solo estaba en Beanie): mutar
self.search_fieldsya no contamina la clase ni otras requests. - Extras usan
psycopg2-binaryen vez depsycopg2(evita build de fuente).
[0.4.3] - 2026-07-10
Agregado
BaseRepository.paginate_keyset(Beanie). Paginación por cursor (keyset) como alternativa O(1)/página apaginate: filtra porcursor_fieldy traelimit + 1para reportarhas_moresincount()niskip(). Para listados que escalan (historiales de chat, feeds, tablas append-only) donde la paginación offset degrada con la profundidad. Aditivo:paginateno cambia.
Cambiado
BaseService(Beanie): defaults mutables ahora son por instancia.search_fields,duplicate_check_fieldsykwargs_queryse copian en__init__(list(...)/dict(...)). Mutarlos en runtime ya no se filtra al atributo de clase (contaminación cross-request en el mismo proceso). El override por subclass se preserva intacto.BaseRepository.paginate_pipelineya no descarta filas en silencio. Una fila que fallamodel_validatese loguea (antes:except: continuemudo, que devolvía menos ítems que ellimitsin aviso). Se sigue omitiendo la fila corrupta para no romper el listado completo.
[0.4.2] - 2026-06-18
Agregado
- Política de borrado configurable en
BaseService. Nuevodelete_modede clase con cuatro modos: "hard"(default, comportamiento histórico) — elimina físicamente."soft"— marcadeleted_at(requiere modelo consoft_delete())."soft_mangle"— soft + renombramangle_fields(<valor>__del_<id>) para liberar un valor único y poder recrear el registro (evita choque del unique al borrar+recrear el mismo email/cédula/nombre)."hard_if_unused"— elimina físicamente si no está referenciado; si lo está (segúndelete_references = [(Model, "fk_attr"), ...]) levanta 409.BaseService.apply_delete(obj)aplica la política sobre una entidad ya cargada (para subclases que scopean el objeto antes de borrar);delete(id)la usa por defecto.BaseRepository.save(obj)yBaseRepository.hard_delete(obj)para persistir entidades mutadas y eliminar físicamente sin tocar la sesión desde el servicio.
[0.4.1] - 2026-06-10
Corregido
actionahora es filtrable. Se quitó"action"de_params_excluded_fields(controllersaioyaio/sqlalchemy). El leak del?action=espurio ya lo evita elClassVardeBaseController.action(0.4.0), así que excluirlo del set de filtros era redundante y rompía filtrar por una columnaactiondeclarada como query param (ej. un endpoint de audit-logs con?action=...). Test de regresión inversa agregado.
[0.4.0] - 2026-06-09
Mejoras de controller/repository + helpers de cableado reutilizables.
Agregado
register_exception_handlers(app)— cablea el set completo de handlersexcepción → BaseResponseen una sola llamada (antes cada proyecto copiaba el mapeo). Suma handler de SQLAlchemyIntegrityErrory un handler deRequestValidationErrorque devuelve el envelope sin relanzar.simplify_openapi(app)— limpia losoperationId/summarygenerados por controllers@cbv(quita el prefijo de claseUserController.), consummary_overridesopcional por operación.- Filtros con operadores en
BaseRepository: sufijocampo__opcongte/gt/lte/lt/ne/in/like/ilike. El operador por defecto (eq) conserva la semánticaINpara valores de lista; no rompe los paths de relación (user__role__code).
Corregido
actionya no se filtra como query param espurio en cada ruta@cbv: se declaraClassVarpara quefastapi-restfulno lo promueva.prepare_actionsigue asignandoself.actionen runtime._params()ahora respeta_params_excluded_fields(estaba definido pero sin usar) y el set incluyeaction.prepare_actionpropaga la acción canónica (list/retrieve/...) aservice.action(antes el service la derivaba del nombre de la función del endpoint, p. ej.list_users, poco fiable paraget_kwargs_query).BasePaginationResponse.paginationahora tiene defaultNone(en Pydantic v2 era un campo requerido).
[0.3.5] - 2026-05-20
Release de plugin/skill — sin cambios en el código de la librería
(pyproject.toml permanece en 0.3.3).
Agregado
- Nueva skill
fastapi-basekit-sentry— codifica el patrón de observabilidad Sentry/GlitchTip implementado eneventsvileads_backend. Contempla: app/utils/observability.pyconinit_sentry,capture_exceptiony_scrub_event(before_send hook que filtraauthorization,cookie,x-api-key,stripe-signature- body keys
password,secret,token,api_key,refresh_token,access_token,credit_card,card_number,cvv).
- body keys
- Captura por excepción desde
app/utils/exception_handlers.py(cero middleware nuevo, cero overhead en responses 2xx) con nivelwarningpara 4xx yerrorpara 5xx. init_sentry()llamado enapp/main.pyANTES decreate_application()para que las integraciones (Starlette,FastAPI,Sqlalchemy,Redis) parchen las libs antes de que se instancien.- Settings (
SENTRY_DSN,SENTRY_ENVIRONMENT,SENTRY_RELEASE,SENTRY_TRACES_SAMPLE_RATE,SENTRY_PROFILES_SAMPLE_RATE,SENTRY_SEND_PII) consend_default_pii=Falsepor default (PII discipline). - Pin de dependencia
sentry-sdk[fastapi]>=2.10,<3.0. - GlitchTip-compatible (mismo DSN, mismo formato — self-host gratis).
- No-op silencioso si SDK no instalado o DSN vacío. Incluye checklist de verificación, pitfalls comunes y guía de cuándo desviarse del patrón.
[0.3.4] - 2026-05-18
Release de plugin/skill — sin cambios en el código de la librería
(pyproject.toml permanece en 0.3.3).
Agregado
- Skill
fastapi-basekit-crud— regla "Core rule — every function has a home (no orphan helpers)". Controllers, services y repositories no llevan funciones auxiliares sueltas; cada tipo de lógica tiene un hogar único: serialización → schema (BaseSchema+@computed_field), factories →dependency.py, helpers locales →app/utils/, reusables → la librería, errores de dominio → unDomainErrorbase. Incluye un ejemplo trabajado (_to_responsemal vs bien). - Skill
fastapi-basekit-crud— §30 "List endpoints with filters — NEVER reimplement basekit". Documenta el flujo completo delist()(params →get_filters→build_list_queryset/build_list_pipeline→ paginación), el patrón correcto de controller y service, qué acepta elfiltersdict, y los anti-patrones rechazados en review.
[0.3.3] - 2026-05-02
Agregado
-
BaseController.prepare_action(action_name)(fastapi_basekit/aio/controller/base.py). Punto único del lifecycle de cada acción: seteaself.actiony correcheck_permissions(). Idempotente por instancia — invocaciones repetidas con el mismoaction_nameno re-disparan checks. Llamado automáticamente al inicio de cada CRUD estándar (list,retrieve,create,update,delete) en el base + variantes SQLAlchemy / SQLModel / Beanie. Métodos custom deben llamarlo manualmente si quieren el flujo automático. -
permission_classes: List[Type[BasePermission]]yget_permissions()estilo DRF enBaseController. Overrideget_permissions()para despachar permisos porself.action: -
check_permissions_class()retro-compat. Alias del nuevocheck_permissions()para controladores pre-0.3.3 que llamaban manual el chequeo desde cada endpoint.
Cambiado
format_responseahora permisivo: cuando eldata(dict / objeto) no satisface elschema_classdel controlador, devuelve el valor crudo en vez de levantarValidationError. Útil para endpoints custom que retornan dicts ad-hoc sin definir un schema dedicado.
Tests
- 134 tests passing across the three ORMs (Beanie, SQLAlchemy, SQLModel).
- Suite previously broken (
test_controller_auto_permissions.py— 17 fails) ahora 100% green tras corrección de bugs en los tests: service = serviceshadowing en class body dentro de funciones asyncHTTPXAsyncClient(app=app)deprecated en httpx ≥0.27 →ASGITransport- Fixtures con
@app.getsobre clases sin__call__→ reemplazadas por el router canónicoexample_crud.controller.routercon@cbv - Status code esperado en POST: 200 → 201
[0.3.2] - 2026-05-01
Agregado (Beanie)
-
BaseRepository.build_list_querysetybuild_list_pipeline(fastapi_basekit/aio/beanie/repository/base.py). Hooks de extensión equivalentes albuild_list_querysetde SQLAlchemy para componer queries en endpointslist. Default delega abuild_filter_query/ pipeline básico ($match+$sort). Subclases override para añadir$lookup,$project,$group, etc. — i.e. subqueries / JOINs sin tocar controlador ni servicio CRUD. -
BaseRepository.paginate_pipeline(pipeline, page, count, validate=True)Ejecuta un pipeline arbitrario envuelto en$facet(paginación + total en una sola query).validate=Falsecuando el$projectproduce una forma plana distinta del modelo (joined columns). -
BaseService.use_aggregation: bool = Falseyaggregation_validate: bool = True. Flag de servicio para forzar la ruta de aggregation pipeline (sin depender deorder_byanidado). Cuandoaggregation_validate=False, los dicts crudos del pipeline se devuelven sin validar contra el modelo (útil cuando el$projectaplana subqueries). -
BaseService.build_list_querysetybuild_list_pipeline(fastapi_basekit/aio/beanie/service/base.py). Hooks a nivel servicio que delegan en el repositorio. Override en el servicio para añadir lookups/proyecciones por endpoint sin contaminar el repo.
Cambiado (Beanie)
-
BaseService.listahora ramifica entreFindManyy aggregation pipeline segúnuse_aggregationoorder_byanidado. La lógica previa se preserva como ruta default; subclases que ya funcionaban no necesitan cambios. -
BaseRepository.list_with_aggregationse conserva como wrapper retrocompatible que delega abuild_list_pipeline+paginate_pipeline.
Patrón de uso
class AdminUserService(BaseService):
repository: UserRepository
use_aggregation = True
aggregation_validate = False
def build_list_pipeline(self, search=None, search_fields=None,
filters=None, order_by=None, **kwargs):
pipeline = self.repository.build_list_pipeline(
search=search, search_fields=search_fields,
filters=filters, order_by=order_by or "-created_at",
)
pipeline.extend([
{"$lookup": {"from": "wallets", "localField": "_id",
"foreignField": "user.$id", "as": "wallet_data"}},
{"$unwind": {"path": "$wallet_data",
"preserveNullAndEmptyArrays": True}},
{"$project": {
"id": {"$toString": "$_id"},
"wallet_balance": {"$convert": {
"input": "$wallet_data.balance",
"to": "string", "onNull": None,
}},
# ... resto del project
}},
])
return pipeline
El controlador solo expone super().list() — toda la composición vive
en el pipeline declarativo del servicio.
[0.3.1] - 2026-04-29
Agregado
BaseRepository.build_filter_query— alias<field>_idpara camposLink[X](fastapi_basekit/aio/beanie/repository/base.py). Permite filtrar conversaciones/mensajes/cualquier modelo con Link sin conocer la sintaxis Mongo nested (customer.$id): Reglas de resolución (en orden):- Key con
.o$→ passthrough Mongo (customer.$idsigue funcionando). hasattr(model, key)true:- Es
Link[X]→model.<key>.id == ObjectId(v) - No-Link →
model.<key> == v
- Es
- Key termina en
_idymodel.<base>esLink[X]→model.<base>.id == ObjectId(v)(alias). -
Sin match → ignora silenciosamente (igual que antes).
-
Helper interno
_coerce_objectid()— conviertestr/ObjectIdaObjectIdautomáticamente cuando la query es contraLink.id. Evita que el caller tenga que castear manualmente al pasar query params del API.
Cambiado
- Mínimos de dependencias:
pydantic>=2.13.0,<3(era>=2.11.7,<3)pyjwt>=2.12.1(era>=2.10.1)- extras
[beanie]:beanie>=2.0,<3(era>=1.24.0);motorremovido porque basekit no lo usa en runtime (sólo en templates cookiecutter). - extras
[sqlalchemy]:SQLAlchemy[asyncio]>=2.0.30,<3(era>=2.0.0).
Corregido
- Import roto:
from bson import ObjectId, Link→from beanie import Linkenaio/beanie/repository/base.py.Linkno existe en el paquetebson; estaba enbeanie.odm.fields.Linkre-exportado enbeanie.__init__. En 0.3.0 el import explotaba al cargar tests aislados aunque la app real toleraba el side-effect por orden de carga del intérprete.
0.3.0 - 2026-04-26
Agregado
basekit init— scaffolder cookiecutter (pip install fastapi-basekit[init])- CLI
basekitcon subcomandosinityversion. - Template completo en
fastapi_basekit/templates/project/con conditionals Jinja. - Choices:
orm(sqlalchemy/beanie),database(postgres/mariadb/sqlite/mongodb),server(uvicorn/gunicorn),cache(none/redis),background_tasks(none/arq),bucket(none/s3),include_alembic,include_docker,license. - Hooks
pre_gen_project.py(valida orm↔db) ypost_gen_project.py(poda archivos no usados). - Genera
app/completo (config, models, repos, services, controllers, middleware, permissions, schemas, scripts, utils),alembic/,docker-compose.yml,Dockerfile,Makefile,.env.example,LICENSE,pytest.ini,requirements.txt,README.md. -
Boot end-to-end verificado:
make up-d→make migrate-up→make seed→ login. -
Sitio de documentación MkDocs Material (
pip install fastapi-basekit[docs]) - 22+ páginas: getting-started, user-guide, advanced, api-reference, examples.
- Hero CSS custom con gradient + grid pattern + cards con hover lift.
- Mermaid diagrams con tema custom basekit (teal + accent orange).
- Versionado con
mike: aliaseslatest,X.Y,dev. -
Auto-deploy a GitHub Pages vía workflow.
-
Workflows GitHub Actions reestructurados
release.yml— tagv*push → PyPI (OIDC trusted publishing) + mike-versioned docs.workflow_dispatchcon inputsversion/pypi/deploy_docspara releases parciales.docs.yml— push a main con cambios doc-relevantes → deploya aliasdev(preview).-
Concurrencia + permisos OIDC + cache pip configurados.
-
Comando único de release (
scripts/release.py) - Bumpea atómicamente
pyproject.toml,plugin.json,marketplace.json,CHANGELOG.md. - Valida semver + working tree limpio + tag no existe.
- Commit + tag + push con
--follow-tags. - Modos:
--bump patch|minor|major,--dry-run,--pypi-only,--docs-only,--no-changelog. -
Makefile targets:
release V=,release-no-docs,release-docs-only,release-dry. -
Skill
fastapi-basekit-crudv2 (.claude/skills/fastapi-basekit-crud/SKILL.md) -
Secciones nuevas: §22 servicios deben extender
BaseService(incluso no-CRUD), §23 alembicrender_itemparaGUID+LowercaseEnum, §24 API real deJWTService(create_token, NOencode_token), §25 política de extenderSQLAlchemyBaseController, §26 pinning de deps, §27 checklist sync→async migration, §28get_dblean (translation en handlers, no en generator). -
Documentación interna
RELEASING.md - Guía completa para mantenedores: setup PyPI OIDC, GitHub Pages bootstrap, release flow, modos parciales, mike aliases, troubleshooting (8 escenarios), checklist.
Corregido
BasePaginationResponse[Schema](no[List[Schema]])BasePaginationResponseya declaradata: List[T]. Wrappear conList[]doble-anida aList[List[T]]y Pydantic itera filas como tuplas(field, value)→ 8 errores per row.-
Fix en swapdealer + skill + template cookiecutter.
-
Mermaid runtime en docs (Material 9.7+)
- Material removió auto-bootstrap de mermaid.
-
Carga explícita CDN + init script con tema matching + hook re-render en instant nav.
-
Alembic
render_itempara tipos custom - Sin esto, autogen emite
app.models.types.LowercaseEnum(...)literal →NameErroren upgrade. - Renderiza
GUIDyLowercaseEnumcomosa.String(length=N).
Cambiado
-
get_dblean — soloyield + commit / except: rollback + raise. Translation de errores (IntegrityError → mensaje friendly) vive enapp/utils/exception_handlers.py, registrado globalmente. Saca domain knowledge del session generator. -
self.actionautomático en controllers/services —BaseController.__init__lo asigna desderequest.scope["endpoint"].__name__. Skill actualizada: nunca asignar manual, branch enself.action == "method_name". -
mkdocs.yml —
pymdownx.emojiconmaterial.extensions.emoji.twemoji, custom palette (teal/deep-orange), font Inter + JetBrains Mono, navigation features ampliados.
Empaquetado
- Optional extras nuevos:
[init](cookiecutter),[docs](mkdocs-material + mkdocstrings). [project.scripts]registrabasekit = "fastapi_basekit.cli:main".package-dataincluye templates en el wheel.
0.2.0 - 2026-02-27
✨ Agregado
- Soporte para SQLModel ORM (
fastapi_basekit.aio.sqlmodel) BaseRepository— repositorio async consqlmodel.ext.asyncio.session.AsyncSession. Usasession.exec()para queries tipados sobre modelos SQLModel; mantienesession.execute()para consultas de agregación y queries complejos con Result Hydration. Contrato idéntico al repositorio SQLAlchemy.BaseService— servicio base que referencia el repositorio SQLModel. Mismas operaciones:retrieve,list,create,update,delete.SQLModelBaseController— controlador base con soporte parajoins,use_oryorder_by. La serialización aprovecha que los modelos SQLModel son también modelos Pydantic (model_dump()nativo).-
to_dict()simplificado en el controlador gracias a la integración Pydantic de SQLModel. -
Dependencia opcional
sqlmodelenpyproject.toml - Instalar con:
pip install fastapi-basekit[sqlmodel] - Incluido en el extra
[all].
0.1.25 - 2026-02-11
✨ Agregado
- Vínculo bidireccional Servicio-Repositorio
BaseRepositoryahora tiene un atributoserviceque referencia al servicio que lo utiliza.BaseServicevincula automáticamente su instancia (self) a todos los repositorios inyectados durante la inicialización.
🔧 Cambiado
- Refactor de Construcción de QuerySet
- Se eliminó el método redundante
build_querysetdeBaseService. - El método
BaseRepository.list_paginatedahora es el único responsable de iniciar la construcción del query a través debuild_list_queryset(). - Se simplificó la firma de
list_paginatedeliminando el parámetrobase_query. BaseService.listahora es más limpio al delegar la gestión del query completamente al repositorio.
🔧 Mejorado
- Inicialización de Servicios
BaseService.__init__ahora acepta**kwargsy vincula automáticamente cualquier instancia deBaseRepositorypasada como argumento nombrado, permitiendo que servicios complejos con múltiples repositorios mantengan el vínculo correctamente.
0.1.16 - 2025-10-14
✨ Agregado
-
Controllers completamente separados por ORM/ODM
-
BeanieBaseController: Controller específico para proyectos con MongoDB/Beanie SQLAlchemyBaseController: Controller específico para proyectos con SQLAlchemy- Cada controller tiene implementación completa y optimizada para su ORM/ODM
-
Ya no hay herencia de un
BaseControllergenérico compartido -
SQLAlchemyBaseController: Nuevas capacidades
-
Soporte completo para JOINs con
joinsparameter - Soporte para expresiones
ORDER BYpersonalizadas - Operador
ORen filtros conuse_or=True - Método
to_dict()mejorado para modelos SQLAlchemy -
_params_excluded_fieldsincluye automáticamenteuse_or,joins,order_by -
BeanieBaseController: Optimizado para MongoDB
-
Implementación optimizada para documentos Beanie
- Extracción automática de parámetros sin frames extras
-
Método
to_dict()específico para documentos MongoDB -
Documentación completa
- Nuevo archivo
CONTROLLERS_GUIDE.mdcon guía detallada - Ejemplos de uso para cada controller
- Tabla comparativa de características
- Guía de migración desde versiones anteriores
🔧 Cambiado
-
Dependencias más flexibles
-
fastapi:>=0.116.1,<0.117(antes:==0.116.1) pydantic:>=2.11.7,<3(antes:==2.11.7)fastapi-restful[all]:>=0.6.0,<0.7(antes:==0.6.0)SQLAlchemy[asyncio]:>=2.0.43,<3(antes:==2.0.43)-
psycopg2:>=2.9.10,<3(antes:==2.9.10) -
BaseController.format_response()
- Parámetro
statusrenombrado aresponse_statuspara evitar conflictos - Mejora la compatibilidad con imports de Starlette/FastAPI
🐛 Corregido
-
_params()ahora funciona correctamente en SQLAlchemyBaseController -
Solucionado problema de introspección de frames
- Agregado parámetro
skip_framespara navegar correctamente en la pila -
SQLAlchemy ahora usa
skip_frames=2para capturar parámetros correctamente -
Eliminado conflicto con parámetro
status - El parámetro
statusenformat_response()podía generar conflictos - Ahora se llama
response_statuspara mayor claridad
📚 Documentación
- README actualizado con sección de controllers separados
- Guía completa en
CONTROLLERS_GUIDE.md - Ejemplos actualizados para ambos controllers
- Tabla comparativa de características
🔄 Migración desde v0.1.15
Antes:
Ahora:
# Para SQLAlchemy
from fastapi_basekit.aio.sqlalchemy import SQLAlchemyBaseController
# Para Beanie
from fastapi_basekit.aio.beanie import BeanieBaseController
El BaseController genérico sigue disponible para compatibilidad, pero se recomienda usar los controllers específicos.
0.1.15 - 2025-10-XX
Agregado
- Controller base genérico con soporte para Beanie y SQLAlchemy
- Sistema de permisos basado en clases
- Extracción automática de parámetros con
_params() - Paginación automática
- Búsqueda multi-campo
Cambiado
- Mejoras en la estructura del proyecto
0.1.0 - 2025-XX-XX
Agregado
- Versión inicial de fastapi-basekit
- Soporte básico para SQLAlchemy y Beanie
- Repositorios base
- Servicios base
- Schemas base