Metadata-Version: 2.4
Name: sysnet-soft-delete
Version: 0.2.0
Summary: Soft-delete mixin a repository pro Beanie ODM
Project-URL: Homepage, https://github.com/sysnet-cz/sysnet-soft-delete
Project-URL: Repository, https://github.com/sysnet-cz/sysnet-soft-delete
Project-URL: Documentation, https://github.com/sysnet-cz/sysnet-soft-delete/tree/main/docs
Project-URL: Changelog, https://github.com/sysnet-cz/sysnet-soft-delete/blob/main/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/sysnet-cz/sysnet-soft-delete/issues
Author-email: "SYSNET s.r.o." <dev@sysnet.cz>
License: # GNU AFFERO GENERAL PUBLIC LICENSE
        Version 3, 19 November 2007
        
        Copyright (C) 2007 Free Software Foundation, Inc.
        <https://fsf.org/>
        
        Everyone is permitted to copy and distribute verbatim copies
        of this license document, but changing it is not allowed.
        
        ## Preamble
        
        The GNU Affero General Public License is a free, copyleft license for
        software and other kinds of works, specifically designed to ensure
        cooperation with the community in the case of network server software.
        
        The licenses for most software and other practical works are designed
        to take away your freedom to share and change the works.  By contrast,
        our General Public Licenses are intended to guarantee your freedom to
        share and change all versions of a program--to make sure it remains free
        software for all its users.
        
        When a program is modified and run on a server, its users cannot
        normally access its source code.  The GNU Affero General Public License
        is designed specifically to ensure that, in such cases, the modified
        source code becomes available to the community.
        
        The GNU Affero General Public License is based on the GNU General Public
        License, version 3.  It has been supplemented with an additional
        requirement to convey the corresponding source code of modified
        versions publicly when those versions are used in network server
        software.
        
        The precise terms and conditions for copying, distribution and
        modification follow.
        
        ## TERMS AND CONDITIONS
        
        ### 0. Definitions.
        
        “This License” refers to version 3 of the GNU Affero General Public License.
        
        “Copyright” also means copyright-like laws that apply to other kinds of
        works, such as semiconductor masks.
        
        “The Program” refers to any copyrightable work licensed under this
        License.  Each licensee is addressed as “you”.  “Licensees” and
        “recipients” may be individuals or organizations.
        
        To “modify” a work means to copy from or adapt all or part of the work
        in a fashion requiring copyright permission, other than the making of
        an exact copy.  The resulting work is called a “modified version” of the
        earlier work or a work “based on” the earlier work.
        
        A “covered work” means either the unmodified Program or a work based
        on the Program.
        
        To “propagate” a work means to do anything with it that, without
        permission, would make you directly or secondarily liable for
        infringement under applicable copyright law, except executing it on a
        computer or modifying a private copy.  Propagation includes copying,
        distribution (with or without modification), making available to the
        public, and in some countries other activities as well.
        
        To “convey” a work means any kind of propagation that enables other
        parties to make or receive copies.  Mere interaction with a user through
        a computer network, with no transfer of a copy, is not conveying.
        
        An interactive user interface displays “Appropriate Legal Notices”
        to the extent that it includes a convenient and prominently visible
        feature that (1) displays an appropriate copyright notice, and (2)
        tells the user that there is no warranty for the work, that licensees
        may convey the work under this License, and how to view a copy of this
        License.
        
        The “Corresponding Source” for a work in object code form means all the
        source code needed to generate, install, and (for an executable work)
        run the object code and to modify the work, including scripts to control
        those activities.  However, it does not include the work's System
        Libraries, or general-purpose tools or generally available free
License-File: LICENSE.md
Keywords: beanie,fastapi,mongodb,soft-delete
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: beanie>=2.0
Requires-Dist: pymongo>=4.0
Provides-Extra: dev
Requires-Dist: motor>=3.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# sysnet-soft-delete

Sdílená knihovna poskytující **konzistentní, bezpečný a snadno použitelný soft-delete mechanismus** pro mikroservisy postavené na **FastAPI + Beanie + MongoDB**.

```bash
pip install sysnet-soft-delete
```

