Metadata-Version: 2.4
Name: client-core
Version: 0.1.0
Summary: Brique réutilisable CRM clients finaux (CDC-CLIENT-CORE-v1) — embarquée par chaque app, données par app, GDPR first-class. Symétrique de fin-core.
Author: Holding MAPFARM
License: Proprietary
Keywords: clients,consentement,consolidation,crm,gdpr,mapfarm
Requires-Python: >=3.11
Requires-Dist: pydantic>=2
Provides-Extra: db
Requires-Dist: psycopg[binary]>=3; extra == 'db'
Provides-Extra: test
Requires-Dist: psycopg[binary]>=3; extra == 'test'
Requires-Dist: pytest>=8; extra == 'test'
Requires-Dist: testcontainers[postgres]>=4; extra == 'test'
Description-Content-Type: text/markdown

# client-core

**Brique logicielle réutilisable** — **CRM clients finaux** : registre client générique, identité/
déduplication, **moteur de consentement (GDPR)**, segmentation, historique relationnel, **journal
d'audit inviolable**, et **contrat de consolidation** vers le Cockpit.

Spécifiée par `CDC-CLIENT-CORE-v1` (Holding MAPFARM ; `docs/`). **Symétrique de `fin-core`** :
`fin-core` gère l'argent, `client-core` gère la relation (qui est le client, son histoire, son
consentement) — liées par l'ordre (OMS), jamais fusionnées. Chaque application embarque la brique et
**possède ses propres données** (store par app) ; le Cockpit **consolide** une vue 360 par read-model
HTTP et **n'écrit jamais** dans les stores des apps.

> Ce dépôt = **Livrable 0** du CDC : la brique seule (modèle §5, identité §6.1, consentement §6.2/§7,
> effacement §6/G4, audit G2, contrat de consolidation §3.3/§6.5). Le câblage consommateur (Harvest L1,
> Cockpit L2, reconnaissance 360 L3) est hors de ce dépôt.

## Principes (non négociables — CDC §7/§8)

| # | Règle |
|---|---|
| R1 | Tout objet client tagué `entite_id` + `societe_id` + `marque_id` (canon référentiel). |
| R2/R3 | Chaque app **propriétaire** de ses clients ; aucun store partagé en écriture (séparabilité). |
| R5 | **Identité dédoublonnée**, jamais de doublon fabriqué (freeze-au-write). |
| R6 | **Contrat de consolidation standardisé** émis vers le Cockpit. |
| R7 / G1 | **GDPR fail-closed** : doute consentement/effacement → ne pas envoyer / effacer. |
| R8 | Pas de fusion client ↔ tiers (`fin-core`) ; pas de copie (références only). |
| G2 | **Auditable** : tout accès/écriture/export tracé (chaîne de hash inviolable). |
| G4 | **Droit à l'effacement** honoré + propagé (y compris read-model 360). |

GDPR *by design* : consentement gouverné par **canal × finalité**, horodaté, avec preuve ; la garde
`ConsentEngine.can_contact` est **l'unique** point d'autorisation de contact, **fail-closed**.

## Installation (registre PyPI Gitea)

```bash
pip install client-core --extra-index-url https://git.mapfarm.cloud/api/packages/mapfarm/pypi/simple/
```

## Usage (brique embarquée par une app)

```python
from client_core import ConsentEngine, Canal, Finalite
from client_core.schema import apply_schema   # extra [db]

apply_schema(conn, "xavier__monapp__crm")     # DDL idempotent sur le schéma de l'app
engine = ConsentEngine()
if engine.can_contact(consents=consents, canal=Canal.EMAIL, finalite=Finalite.MARKETING, now=now):
    ...                                        # envoi marketing autorisé (sinon fail-closed)
```

## Développement

```bash
make install      # pip install -e ".[test]"
make lint         # ruff check + format --check
make test         # pytest (purs + intégration DB si Docker/CLIENT_CORE_TEST_DSN)
make build        # sdist + wheel
```
