Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
967dc97
perf(db): optimize create_multi using INSERT RETURNING clause
alialfostovar Aug 23, 2026
ae3209d
perf(db): optimize update_multi using UPDATE RETURNING clause
alialfostovar Aug 23, 2026
9c07432
perf(db): optimize delete_multi using DELETE RETURNING clause
alialfostovar Aug 23, 2026
965a57b
perf(db): optimize update_multi with direct DBAPI executemany execution
alialfostovar Aug 23, 2026
08baa45
feat(kernel): add background_scope and background_task decorator
alialfostovar Aug 23, 2026
9ac3c4b
feat(kernel): add background scope and task decorator with auto-wiring
alialfostovar Aug 23, 2026
783a981
chore(kernel): update di imports
alialfostovar Aug 24, 2026
bcea060
feat(kernel): export background scope and task utilities
alialfostovar Aug 24, 2026
8e2306f
feat(db): add advanced filter operators
alialfostovar Aug 24, 2026
111f56e
feat(db): make search relation depth configurable
alialfostovar Aug 24, 2026
68ab32c
feat(db): refine search operators and add filter depth tests
alialfostovar Aug 24, 2026
ecbdcec
feat(db): add soft delete mixin
alialfostovar Aug 24, 2026
5ccbb4d
feat(db): integrate soft delete with repository queries
alialfostovar Aug 24, 2026
5547ee7
chore(tests): modernize test suite typing and formatting
alialfostovar Aug 24, 2026
556bf85
feat(cli): introduce interactive project scaffolding
alialfostovar Aug 24, 2026
34751e5
chore(project): modernize project metadata and development configuration
alialfostovar Aug 24, 2026
751df7d
docs(readme): document interactive CLI and scaffolding workflow
alialfostovar Aug 24, 2026
1d19be9
docs(readme): include dev dependencies in local setup
alialfostovar Aug 24, 2026
25e4a21
perf(db): optimize bulk operations in WriteRepositoryMixin (#86)
alialfostovar Aug 27, 2026
7ca59d5
feat(kernel): add background_scope and @background_task with auto-wir…
alialfostovar Aug 27, 2026
917736d
feat(db): add advanced filter operators and configurable relation dep…
alialfostovar Aug 27, 2026
2c80ab8
feat(db): add SoftDeleteMixin and integrate with repository queries (…
alialfostovar Aug 27, 2026
5f73dd3
chore(tests): modernize test suite typing and formatting (#90)
alialfostovar Aug 27, 2026
3bbe831
feat(cli): introduce interactive scaffolding and project orchestratio…
alialfostovar Aug 27, 2026
8287288
chore(project): update metadata, dependency groups, and project docum…
alialfostovar Aug 27, 2026
ff35dcd
fix(cli): align scaffolded repository and service templates with sing…
alialfostovar Aug 28, 2026
b8ea77c
fix(cli): align scaffolded repository and service templates with sing…
alialfostovar Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ representative at an online or offline event.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
alialfostovar@gmail.com.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
Expand Down Expand Up @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
Expand All @@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity).

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
https://www.contributor-covenant.org/translations.
52 changes: 33 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,30 @@ pip install -e ".[all,dev]"
We aim for high test coverage on core architectural units. ZCore uses `pytest` and `pytest-asyncio` for asynchronous test suites.

### Test Architecture
ZCore's codebase is highly modular. To ensure that components like the Kernel, Plugins, Dependency Injection (DI), Unit of Work (UOW), Router, and Middleware interact correctly, we organize our tests as follows:
ZCore's tests are organized modularly across architectural domains:

```text
tests/
├── unit/ # Tests for isolated, single architectural units with mocks
│ ├── test_repository.py
│ └── test_zchema.py
├── integration/ # Tests verifying interactions between modules
│ ├── test_kernel_startup.py
│ ├── test_plugin_loading.py
│ └── test_request_scope.py
└── e2e/ # Full end-to-end request/response flows using TestClient
└── test_crud_flow.py
├── test_cache.py
├── test_cli.py
├── test_context.py
├── test_db_lifecycle.py
├── test_di.py
├── test_events.py
├── test_exceptions.py
├── test_kernel.py
├── test_logging.py
├── test_pagination.py
├── test_repository.py
├── test_search.py
├── test_security.py
├── test_service.py
├── test_soft_delete.py
├── test_storage.py
├── test_streams.py
├── test_testing_subsystem.py
├── test_utils.py
└── test_web.py
```

### Running Tests Locally
Expand All @@ -84,11 +95,11 @@ pytest

If you prefer to run tests inside Hatch-isolated environments:
```bash
hatch run test
hatch test
```

### Writing Tests
- **Asynchronous Tests:** Ensure your async tests are decorated with `@pytest.mark.asyncio`.
- **Asynchronous Tests:** Ensure your async tests are decorated with `@pytest.mark.anyio` or `@pytest.mark.asyncio`.
- **Isolation:** Tests should not leave behind lingering SQLite databases, active sessions, or running background threads.
- **Mocks:** When writing tests that require external services like Redis, implement mock fallbacks where appropriate to ensure the test suite can run fully offline.

Expand All @@ -107,8 +118,8 @@ mypy src/
### 2. Linting & Formatting
Ensure your code is clean, PEP-8 compliant, and structured consistently. We recommend using `ruff` for formatting and linting:
```bash
ruff check src/
ruff format src/
ruff check .
ruff format --check .
```

---
Expand All @@ -124,14 +135,17 @@ ZCore uses the **Conventional Commits** specification to automate our changelog
Common types include:
- `feat`: A new feature (corresponds to a minor version bump).
- `fix`: A bug fix (corresponds to a patch version bump).
- `perf`: A code change that improves performance.
- `docs`: Documentation updates.
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc.).
- `refactor`: Code changes that neither fix a bug nor add a feature.
- `test`: Adding or correcting tests.
- `build`: Changes that affect the build system or external dependencies.
- `ci`: Changes to our CI/CD workflows or scripts.

*Examples:*
- `feat(di): add redis plugin support`
- `fix(uow): resolve transaction rollback issue on async commit`
- `feat(di): add background_scope and background_task decorator`
- `perf(db): optimize create_multi using insert returning clause`
- `docs(zchema): update guide for dynamic schema pruning`

---
Expand All @@ -148,12 +162,12 @@ flowchart LR
D --> E[Submit PR]
```

1. **Branch Naming:** Use descriptive branch names (e.g., `feature/add-s3-provider` or `bugfix/fix-uow-flush`).
1. **Branch Naming:** Use descriptive branch names (e.g., `feat/add-s3-provider` or `fix/uow-flush-isolation`).
2. **Atomic Commits:** Keep your commits focused on single logical changes and adhere to the conventional commits schema.
3. **Documentation:** If you are adding a new feature or modifying an existing protocol, you **must** update the corresponding documentation page under the `docs/` folder.

### 🛡️ CI/CD & Branch Protection
Our repository has strict branch protection rules configured on `master` and `develop`.
Our repository has strict branch protection rules configured on `main` and `develop`.
- **Mandatory CI Checks:** Your Pull Request cannot be merged unless all status checks (Linting with Ruff, Type-checking with Mypy, and Test Suites with Pytest) pass successfully in our GitHub Actions pipeline.
- **No Direct Pushes:** All code changes must go through a Pull Request. Direct pushes to protected branches are blocked.

Expand All @@ -164,4 +178,4 @@ Our repository has strict branch protection rules configured on `master` and `de
By contributing to ZCore, you agree that your contributions will be licensed under the project's **Apache License 2.0**.

- **No CLA Required:** We do not currently require a signed Contributor License Agreement (CLA) for individual contributions.
- **Certificate of Origin:** By submitting a Pull Request, you assert that you have the right to submit this code and that it conforms to an open-source contribution under the Apache 2.0 terms.
- **Certificate of Origin:** By submitting a Pull Request, you assert that you have the right to submit this code and that it conforms to an open-source contribution under the Apache 2.0 terms.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2024-2026 Ali Alf Ostovar / Baseryn

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
66 changes: 48 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,21 @@ While FastAPI provides a high-performance engine for HTTP, it leaves the archite
- **⚡ Scoped Dependency Injection** — High-performance constructor auto-wiring for Singleton, Transient, and request-scoped dependencies.
- **🏗️ Modular Plugin Architecture** — Organize business domains into decoupled plugins with topological dependency ordering.
- **🔍 Secure Dynamic Search Engine** — Nested JSON filters, eager loading, cursor/offset pagination, and column-level access controls.
- **📦 Zero-Boilerplate CLI** — From `pip install` to running secure CRUD endpoints in under two minutes.
- **📦 Interactive TUI & Scaffolding Engine** — Context-aware terminal dashboard, lightning-fast `uv` virtualenv orchestration, and granular layer-by-layer domain generators.

---

## Why ZCore?

| Concern | Raw FastAPI | With ZCore |
|---------|-------------|------------|
| **Endpoint Scaffolding** | Manually write 7+ routes and handlers per model | One `BaseRouter` class $\rightarrow$ 7 secure endpoints out-of-the-box |
| **Endpoint Scaffolding** | Manually write 7+ routes and handlers per model | One `BaseRouter` class → 7 secure endpoints out-of-the-box |
| **Data Leakage** | Multiple Pydantic models per role; manual conditionals | `Zchema` auto-prunes restricted fields per active context |
| **Database Transactions** | Scattered `commit()` / `rollback()` calls | `UnitOfWork` guarantees atomicity + post-commit domain events |
| **Dependency Wiring** | Deeply nested, verbose `Depends()` parameter chains | Clean constructor auto-wiring via IoC container + `Inject[T]` |
| **Search & Pagination** | Hand-crafted SQL parsing per endpoint | Declarative JSON filters + keyset cursor and offset pagination |
| **Project Layout** | No standard; every team reinvents the wheel | `zc init` + `zc startapp` — decoupled domain modularity |
| **Startup Orchestration** | Fragile `@app.on_event` chains | `Plugin` protocol with dependency DAG $\rightarrow$ topological sorting |
| **Project Tooling & Layout** | Manual folder creation, fragmented glue scripts | `zc` interactive TUI with auto `uv` setup & granular layer picking |
| **Startup Orchestration** | Fragile `@app.on_event` chains | `Plugin` protocol with dependency DAG → topological sorting |

---

Expand All @@ -66,9 +66,16 @@ pip install fastapi-zcore-framework[all]

### 2. Scaffold

Launch the interactive wizard or run directly:

```bash
# Interactive mode (prompts for DB driver, uv/.venv installation, etc.)
zc init my_app && cd my_app
zc startapp tasks --template
zc startapp tasks

# Or instant non-interactive scaffolding with defaults
zc init my_app -y && cd my_app
zc startapp tasks -y
```

### 3. Define
Expand All @@ -94,7 +101,7 @@ class Task(Base):
zc run
```

Your API is live at **`http://127.0.0.1:8000`** with 6 CRUD endpoints and dynamic search ready.
Your API is live at **`http://127.0.0.1:8000`** with 7 secure endpoints (CRUD + Dynamic Search) ready.

> 📖 **Full walkthrough:** [Quick Start Guide](https://baseryn.github.io/zcore-docs/docs/quick-start)

Expand Down Expand Up @@ -209,19 +216,42 @@ A dynamic query builder that translates nested JSON filters into safe SQLAlchemy
</details>

<details>
<summary><strong>📦 CLI Scaffolding</strong></summary>
<summary><strong>📦 Interactive TUI & Scaffolding Engine</strong></summary>
<br>

Stop writing boilerplate. The `zc` CLI generates consistent, production-ready domain modules and environment templates with a single command.
The `zc` CLI gives you a rich, interactive Terminal User Interface (TUI) powered by Questionary and Rich. It features:

* **Workspace & Context Awareness:** Detects whether you are inside an active project, in a root workspace containing multiple services, or starting fresh.
* **Automated `uv` / `.venv` Setup:** Initializes isolated virtual environments and installs dependencies automatically using `uv` (recommended) or standard `pip`.
* **Multi-Engine Driver Bootstrapping:** Configures SQLite (`aiosqlite`), PostgreSQL (`asyncpg`), or MySQL (`aiomysql`) in `.env` and `requirements.txt` out-of-the-box.
* **Granular Architectural Scaffolding:** Generates modular domain apps in 3 modes (*Full Boilerplate*, *Clean/Blank*, or *Custom Layer Selection* across Models, Schemas, Repositories, Services, Routers, Plugins, and Pytest suites).

```text
$ zc

⚡ ZCore Framework v0.1.0-Beta • Modern Modular Monolith
FastAPI • SQLAlchemy 2.0 • Pydantic V2

? What framework task would you like to perform? 📦 init — Scaffold a new full ZCore project
┌ Initialize New ZCore Project
│
? Project directory name: core_api
? Select primary database driver: PostgreSQL (asyncpg) — Production Ready
? Initialize virtual environment (.venv) and install dependencies? Yes (uv)
│ ✓ Environment & dependencies installed successfully.
└ Project 'core_api' ready!
```

#### CLI Command Reference

| Command | Purpose |
|---------|---------|
| `zc init <name>` | Create a new project with settings, `.env`, and `main.py` |
| `zc startapp <name>` | Scaffold an empty domain module |
| `zc startapp <name> --template` | Scaffold with full Model, Schema, Repo, Service, Router, and Plugin boilerplate |
| `zc run` | Launch Uvicorn with auto-reload and environment-aware config |
| `zc gensecret` | Generate a 64-character cryptographically secure secret key |
| `zc genenv` | Introspect registered `Settings` classes and scaffold `.env.example` |
| Command | Interactive | Non-Interactive Flags | Purpose |
|---------|:-----------:|-----------------------|---------|
| `zc` | ✅ | — | Launch interactive orchestration dashboard |
| `zc init [name]` | ✅ | `--db [sqlite\|postgres\|mysql]`, `-y` | Bootstrap a new project with settings, `.env`, and dependencies |
| `zc startapp [name]` | ✅ | `--template / --no-template`, `--test / --no-test`, `-y` | Scaffold domain modules with granular layer selection |
| `zc run` | ✅ | — | Launch local Uvicorn dev server with auto-reload |
| `zc gensecret` | — | — | Generate a 64-character cryptographically secure `SECRET_KEY` |
| `zc genenv` | ✅ | `-o <output>`, `-f / --force` | Introspect active `Settings` classes and scaffold `.env.example` |
</details>

---
Expand All @@ -245,7 +275,7 @@ Contributions are welcome! Please read our guidelines before submitting a PR.

- **Issues:** Bug reports and feature requests via [GitHub Issues](https://github.com/Baseryn/zcore/issues)
- **PRs:** Open a pull request with a clear description of the change
- **Local Setup:** `pip install -e ".[all]"` and run `hatch test` to verify
- **Local Setup:** `pip install -e ".[all,dev]"` and run `hatch test` to verify

---

Expand All @@ -257,5 +287,5 @@ See [LICENSE](https://github.com/Baseryn/zcore/blob/master/LICENSE) for details.
---

<p align="center">
<sub>Built with ☕ and architectural rigor by <a href="https://github.com/alialfostovar">Ali Alf Ostovar</a>.</sub>
<sub>Built with ☕ and architectural rigor by <a href="https://github.com/alialfostovar">Ali Alf Ostovar</a> / <a href="https://github.com/Baseryn">Baseryn</a>.</sub>
</p>
10 changes: 5 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Security Policy

We take the security of ZCore, and the applications built on top of it, extremely seriously. Security is a core pillar of ZCore's design philosophy, integrated deeply into its architecture [security/jwt.py, security/hashing.py] rather than treated as an afterthought.
We take the security of ZCore, and the applications built on top of it, extremely seriously. Security is a core pillar of ZCore's design philosophy, integrated deeply into its architecture (`zcore/security/security.py`, `zcore/web/projection.py`) rather than treated as an afterthought.

If you believe you have found a security vulnerability in ZCore, please read this document to learn how to report it responsibly.

Expand Down Expand Up @@ -87,9 +87,9 @@ The following are generally **not considered** security vulnerabilities in ZCore

## Hardened Defaults in ZCore

ZCore is built with strict, "secure-by-default" configurations [security/jwt.py, storage/local.py]:
- **Production Secret Guard:** The framework will raise a fatal traceback and refuse to start in a production environment if the default fallback `SECRET_KEY` is detected [security/jwt.py].
- **Argon2id default configuration:** We enforce high-entropy password hashing out-of-the-box [security/hashing.py].
- **Path Traversal Protection:** The local storage provider strictly verifies resolved filesystem paths before running write or unlink operations [storage/local.py].
ZCore is built with strict, "secure-by-default" configurations:
- **Production Secret Guard:** The framework will raise a fatal traceback and refuse to start in a production environment if the default fallback `SECRET_KEY` is detected (`zcore/security/security.py`).
- **Argon2id default configuration:** We enforce high-entropy password hashing out-of-the-box (`zcore/security/security.py`).
- **Path Traversal Protection:** The local storage provider strictly verifies resolved filesystem paths before running write or unlink operations (`zcore/storage/local.py`).

*Note: ZCore only fails-fast (crashes) on fatal security configurations. Missing optional configuration elements (e.g., optional caching backends) will only raise non-fatal warnings.*
29 changes: 26 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ license = { text = "Apache License 2.0" }
authors = [
{ name = "Ali Alf Ostovar", email = "240363843+alialfostovar@users.noreply.github.com" }
]
maintainers = [
{ name = "Baseryn" }
]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Framework :: FastAPI",
"Topic :: Software Development :: Libraries :: Application Frameworks",
]
Expand All @@ -30,13 +34,23 @@ dependencies = [
"jsonschema>=4.21.0",
"python-multipart>=0.0.9",
"uvicorn>=0.22.0",
"questionary>=2.0.1",
"rich>=13.7.0",
]

[project.optional-dependencies]
db = [
"sqlalchemy[asyncio]>=2.0.28",
"aiosqlite>=0.20.0",
]
postgres = [
"sqlalchemy[asyncio]>=2.0.28",
"asyncpg>=0.29.0",
]
mysql = [
"sqlalchemy[asyncio]>=2.0.28",
"aiomysql>=0.2.0",
]
redis = [
"redis>=5.0.3",
]
Expand All @@ -50,9 +64,18 @@ crypto = [
"argon2-cffi>=23.1.0",
"pyjwt>=2.8.0",
]
dev = [
"pytest>=8.0.0",
"pytest-asyncio>=0.23.0",
"httpx>=0.27.0",
"mypy>=1.9.0",
"ruff>=0.3.0",
]
all = [
"sqlalchemy[asyncio]>=2.0.28",
"aiosqlite>=0.20.0",
"asyncpg>=0.29.0",
"aiomysql>=0.2.0",
"redis>=5.0.3",
"aiofiles>=23.2.1",
"argon2-cffi>=23.1.0",
Expand Down Expand Up @@ -81,11 +104,11 @@ testpaths = ["tests"]

[tool.hatch.envs.hatch-test]
extra-dependencies = [
'pytest-asyncio',
'httpx'
"pytest-asyncio",
"httpx"
]
features = [
'all'
"all"
]

[tool.ruff]
Expand Down
7 changes: 7 additions & 0 deletions src/zcore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from zcore.db.repository import BaseRepository
from zcore.db.search import SearchRequest
from zcore.db.setup import Base, SessionDep, db_manager, get_db
from zcore.db.soft_delete import SoftDeleteMixin
from zcore.db.uow import UnitOfWork
from zcore.kernel.di import Inject, container
from zcore.kernel.engine import Kernel
Expand Down Expand Up @@ -35,6 +36,7 @@
"SearchRequest",
"Security",
"SessionDep",
"SoftDeleteMixin",
"UnitOfWork",
"ZContext",
"ZCoreAPIRoute",
Expand Down Expand Up @@ -141,5 +143,10 @@ def __getattr__(name: str) -> Any:
from zcore.kernel.events import EventDispatcher

return EventDispatcher

if name == "SoftDeleteMixin":
from zcore.db.soft_delete import SoftDeleteMixin

return SoftDeleteMixin

raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
Loading
Loading