<!-- kompatibilita -->
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white)](https://www.python.org/)
[![Beanie 2.x](https://img.shields.io/badge/beanie-2.x-4db33d?logo=mongodb&logoColor=white)](https://beanie-odm.dev/)
[![pymongo 4+](https://img.shields.io/badge/pymongo-4%2B-green)](https://pymongo.readthedocs.io/)
[![MongoDB 5+](https://img.shields.io/badge/MongoDB-5%2B-4db33d?logo=mongodb&logoColor=white)](https://www.mongodb.com/)
[![asyncio](https://img.shields.io/badge/asyncio-native-brightgreen?logo=python&logoColor=white)](https://docs.python.org/3/library/asyncio.html)
<!-- kvalita -->
[![Tests](https://img.shields.io/badge/tests-47%20passed-brightgreen?logo=pytest&logoColor=white)](tests/)
[![mypy](https://img.shields.io/badge/mypy-strict-2a6db5)](https://mypy.readthedocs.io/)
[![Typing](https://img.shields.io/badge/typing-py.typed-blueviolet)](https://peps.python.org/pep-0561/)
<!-- distribuce -->
[![PyPI](https://img.shields.io/pypi/v/sysnet-soft-delete?logo=pypi&logoColor=white)](https://pypi.org/project/sysnet-soft-delete/)
[![AGPLv3+](https://img.shields.io/badge/license-AGPLv3%2B-blue.svg)](LICENSE.md)

---

## Dokumentace

| Dokument | Popis |
|----------|-------|
| [Uživatelská příručka](docs/user-guide.md) | Instalace, API reference, příklady integrace s FastAPI, auditní logging |
| [Technická dokumentace](docs/technical.md) | Architektura, designová rozhodnutí, testovací strategie, jak přispívat |
| [Manažerský přehled](docs/management-summary.md) | Přínosy, rizika, roadmap, migrace |
| [Changelog](CHANGELOG.md) | Historie verzí |

**Repozitář:** [github.com/sysnet-cz/sysnet-soft-delete](https://github.com/sysnet-cz/sysnet-soft-delete)

---

## Problém, který knihovna řeší

| Problém | Řešení |
|---------|--------|
| Nekonzistentní filtrování `is_deleted` | `SoftDeleteRepository` vynucuje filtr vždy |
| Opakovaný boilerplate kód | Jeden mixin, jeden import |
| Chybějící audit (`deleted_at`, `deleted_by`) | Součást mixinu, volitelný audit port |
| Riziko návratu smazaných dokumentů | `find_active()` / `get_active()` jako primární API |
| Konflikty s unikátními indexy | Vzor `partialFilterExpression` (viz dokumentace) |

---

## Rychlý start

### 1. Model

```python
from beanie import Document
from sysnet_soft_delete import SoftDeleteMixin

class Article(SoftDeleteMixin, Document):
    title: str
    author: str

    class Settings:
        name = "articles"
```

> **Pořadí dědičnosti:** `SoftDeleteMixin` musí být **před** `Document` v MRO.

### 2. Repository

```python
from sysnet_soft_delete import SoftDeleteRepository

class ArticleRepository(SoftDeleteRepository[Article]):
    pass

repo = ArticleRepository(Article)
```

### 3. Použití

```python
# Vytvoření
article = Article(title="Hello World", author="Jan")
await article.insert()

# Soft delete
await article.soft_delete(deleted_by="admin@example.com")
# article.is_deleted == True
# article.deleted_at  == datetime(...)
# article.deleted_by  == "admin@example.com"

# Dotazy — smazaný článek se neobjeví
active = await repo.find_active()                        # []
one    = await repo.get_active(article.id)               # None
one    = await repo.find_one_active({"author": "Jan"})   # None (smazaný)
count  = await repo.count_active()                       # 0

# Obnovení
await article.restore(restored_by="admin@example.com")
# article.is_deleted == False

# Explicitní opt-in pro smazané záznamy
all_docs = await repo.find_all_including_deleted()
```

---

## API — přehled

### `SoftDeleteMixin`

```python
async def soft_delete(self, deleted_by: str | None = None) -> None
async def restore(self, restored_by: str | None = None) -> None
```

Pole: `is_deleted: bool`, `deleted_at: datetime | None`, `deleted_by: str | None`

### `SoftDeleteRepository[D]`

```python
await repo.find_active(*conditions, sort=None, limit=None, skip=None)
await repo.find_one_active(*conditions)          # v0.2.0+
await repo.get_active(document_id)
await repo.count_active(*conditions)
await repo.find_all_including_deleted(*conditions, ...)
```

### Auditní port

```python
from sysnet_soft_delete import configure_audit_logger

configure_audit_logger(SysnetAuditAdapter())  # volat jednou při startu
```

Adapter musí implementovat: `async def log(action, entity, entity_id, actor, metadata, timestamp)`.

### Výjimky

```python
from sysnet_soft_delete import AlreadyDeletedException, NotDeletedException
```

Kompletní API reference → [docs/user-guide.md](docs/user-guide.md)

---

## Verzování

Projekt dodržuje [Semantic Versioning](https://semver.org/).
`AuditLogger` Protocol je **veřejné API** — breaking změna = major verze.

Viz [CHANGELOG.md](CHANGELOG.md) pro historii změn.

---

## Vývoj a testování

```bash
pip install -e ".[dev]"
pytest
```

Testy běží proti real MongoDB instanci (žádné mocky). Výchozí URL: `mongodb://root:s3cr3t@localhost:27017`.
Přepíšete přes proměnnou prostředí:

```bash
TEST_MONGO_URL="mongodb://user:pass@host:27017" pytest
```

---

## Licence

AGPLv3+ — SYSNET s.r.o.
