Changelog & Release Notes
Track the evolution, architectural refinements, breaking changes, and security fixes across ZCore Framework releases.
This page documents all notable architectural evolutions, breaking changes, security patches, and migration paths across ZCore releases.
Upgrading ZCore: To fetch the latest pre-release build, run:
pip install --upgrade "fastapi-zcore-framework[all]==0.1.0rc2"Welcome to v0.1.0-rc.2 (Release Candidate 2) of the ZCore Framework! ๐
As we approach the final validation phase before tagging our official v1.0.0 Stable GA, v0.1.0-rc.2 focuses on framework-wide error normalization, operational robustness, and developer ergonomic refinements.
This release introduces an automated, normalized exception handling system conforming all HTTP errors to the ResponseWrapper envelope; implements an end-to-end soft-delete, restoration, and forced hard-delete lifecycle; scaffolds a high-performance, schema-projected /lookup endpoint; expands the dynamic AST search engine with negated operators and logical NOT grouping; establishes re-entrant, depth-aware Unit of Work coordination; generalizes user identifiers (int, str, UUID) across all subsystems; and introduces schema-level private field shielding for unauthenticated guests.
๐ Core Features & Architectural Advancements
1. ๐ก๏ธ Unified Exception Handling & Error Normalization (ResponseWrapper)
All HTTP exceptions, validation failures, and internal server errors now strictly conform to the ResponseWrapper JSON envelope:
- Pydantic Error Sanitization (
_sanitize_error_item,_format_error_location): Converts raw Pydantic errorloctuples into readable dot-separated paths (e.g.,body.email,query.limit) and safely extracts validation context. - Standardized Handlers:
request_validation_exception_handler: Formats 422 errors with clean field-level error lists and a human-readable summary.http_exception_handler: Preserves original response headers while wrapping Starlette/FastAPIHTTPExceptioninstances.response_validation_exception_handler: Intercepts internal schema mismatch errors (500) and displays field diagnostics only whensettings.DEBUGis enabled.unhandled_exception_handler: Catch-all fallback for uncaught runtime crashes with debug-gated stack traces.
- Centralized Registration (
register_exception_handlers): Attach all handlers with a single call toregister_exception_handlers(app)with selective inclusion flags. - Lazy Module Packaging: Handlers are exported at the root package level via dynamic
__getattr__resolution to prevent circular import overhead.
2. ๐๏ธ End-to-End Soft-Delete Lifecycle & Restoration (restore, force)
Soft deletion is now seamlessly integrated across the Repository, Service, and Web layers:
- Atomic Batch Soft-Delete:
delete_multi()executes atomicUPDATE ... SET deleted_at=now()with SQL dialect-awareRETURNINGsupport and pre-fetch fallbacks. - Single & Batch Restoration: Added
restore(target)andrestore_multi(ids)toWriteRepositoryMixinandWriteServiceMixinto recover soft-deleted records (deleted_at=None). - Forced Physical Hard Deletes: Added
force: bool = Falseacross repository, service execution orchestrators, and lifecycle hooks (pre_delete,post_delete,pre_delete_multi,post_delete_multi). - Web Router Query Flag: Auto-scaffolded DELETE endpoints accept
?force=true(e.g.,DELETE /tasks/{id}?force=true) to permanently purge records when requested.
3. ๐ Lightweight LOOKUP Endpoint & Schema-Driven Projections (POST /lookup)
Designed for autocomplete selectors, dropdown lists, and relational references:
- Automatic Schema Projection (
_resolve_lookup_projections): Introspectslookup_schemaagainst SQLAlchemy model metadata to selectively generateload_only(*columns)statements, always including primary keys. - Automatic Eager-Loader Configuration: Detects relationships declared in
lookup_schemaand attaches optimal loader strategies (selectinloadfor collections,joinedloadfor scalar relations). - Strict Whitelist Protection (
allowed_lookup_fields): Client queries attempting to filter or sort on unauthorized fields are immediately rejected with a 400ValidationError. - RBAC Integration: Mapped to
Actions.LOOKUP(model.actions().LOOKUP) for granular permission checks.
4. โก Search Engine Negation & Logical NOT Grouping (SearchEngine)
The dynamic JSON search engine now supports inverted filter operations:
- Inverted Operators: Added
not_like,not_ilike,not_contains,not_startswith,not_endswith,not_in,not_between, andis_not_null. - SQL Expression Wrapping:
_compare_columndetectsnot_prefixes and wraps clauses in SQLAlchemy'snot_()expression. - Logical
NOTBlocks: Evaluates nested filter groups underop="not"asnot_(and_(*sub_exprs))or single-field inversions. - Null Semantics:
is_nullandis_not_nullnow accept boolean flags (True/False) orNonevalues consistently.
5. ๐ Re-entrant Unit of Work & Deferred Domain Events (UnitOfWork)
Coordinates multi-service business transactions across complex modular monolith architectures:
- Depth-Aware Re-entrancy (
uow_depth): Tracks execution nesting depth insession.info['uow_depth']. NestedUnitOfWorkblocks execute safe intermediatesession.flush()calls, delegating the physicalsession.commit()solely to the outermost root boundary. - Buffered Post-Commit Events: Domain events registered via
uow.register_event()across nested scopes accumulate insession.info['uow_events']and dispatch atomically only after the root transaction commits. - Global Rollback Safeguard: Any unhandled exception resets depth to
0, clears pending events, and executes an immediate session rollback.
6. ๐ Polymorphic User Identifiers (int, str, UUID)
Removed strict uuid.UUID type enforcement from core identity layers:
- Polymorphic
ZContext&UserProtocol:ZContext.user_idandUserProtocol.idnow acceptAny | None(supporting integer IDs, UUIDs, Auth0/Firebase string IDs, or custom tenant keys). - Real-time Streaming (
StreamManager): Subscriber mapping queues (users_queues) now accept arbitrary user ID types with mixed-type string comparison routing. - Cursor Pagination PK Inspection: Keyset cursor pagination dynamically inspects column types (
mapper.primary_key[0].type.python_type), coercing cursor payload keys tointorUUIDautomatically.
7. ๐ Optional Authentication & Schema-Level Private Fields (Zchema.__private__)
Enables clean guest-friendly routes and sensitive field filtering:
- Optional Authentication (
BaseAuth(auto_error=False)): Allows endpoints to accept optional authentication without raising401 Unauthorizedon missing or invalid tokens. - Dependency Anchor (
get_optional_user_stub): Exported acrosszcoreandzcore.securityfor optional route parameters. - Private Field Pruning (
__private__): Schemas can declare sensitive fields via__private__: ClassVar[set[str]] = {"cost_price", "notes"}. ZCore automatically prunes these fields from response payloads, input validations, and generated JSON schemas (?schema=true) when no authenticated user is present.
8. โ๏ธ Tunable Framework Settings & Dynamic Bounds Validation
Replaced magic numbers across subsystems with environment-driven settings in Settings:
- Subsystem Tuning: Added
PAGINATION_DEFAULT_SIZE(20),PAGINATION_MAX_SIZE(100),SEARCH_MAX_DEPTH(3),CACHE_LOCAL_MAXSIZE(1000),CACHE_DEFAULT_TTL(3600),CACHE_EVICTION_INTERVAL(60),STREAM_QUEUE_MAXSIZE(100), andAUTH_CACHE_TTL(300). - Dynamic Parameter Validation: Added Pydantic
@model_validatoracrossPageNumberParams,CursorParams, andSearchRequestto clamp requested page sizes within configured minimum and maximum boundaries.
9. ๐งช Advanced Testing Harness & Sandboxing Engine (zcore.testing)
- Database Table Lifecycle (
setup_test_database): Drop and recreate test database tables across sync fixtures or running event loops viaThreadPoolExecutorsafely. - Event Sandboxing (
EventDispatcherSandbox): Snapshots and restores registered event subscribers across test runs, eliminating listener pollution. - Multi-Dependency Overrides:
DatabaseRollbackandZTestClientsupport custom engine injections, multiple authentication stub overrides, and strict Pydantic user model validation (user_model).
10. ๐ชต Non-Intrusive Logging & Scope Context Isolation
- Status-Code-Aware Exception Logging: Application and HTTP exceptions log at
DEBUGfor client errors (< 500) andERRORfor server failures (>= 500). - Independent Slow-Query Interceptor: Slow queries exceeding
slow_query_threshold_msare logged even if generallog_sql_queriesis disabled. - Developer Console Mode: Development mode preserves native Uvicorn console formatting via
passthrough_loggers, switching cleanly toProcessorFormatterJSON rendering in production. - Background Scope Context:
background_scopeisolates Structlog contextvars, bindstask_id=scope_id, and restores parent context on exit.
11. ๐ฅ๏ธ Cascading CLI Server Configuration & Dynamic Scaffolding
- Cascading Precedence (
zc run): Server parameters resolve with the precedence:CLI Arguments > .env File > Defaults. - Transparent Uvicorn Passthrough: Uses
parse_known_args()to forward arbitrary flags (e.g.,--root-path,--proxy-headers) directly to Uvicorn. - Multi-Worker Safety: Automatically disables
--reloadwhen--workers > 1. - Dynamic Test Filename Pattern:
zc startapp <app_name>generates Pytest files following standard naming conventions (test_<app_name>.py).
โ ๏ธ Breaking Changes & Migration Guide
Replace manual exception handler bindings in main.py with the unified register_exception_handlers utility.
# Before (v0.1.0-rc.1)
from zcore.exceptions import AppException, app_exception_handler
app.add_exception_handler(AppException, app_exception_handler)
# After (v0.1.0-rc.2)
from zcore import register_exception_handlers
register_exception_handlers(app)Welcome to v0.1.0-rc.1 (Release Candidate 1) of the ZCore Framework! ๐
As we officially transition from the Beta phase toward our milestone v1.0.0 Stable GA, v0.1.0-rc.1 marks a major milestone in framework stability, security hardening, and production readiness.
This release delivers dynamic primary key detection across REST endpoints, introduces an anti-shadowing weighted route sorting algorithm, optimizes ORM mutations to accept model instances directly (bypassing duplicate database fetches), adds dialect-aware batch fallbacks for non-RETURNING databases (such as MySQL), integrates a centralized IANA timezone subsystem (ZDateTime), redesigns the structured logging pipeline via ProcessorFormatter, completely hardens the file storage layer with strict sandboxing and active XSS/executable scanning, and achieves complete unit and integration test coverage across all subsystems.
๐ Core Features & Architectural Advancements
1. ๐ฏ Dynamic Primary Key Resolution & Generalized Routing (BaseRouter)
Previously, BaseRouter assumed model primary keys were strictly UUIDs. In v0.1.0-rc.1, routing infrastructure dynamically inspects ORM metadata:
- Automatic PK Type Detection (
_resolve_pk_type): Automatically resolves whether the primary key is anint,uuid.UUID, or other scalar type via SQLAlchemy column inspection. - Dynamic Path Mapping (
_get_pk_path): Generates type-safe URL converter paths (e.g.,/{id:int}for integer PKs,/{id:uuid}for UUIDs, or/{id}as a fallback). - Explicit PK Override: Models or routers can explicitly declare
pk_type = intto override dynamic reflection. - Streamlined Endpoint Signatures: Cleaned up internal wrapper signatures by removing unused
**kwargsand enforcing explicit parameter typing.
2. โ๏ธ Weighted Route Specificity Sorting (Anti-Path Shadowing)
A notorious issue in REST frameworks is Path Shadowingโwhere dynamic parameterized routes accidentally capture requests intended for static endpoints (e.g., GET /{id} shadowing POST /search):
- Multi-Tier Weighted Scoring (
_sort_routes): Replaced basic string sorting with an advanced scoring tuple:(has_dynamic, total_dynamic, segment_scores, -len(segments)). - Strict Route Precedence: Guarantees that static segment routes (
/search) are always matched before single dynamic parameters (/{id}) and catch-all path parameters (/{path:path}), regardless of declaration order.
3. โก Optimized Instance-Aware ORM Mutations (update, delete, update_multi)
To eliminate redundant database lookups when an entity is already loaded in memory:
- Direct Model Acceptance:
BaseRepository.update()andBaseRepository.delete()now accepttarget: ModelType | Any. If a model instance is passed directly, the preliminarySELECTquery is completely skipped. - Instance-Keyed Batch Updates:
update_multinow accepts dictionaries keyed by either model instances or primary key scalars (dict[ModelType | Any, BaseModel]), resolving the PK seamlessly viagetattr(key, self.pk_name, key). - Aligned Service Hooks: Updated
pre_update,on_update,pre_delete, andon_deleteinBaseServiceto accepttarget: ModelType | Any.
4. ๐ Cross-Dialect Batch Compatibility (Dialect-Aware Fallbacks)
Enables seamless database portability across SQL engines that lack native RETURNING support:
- Dialect-Aware
create_multi: Inspects the engine'sinsert_returningcapability. If supported (PostgreSQL, modern SQLite), it executesinsert().returning(). Otherwise (MySQL, older SQLite), it falls back gracefully todb.add_all()anddb.flush(). - Dialect-Aware
delete_multi: Inspectsdelete_returning. If unsupported, it fetches records viaget_by_ids()prior to atomic deletion, guaranteeing deleted instances are returned intact.
5. โฑ๏ธ Centralized Timezone Management & ZDateTime Subsystem
Introduced zcore.utils.timezone for robust, timezone-aware datetime manipulation:
- IANA ZoneInfo Resolution (
get_app_timezone): Resolves timezones with LRU caching and falls back safely to UTC if an invalid timezone is provided. ZDateTimeType Alias: Custom type alias utilizing Pydantic'sPlainSerializerto automatically format datetimes as timezone-aware ISO 8601 strings with offsets during JSON serialization.- Timezone-Aware Helpers: Added
now(),utc_now(),to_app_timezone(), andformat_iso_with_app_timezone(). - Soft Delete & JSON Sync:
SoftDeleteMixinandCustomJSONEncodernow natively utilize timezone-aware timestamps. - Windows Support: Added
tzdata>=2024.1for guaranteed IANA timezone database resolution on Windows environments.
6. ๐ชต Enterprise Structured Logging (LoggingSettings & ProcessorFormatter)
Redesigned the logging pipeline to seamlessly unify structlog and Python's standard logging library:
ProcessorFormatterIntegration: Eliminates duplicate log emissions and bridges third-party loggers (uvicorn,sqlalchemy.engine) into a unified structlog pipeline.LoggingSettingsModel: Configured viaSettings.LOGGINGwith backward-compatible bidirectional synchronization to legacyLOG_LEVEL.- Slow Query Interceptor: Added
slow_query_threshold_msto silently filter out fast queries and log only statements exceeding latency thresholds. - Built-in File Rotation & DictConfig: Added
RotatingFileHandlersupport (10MB, 5 backups) viafile_pathsetting and support for fulllogging.config.dictConfigoverrides. - Enhanced Telemetry:
RequestLogMiddlewarenow captures real HTTP status codes fromhttp.response.startand client IPs.
7. ๐ฆ Sandboxed Local Storage & Advanced Threat Validation
Expanded zcore.storage into an enterprise-grade, sandboxed asset management subsystem:
- Path Traversal Defense:
LocalStorageProviderincorporates_extract_key,_key_to_path, and_resolve_pathto strictly bound all read/write/delete operations withinbase_path. - URL Resolution & Existence Check: Added
get_url(file_path_or_url)andexists(file_path_or_url)to theStorageProviderbase interface. - Executable & XSS Threat Detection (
SafeMimeTypeValidator):- Increased sample inspection buffer from 2KB to 8KB.
- Rejects binary executable headers (
MZfor.exe/.dll,#!/for shell scripts,\x7fELFfor Linux binaries). - Scans file payloads for Stored XSS and active script injections (
<script>,<?php,javascript:,onload=,onerror=,<iframe>, etc.).
8. ๐ Search Engine Hardening & Operator Unification
- Consolidated Text Operators: Unified
containsinto theilikeoperator family with automatic SQL wildcard escaping (%,_). - Non-String Column Text Search: Automatically casts non-string database columns (e.g., UUIDs, integers) via
cast(col, String)when text operators (ilike,startswith,endswith,contains) are applied. - Expanded Type Coercion: Supports
setcollections alongsidelistandtupleforinoperators, and provides clear, column-awareValidationErrormessages when coercion fails.
9. ๐๏ธ Native Engine JSON Serialization & Guaranteed Lifespan Teardown
- Custom JSON Column Serializer:
DatabaseManagerpassesjson_dumpsandjson_loadsdirectly tocreate_async_engine, enabling native persistence ofUUID,Decimal,date, anddatetimetypes in database JSON/JSONB columns. - Guaranteed Shutdown Teardown:
Kernel.lifespanautomatically executesawait close_cache()andawait db_manager.close()in itsfinallyblock, ensuring clean connection pool disposal upon application shutdown. - Event-Loop Safe Cache Eviction: Background cache eviction task in
BaseCachelazily schedules sweeps only when an active event loop is running, preventingRuntimeErrorduring CLI/import time.
โ ๏ธ Breaking Changes & Migration Guide
In BaseRepository and BaseService, variadic filter expressions (*criterion) have been moved to the beginning of the parameter list to match standard Python conventions and prevent positional shifting.
# Before (v0.1.0-beta.8) โ ambiguous positional parameter placement
items = await repo.get_list(pagination_params, fields_list, User.is_active == True)
# After (v0.1.0-rc.1) โ positional criterion first, optional controls via keyword arguments
items = await repo.get_list(
User.is_active == True,
pagination=pagination_params,
fields=fields_list
)Welcome to v0.1.0-beta.8 of the ZCore Framework! ๐
As we approach our milestone v1.0.0 stable release, v0.1.0-beta.8 delivers major performance breakthroughs in relational data mutations, introduces an enterprise-grade isolated background task execution pipeline with automatic dependency injection, embeds native soft-delete capabilities, significantly expands dynamic search operators, completely redesigns the developer experience with a rich, interactive Terminal User Interface (TUI), and aligns all CLI scaffolding templates with the latest single-generic architecture.
๐ Core Features & Architectural Advancements
1. โก High-Performance Bulk DBAPI Mutations (create_multi, update_multi, delete_multi)
We completely revamped the bulk data modification pipelines in BaseRepository to bypass individual ORM hydration overhead and leverage native database acceleration:
create_multiviaINSERT ... RETURNING: Batch insertions now execute in a single roundtrip using atomicINSERT ... RETURNINGclauses, eliminating individual entity flushes while returning fully hydrated model instances.update_multivia DBAPIexecutemany: Batch updates now bypass pre-fetching and hydrating ORM entities in memory. Updates are executed directly at the DBAPI level with compiled parameterized payloads, followed by a single consolidated batch query fetch.delete_multiviaDELETE ... RETURNING: Bulk deletions are executed in a single atomic SQL statement without prior entity fetching, returning all deleted records cleanly.
2. โฑ๏ธ Isolated Background Tasks & Scope Management (background_scope, @background_task)
Running background jobs in FastAPI that access request-scoped dependencies or database sessions often triggers RuntimeError: Session is closed. ZCore resolves this at the architectural layer:
background_scopeAsync Context Manager: Provisions an independent IoC scope, allocates a fresh, dedicatedAsyncSessionfromdb_manager, and safely clones the active user context (inherit_context=True) for background execution.@background_taskDecorator: Automatically wraps any async coroutine or synchronous function (executed in a non-blocking threadpool viaanyio.to_thread) insidebackground_scope().- Automatic IoC Auto-Wiring: Any type-annotated parameter omitted during invocation is automatically resolved directly from the IoC container.
3. ๐๏ธ Built-in Soft Deletion Infrastructure (SoftDeleteMixin)
Soft deletion is now an out-of-the-box framework primitive rather than a manual scoping pattern:
SoftDeleteMixin: Add timestamp-based soft deletion to any model withclass Task(Base, SoftDeleteMixin):.- Automatic Query Scoping: Injects an indexed, timezone-aware
deleted_at: Mapped[datetime | None]column and automatically filters all repository operations (get(),get_list(),count(),exist(),search()) withWHERE deleted_at IS NULL. - Lifecycle Helpers: Provides clean
task.soft_delete(),task.restore(), andtask.is_deletedproperties.
4. ๐ Advanced Dynamic Search Operators & Configurable Depth (SearchEngine)
The dynamic query engine has been significantly expanded with powerful string-matching and range operators:
contains: Performs substring matching on text columns (with automatic wildcard sanitization) and collection containment.startswith&endswith: String prefix and suffix matching with automated SQL wildcard escaping.between: Range evaluations for numerical, date, and timestamp columns accepting inclusive[min, max]boundaries with automatic type coercion.- Configurable
__max_search_depth__: Filter and relation inclusion (include) depth limits can now be customized per model via the__max_search_depth__attribute (defaulting safely to3to defend against query DoS attacks).
5. ๐ก๏ธ Scope-Aware Existence Verifications (exist)
BaseRepository.exist()now strictly evaluates and enforces model-levelscope_queryand soft-delete filters before checking record existence vialimit(1), preventing cross-tenant or deleted entity enumeration.
6. ๐ฅ๏ธ Interactive TUI & Scaffolding Engine (zc)
The zc CLI has been completely rewritten into an interactive Terminal User Interface powered by Rich and Questionary:
- Context-Aware Dashboard: Running
zcautomatically detects whether you are in an active project or a workspace with multiple microservices. - Multi-Database Bootstrapping:
zc initinteractively configures SQLite (aiosqlite), PostgreSQL (asyncpg), or MySQL (aiomysql) with pre-configured.envandrequirements.txtfiles. - Automated Virtual Environment Setup: Automatically initializes isolated
.venvenvironments and installs dependencies using ultra-fastuvor standardpip. - Granular 7-Layer Scaffolding:
zc startappsupports Full Boilerplate, Clean/Blank, or Custom Layer Selection across Models, Schemas, Repositories, Services, Routers, Plugins, and Pytest suites. - Automatic Secret Key Generation:
zc initautomatically provisions fresh 64-character cryptographicSECRET_KEYstrings into.env.
๐ Bug Fixes & Refinements
7. ๐ ๏ธ CLI Scaffolding Template Alignment
- Fixed
BaseRepository&BaseServiceBoilerplate: Corrected scaffolding templates inzcore.cli.templates(REPOSITORY_TEMPLATEandSERVICE_TEMPLATE) to use the streamlined single-generic signature (BaseRepository[Model]andBaseService[Model]) introduced inv0.1.0-beta.7, removing obsolete schema generic parameters and redundant imports. - AST Compilation Test Guard: Added explicit AST compilation testing to the test suite (
test_scaffolded_templates_are_valid_python) to guarantee all generated boilerplates are 100% valid, error-free Python code.
โ ๏ธ Breaking Changes & Migration Guide
Because create_multi, update_multi, and delete_multi now utilize database-level RETURNING clauses and direct DBAPI execution, manual refresh=True loops are no longer needed.
# Before (v0.1.0-beta.7)
created_items = await repo.create_multi(schemas, refresh=True)
# After (v0.1.0-beta.8)
created_items = await repo.create_multi(schemas)Welcome to v0.1.0-beta.7 of the ZCore Framework! ๐
This is one of the most substantial and transformative releases in ZCore's history. Guided by our foundational philosophy of Engineered Simplicity (KISS) and Clean Architecture, v0.1.0-beta.7 eliminates generic boilerplate across data layers, introduces a complete asynchronous testing framework with transaction rollback guarantees, unifies request-scoped context state and security primitives, and introduces event-driven subscriber mechanics.
๐ Core Features & Architectural Advancements
1. ๐งช Comprehensive Async Testing Infrastructure (zcore.testing)
Writing integration and unit tests for database-backed FastAPI services is now effortless and boilerplate-free:
ZTestFixtureEngine: Modular async fixtures includingContainerSandbox(snapshots and restores IoC state),DatabaseRollback(wraps tests in isolated savepoint transactions),UserContext(injects user identities and security scopes), andAppLifespan(manages FastAPI lifecycle hooks).ZTestClient: An asynchronous test client extendinghttpx.AsyncClientthat coordinates test sandboxes with zero manual mock setups.BaseZTest: An abstract class providing clean, class-based test suites using an intuitiveasync with self.run(use_db=True)context manager.- CLI Test Generator: Run
zc startapp <domain> --testto scaffold ready-to-run test files automatically.
2. ๐ Centralized Request Context & Scopes (ZContext & ctx)
Replaced fragmented context functions with a unified, high-performance, contextvar-isolated ZContext class:
- Global
ctxSingleton: Access context variables anywhere in the request lifecycle via strongly-typed properties (ctx.user_id,ctx.restricted_fields,ctx.action). ctx.scope()Context Manager: Create isolated, temporary context overrides for background tasks, cron jobs, or test sandboxing.- Action-Aware Routing: Route operations (
create,view,update,delete) are automatically detected and injected intoZContext, driving action-scoped field pruning inZchema.
3. ๐งน Streamlined Data Layer Generics & Dynamic Hook Propagation
We eliminated the verbose schema generic clutter from data access layers:
- Single Generic Parameter:
BaseRepository[Model]andBaseService[Model]now only require the database model type. - Dynamic Criterion & Query Filters: Repository
get(),exist(), andget_list()now accept arbitrary positional SQLAlchemy binary expressions (*criterion) and keyword arguments (**filters) consolidated via_apply_filters. - Dynamic Pre-Hook Data Injection: Service
pre_createandpre_updatelifecycle hooks can now return a dictionary (Optional[dict[str, Any]]) that automatically merges context-derived data (e.g.,user_idfromctx) directly into repository database flushes.
4. ๐ Consolidated Security & Generic Authentication (BaseAuth)
- Unified
SecurityClass: Merged scattered hashing and JWT logic into a centralizedSecuritycoordinator supporting Argon2id password hashing, PyJWT token encoding/decoding, and cryptographic token generation. - Template Method
BaseAuth: A generic authentication dependency that extracts and validates tokens, integrates withBaseCachefor user-lookup caching, and automatically binds the resolved user toZContext. - Dynamic Scope Resolution:
HasScopespermission dependencies now evaluate scopes dynamically fromZContext(ctx.get("scopes")) with automatic type coercion for lists, tuples, and sets.
5. โก Modern Constructor Auto-Wiring (Inject[T])
- Converted
Injectinto a subscriptable type marker (Inject[T]), which seamlessly maps toAnnotated[T, Depends(Injector(T))]. - Allows clean, idiomatic constructor type-hinting in services and routes without importing or declaring raw FastAPI
Depends()chains.
6. ๐ก Event-Driven Architecture (@on_event) & SQL Diagnostics
@on_eventDecorator: Mark service methods as event subscribers with automatic container-backed resolution viaEventDispatcher.register_listeners().- SQL Execution Telemetry: Built-in connection interceptors log SQL execution durations in milliseconds and filter out Postgres system catalog query noise.
- Static Route Protection: Added
_sort_routes()to ensure parameterized paths (e.g.,/{id:uuid}) never shadow sibling static endpoints like/search.
๐ ๏ธ CLI & Subsystem Enhancements
zc genenv: Introspects registered PydanticSettingsclasses and scaffolds a clean.env.examplefile automatically.SettingsSimplification: RenamedZCoreCoreSettingstoSettingsand replacedENVIRONMENTstrings with booleanDEBUGflags.ZCoreJSONResponse: Replaces standard JSON responses to safely serialize complex types (UUIDs, ISO datetimes, Decimals).- Standalone Documentation Portal: Decoupled documentation from the core repository into the official standalone repository Baseryn/zcore-docs.
โ ๏ธ Breaking Changes & Migration Guide
You no longer need to pass schema types to BaseRepository or BaseService.
# Before (v0.1.0-beta.6)
class TaskRepo(BaseRepository[Task, TaskCreate, TaskUpdate]):
...
class TaskService(BaseService[Task, TaskCreate, TaskUpdate]):
...
# After (v0.1.0-beta.7)
class TaskRepo(BaseRepository[Task]):
...
class TaskService(BaseService[Task]):
...Welcome to v0.1.0-beta.6 of the ZCore Framework! ๐
This release represents a significant step forward in robust data handling, security validation, and comprehensive project governance. Following our core philosophy of Engineered Simplicity (KISS), we addressed critical edge-cases in timezone serialization, refined schema semantics to align with Domain-Driven Design (DDD), and overhauled repository testing pipelines.
๐ Core Architectural Refinements
๐ Decoupled Presentation Layer Domain (__model__)
In Zchema (zcore/web/projection.py), the class attribute __db_name__ has been officially deprecated in favor of a more semantic and architecturally accurate attribute: __model__.
- The Rationale: Schemas (DTOs) belong purely to the presentation layer and should not be tightly coupled to database nomenclature by name.
- The Alignment: All internal recursion, pruning logics, and CLI code-generation templates have been fully migrated to use
__model__for strict domain binding.
# Before (beta.5)
class TaskResponse(Zchema):
__db_name__ = "tasks"
# After (beta.6+)
class TaskResponse(Zchema):
__model__ = "tasks"๐ Lazy-Loaded Root Namespace Imports
Developers can now import highly utilized core framework constructs directly from the root namespace:
from zcore import RouteKey, Plugin, on_event, EventDispatcher- Implemented dynamic, lazy-loaded import resolutions within
src/zcore/__init__.pyusing Python's dynamic__getattr__module block, ensuring zero performance or startup overhead during initialization.
๐ Data Integrity & Security Fixes
๐ข Precision-Preserving Decimal Serialization
Changed JSON encoding for Decimal instances from standard floating-point (float) to string (str) inside CustomJSONEncoder.
- The Fix: Converting Decimals to floats introduces floating-point arithmetic inaccuracies and precision loss right before data is dispatched to clients.
- The Result: Preserves exact decimal precision, establishing the industry standard for financial calculations and highly accurate APIs.
๐บ๏ธ Timezone-Aware Pagination Cursors
Refactored the _encode_cursor method inside zcore/db/pagination.py to intercept naive datetime instances.
- Naive datetimes are now explicitly normalized to UTC, and timezone-aware instances are converted safely to UTC before being base64 encoded into cursor payloads.
- Resolves cursor misalignment and timezone-awareness dropouts in geographically distributed deployments.
๐ก๏ธ Robust Security Path Normalization
Eliminated overzealous string prefix stripping in path resolutions inside SearchEngine and Zchema.
- The Fix: Previously,
path.replace("resource.", "")acted globally and could corrupt legitimate nested relation paths (e.g.,project.resource.statusincorrectly mutated toproject.status). - The Result: Replaced with a strict, localized prefix-matching resolution to secure nested relationships without false positives during access checks.
โฑ๏ธ Native ISO-8601 Datetime Parsing
Simplified UTC datetime coercion in zcore/db/search.py by removing legacy .replace("Z", "+00:00") string manipulation workarounds. The coercion layer now fully relies on native, optimized Python 3.11+ datetime.fromisoformat() UTC suffix parsing out-of-the-box.
โ๏ธ Automated CI/CD & Project Governance
- GitHub Actions Test Suite (CI): Deployed automated pull-request code quality gates using
ruff checklinting and thehatchtest suite (blocking merges unless all status checks pass). - Standardized Issue Templates: Added customized Bug Report and Feature Request templates to capture environmental diagnostics (DB engines, SQLAlchemy, and Redis versions).
- Automated Semantic Changelogs: Configured
.github/release.ymlto automatically categorize pull requests under semantic sections based on metadata tags. - Community Guidelines: Introduced formal
CONTRIBUTING.mdandSECURITY.mdfiles to clarify local setup steps and private vulnerability reporting workflows.
Welcome to v0.1.0-beta.5 of the ZCore Framework! This release centers on Engineered Simplicity (KISS). We deprecated complex, reflection-based configuration variables and brittle runtime hacks, replacing them with standard Object-Oriented patterns, native Pydantic V2 integrations, and cleaner dependency structures.
๐ Core Features & Enhancements
๐ก๏ธ Unified Schema Security (Zchema)
Completely overhauled data pruning and shielding mechanisms. Previously, data masking was handled globally in the web layer via a generic resource.* prefix, which was prone to namespace collisions.
- The
ZchemaClass: All schemas now inherit fromZchema(extending PydanticBaseModel). - Domain-Specific Namespacing: Define a class-level
__db_name__(migrated to__model__in beta.6). - 3-Tier Protection: Dynamic Schemas (
?schema=true), Input Filtering (Anti-Mass Assignment), and Response Serialization Pruning.
๐ฆ Template Method Service Hooks
To guarantee that business-critical pre_ and post_ lifecycle hooks and transaction boundaries are never skipped, we separated orchestration from execution:
- Custom Database Operations: Developers now override dedicated
on_create,on_update, andon_deletecallback hooks instead of overriding the publiccreate()orchestrator. - The orchestrator guarantees that validation, hooks, and transaction commits (
_safe_commit) execute in the exact correct order.
๐ FastAPI-Native Route Dependencies
Conceptually renamed the routing security layer from "Permissions" to "Dependencies", matching FastAPI's core design:
- Removed 8 static class variables (
DEFAULT_PERMISSIONS,POST_PERMISSIONS, etc.). - Introduced a single, elegant factory method:
get_route_dependencies(self, route_key: RouteKey, action: str) -> list[Any]. - Developers can now use standard Python inheritance and
super()to customize specific endpoints while maintaining default scopes for others.
๐ฆ Robust Modular Monolith Imports
Resolved ModuleNotFoundError across nested modules (such as importing from shared/ within modules/identity/) using a 3-layer approach across CLI, Runtime, and IDE configuration.
โ ๏ธ Breaking Changes & Migration Guide
Replace BaseModel with Zchema and define your domain identifier on schemas:
# Before (v0.1.0-beta.4)
from pydantic import BaseModel
class UserResponse(BaseModel):
email: str
# After (v0.1.0-beta.5)
from zcore import Zchema
class UserResponse(Zchema):
__db_name__ = "user" # Note: renamed to __model__ in beta.6
email: str๐ Bug Fixes & Refactoring
- Fixed
ModuleNotFoundErrorin subfolders of modular directory layouts (#53). - Corrected
IoCContainerresolution forAnnotatedtype hints and manual request-scope instance registration (#48). - Simplified
ZCoreJSONResponseand removedResponseProjectorto avoid redundant serialization overhead.
Welcome to v0.1.0-beta.4 of the ZCore Framework! This version introduces critical architectural refinements, improves ASGI/Async performance by eliminating thread-pool bottlenecks, and simplifies developer experience (DX) for database-backed microservices.
๐ Key Improvements & Features
1. Complete DI Overhaul & Web-Decoupled Scoping
The dependency injection (DI) layer has been restructured to strictly adhere to Clean Architecture:
- ASGI Middleware Session Scoping: The lifetime of the
AsyncSessiondatabase connection is now managed at the ASGI middleware level (ScopedDependencyMiddleware). This guarantees that a request-scoped database session is initialized and registered in the DI container before FastAPI resolves routing dependency graphs. - Annotated Type Unpacking: The custom DI container (
_auto_wire) supports Python's nativetyping.Annotatedpatterns, gracefully extracting the core class definition. - High-Performance Async Injector: Modified
Injector.__call__to be asynchronous (async def), evaluating dependencies directly on the main event loop.
2. Base Query Hook & Extension Layer
Introduced structured hook methods in the base repository layer to allow granular control over queries:
_get_base_query(): Reusable hook returning the defaultSelectstatement.- Integrated the base query pipeline seamlessly with the
SearchEnginedynamic filter compiler.
3. One-Command Database Bootstrapping
Running zc init <project_name> through the ZCore CLI automatically creates the default SQLite database file (zcore_dev.db) on the filesystem.
4. Dependency Management
Added uvicorn as a primary core dependency inside pyproject.toml to guarantee zc run functions correctly out of the box.
โ ๏ธ Breaking Changes & Migration Guide
You no longer need to write = Inject(...) default values or rely on SessionDep in repository/service constructors. Use clean, native Python type hints:
# Before (v0.1.0-beta.3)
class UsersRepository(BaseRepository):
def __init__(self, db: SessionDep):
super().__init__(model=Users, db=db)
class UsersService(BaseService):
def __init__(self, repository: UsersRepository = Inject(UsersRepository)):
super().__init__(model=Users, repository=repository)
# After (v0.1.0-beta.4)
class UsersRepository(BaseRepository):
def __init__(self, db: AsyncSession): # Standard AsyncSession
super().__init__(model=Users, db=db)
class UsersService(BaseService):
def __init__(self, repository: UsersRepository): # Pure Python, no defaults
super().__init__(model=Users, repository=repository)