Skip to content

Commit 7c5fff7

Browse files
release(v0.1.0-rc.2): framework stabilization, soft-delete, and lookup (#126)
## Description This release candidate (`v0.1.0-rc.2`) introduces major architectural stabilization, performance optimizations, and core feature additions to prepare the framework for the upcoming `v1.0.0` stable milestone. ### Summary - **Unified Exception Envelope & Normalization**: Implemented standardized error normalization across all exception types (`AppException`, `RequestValidationError`, `StarletteHTTPException`, `ResponseValidationError`, and generic `Exception`) wrapping responses in `ResponseWrapper[None]`, with Pydantic error sanitization (`_sanitize_error_item`, `_format_error_location`), debug-gated response details, and one-call registration via `register_exception_handlers(app)`. - **End-to-End Soft-Delete & Restoration Lifecycle**: Added declarative soft-delete support across Repository, Service, and Router layers. Includes `restore()` / `restore_multi()` with atomic SQL dialect-aware `RETURNING` updates, lifecycle hooks (`pre/post_restore`), and `force: bool = False` flag propagation for physical deletion via `DELETE /resource/{id}?force=true`. - **Field-Restricted `LOOKUP` Endpoint & Query Projections**: Introduced `RouteKey.LOOKUP` (`POST /lookup`) with automatic schema-driven column projection (`load_only`), relationship eager-loading (`selectinload` / `joinedload`), allowed field validation, and `Actions.LOOKUP` RBAC permission integration. - **Search Engine Inversion & Logical NOT Groups**: Added inverted comparison operators (`not_like`, `not_ilike`, `not_contains`, `not_startswith`, `not_endswith`, `not_in`, `not_between`, `is_not_null`) and logical `not` grouping to the AST query builder. - **Re-entrant Unit of Work & Deferred Event Dispatching**: Added depth-aware transaction coordination (`uow_depth`) for nested `UnitOfWork` scopes, buffering domain events in `session.info['uow_events']` to ensure atomic root-level dispatching. - **Polymorphic Identifier Support**: Generalized user identity types across `ZContext`, `UserProtocol`, `StreamManager`, and keyset `CursorPagination` to seamlessly support `int`, `str`, and `UUID` identifiers. - **Optional Auth & Guest Field Shielding**: Added `auto_error=False` support to `BaseAuth`, exported `get_optional_user_stub`, and introduced `__private__` class attributes on `Zchema` to prune sensitive fields for unauthenticated requests automatically. - **Tunable Configuration & Parameter Bounding**: Added framework-wide settings for pagination bounds, search depth, caching TTL/maxsize, and stream queue limits, enforced dynamically via Pydantic model validators. - **Logging Refinement & Context Isolation**: Implemented status-code-aware log levels (DEBUG for `<500`, ERROR for `>=500`), decoupled slow-query logging, preserved native Uvicorn console formatting in dev mode vs JSON intercept in production, and hardened Structlog contextvar isolation across background scopes. - **Enhanced Test Harness & Fixtures**: Added `setup_test_database`, `EventDispatcherSandbox`, custom engine/dependency overrides in `DatabaseRollback`, and guest/superuser mocking in `ZTestClient`. - **Tooling, Docs & CI**: Upgraded `zc run` with cascading configuration (`CLI > .env > Defaults`) and transparent Uvicorn argument forwarding, added dynamic test suite naming (`test_<app_name>.py`), restructured `README.md` with the ZShop showcase, and split GitHub Actions CI into quality check, cross-platform matrix, and smoke installation jobs. ### Impact Standardizes error handling, transaction lifecycles, and data exposure mechanisms across all layers of the framework. These changes resolve multi-tenancy, typing, and background execution edge cases while boosting serialization performance and providing developer tooling for the stable `v1.0.0` release. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [x] Documentation update ## How Has This Been Tested? - [x] Unit/Integration tests (`hatch test`) - Validated full test suite (515+ tests) across Python 3.11, 3.12, and 3.13 on Ubuntu, Windows, and macOS. - Verified exception envelope conformity and header preservation across all HTTP handlers. - Tested single and bulk soft-delete, hard-delete (`force=True`), and restoration lifecycles. - Tested dynamic search operators, negation logic, and nested filter depth validation. - Verified `ZTestClient` savepoint rollbacks, polymorphic user IDs, and optional auth mocking. - Validated `Zchema` guest pruning (`__private__`) and role-based field restrictions. - [x] Static type check passing (`mypy src/`) - Strict type checking passed with zero errors across all modules. - [x] Code style and formatting checks (`ruff check src/`, `ruff format --check src/`). - [x] Smoke install build test (`pip install dist/*.whl` and CLI verification). ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation in `zcore-docs` if applicable - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
2 parents 85964b5 + 035d3b6 commit 7c5fff7

69 files changed

Lines changed: 4498 additions & 1859 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/test.yml‎

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ name: Test Suite (CI)
22

33
on:
44
pull_request:
5-
branches:
6-
- master
7-
- develop
5+
branches: [master, develop]
86
push:
9-
branches:
10-
- master
11-
- develop
7+
branches: [master, develop]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
1212

1313
jobs:
14-
test:
15-
name: test
14+
quality-check:
15+
name: Code Quality & Type Check
1616
runs-on: ubuntu-latest
1717
steps:
1818
- uses: actions/checkout@v4
@@ -22,14 +22,86 @@ jobs:
2222
python-version: "3.11"
2323
cache: "pip"
2424

25-
- name: Upgrade pip
26-
run: python -m pip install --upgrade pip
27-
28-
- name: Install Hatch and Ruff
29-
run: pip install hatch ruff
25+
- name: Install Dependencies & Tools
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install ruff mypy
29+
pip install -e ".[all]"
3030
31-
- name: Run Ruff Lint Check
31+
- name: Ruff Linter
3232
run: ruff check src/zcore
3333

34-
- name: Run Hatch Tests
35-
run: hatch test
34+
- name: Ruff Formatter Check
35+
run: ruff format --check src/zcore
36+
37+
- name: Mypy Strict Type Analysis
38+
run: mypy src/zcore
39+
40+
matrix-tests:
41+
name: test (${{ matrix.os }} / py${{ matrix.python-version }})
42+
needs: quality-check
43+
runs-on: ${{ matrix.os }}
44+
strategy:
45+
fail-fast: false
46+
matrix:
47+
os: [ubuntu-latest, windows-latest, macos-latest]
48+
python-version: ["3.11", "3.12", "3.13"]
49+
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
- uses: actions/setup-python@v5
54+
with:
55+
python-version: ${{ matrix.python-version }}
56+
cache: "pip"
57+
58+
- name: Upgrade pip & install hatch
59+
run: |
60+
python -m pip install --upgrade pip
61+
pip install hatch
62+
63+
- name: Run 515+ Tests via Hatch
64+
run: hatch test
65+
66+
smoke-install-test:
67+
name: smoke test (${{ matrix.os }})
68+
needs: matrix-tests
69+
runs-on: ${{ matrix.os }}
70+
strategy:
71+
fail-fast: false
72+
matrix:
73+
os: [ubuntu-latest, windows-latest, macos-latest]
74+
steps:
75+
- uses: actions/checkout@v4
76+
77+
- uses: actions/setup-python@v5
78+
with:
79+
python-version: "3.11"
80+
81+
- name: Install Hatch & Build Wheel
82+
run: |
83+
pip install hatch
84+
hatch build
85+
86+
- name: Install Generated Wheel & Test CLI
87+
shell: bash
88+
run: |
89+
pip install dist/*.whl
90+
zc --version
91+
python -c "import zcore; print('ZCore successfully imported from:', zcore.__file__)"
92+
93+
all-checks-passed:
94+
name: all-checks-passed
95+
needs: [quality-check, matrix-tests, smoke-install-test]
96+
runs-on: ubuntu-latest
97+
if: always()
98+
steps:
99+
- name: Verify all dependencies succeeded
100+
run: |
101+
if [ "${{ needs.quality-check.result }}" != "success" ] || \
102+
[ "${{ needs.matrix-tests.result }}" != "success" ] || \
103+
[ "${{ needs.smoke-install-test.result }}" != "success" ]; then
104+
echo "One or more checks failed!"
105+
exit 1
106+
fi
107+
echo "All 13 checks passed with 100% success!"

‎.gitignore‎

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,48 @@
1-
# Byte-compiled / optimized / DLL files
1+
# Byte-compiled / optimized / compiled files
22
__pycache__/
3-
*.py[cod]
4-
*$py.class
3+
*.pyc
4+
*.pyd
5+
*.pyo
6+
*.egg-info/
7+
.eggs/
58

6-
# C extensions
7-
*.so
9+
# Virtual environment
10+
venv/
11+
.venv/
12+
env
13+
.env
814

915
# Distribution / packaging
10-
bin/
11-
build/
12-
develop-eggs/
1316
dist/
14-
downloads/
15-
eggs/
16-
.eggs/
17-
lib/
18-
lib64/
19-
parts/
20-
sdist/
21-
var/
22-
wheels/
23-
share/python-wheels/
24-
*.egg-info/
25-
.installed.cfg
17+
build/
2618
*.egg
19+
*.whl
2720

28-
# Virtual Environments
29-
.venv/
30-
venv/
31-
ENV/
32-
env/
33-
34-
# IDEs and editors
35-
.idea/
21+
# Editor and IDE files
3622
.vscode/
23+
.idea/
3724
*.swp
25+
*.bak
3826
*.swo
3927

40-
# Local configuration & environment variables
41-
.env
42-
.env.local
43-
.env.*
28+
# OS generated files
29+
.DS_Store
30+
Thumbs.db
31+
32+
# Logs and databases
33+
*.log
34+
*.sqlite3
35+
*.db
36+
37+
# Temporary files
38+
tmp/
39+
*.tmp
40+
41+
# Jupyter Notebook files
42+
.ipynb_checkpoints/
4443

45-
# database
46-
*.db
44+
# Miscellaneous
45+
.pytest_cache/
46+
htmlcov/
47+
.coverage
48+
.mypy_cache

0 commit comments

Comments
 (0)