diff --git a/CHANGELOG.md b/CHANGELOG.md
index 224008f7e..47498be79 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,30 +1,5 @@
-
# Changelog
-## [1.0.8-rc33] - unstable
-
-### Added
-
-### Changed
-
-### Fixed
-
-* [PostIt.Android] Avoid applying camera sensor rotation twice: account for the rotation already included in Camera2's SurfaceTexture matrix before rotating encoder input, while retaining portrait output dimensions.
-* [PostIt.Android] Fix zero-second camera captures after adding OpenGL rotation: align Camera2 timestamps with the recorder's monotonic clock, preserve frame intervals, ignore duplicate frames and start camera requests only after the encoder is ready. Add a real Camera2/microphone regression check for segment duration and H.264/AAC tracks.
-* [PostIt.Android] Keep the `VideoLAN.LibVLC.Android` JNI/native bindings alive in Release builds with a ProGuard rule set so the bundled `libvlc`/`libc++_shared` libraries are not stripped.
-* [PostIt.Android] Rotate camera frames before H.264 encoding using an OpenGL surface, based on sensor orientation, lens facing and display rotation at capture start. Portrait captures swap the encoded dimensions; live MPEG-TS/HLS and replays no longer depend on an ineffective MP4-only orientation hint. Restore compilation by reading display orientation from the activity rather than the capture service.
-
-## [1.0.8-rc32] - unstable
-
-### Added
-
-### Changed
-
-### Fixed
-
-* Performer notification audience
-* [PostIt.Android] Upgrade `VideoLAN.LibVLC.Android` to 3.7.0-beta to resolve the runtime `failed to load libc++_shared.so` problem on 16 KiB-page Android devices and document the native-library compatibility requirement.
-
## [1.0.8-rc31] - unstable
### Added
@@ -41,6 +16,7 @@
* avoid NRE in MailSender on rdv query notifications
* Android emulator smoke test skipped in CI because Calabash instrumentation signature mismatches the target APK on hosted runners
+
## [1.0.8-rc30] - unstable
### Added
diff --git a/INSTALL.md b/INSTALL.md
index 5cea2b6f0..99c4f04b5 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -166,15 +166,6 @@ at IDR frames, with timestamps used for segment durations. Closed segments
enter the same ordered upload/retry/quota/replay pipeline as desktop.
Devices without a supported camera/encoder report a startup error.
-Camera frames are rotated through an OpenGL surface before encoding, so both
-live playback and replays have upright pixels without relying on rotation
-metadata (not supported by the MPEG-TS recorder). The sensor, front/rear lens
-and display orientation are sampled when capture starts; portrait output swaps
-width and height. Camera2 may already include sensor rotation in the
-SurfaceTexture transform; only the remaining rotation is applied by OpenGL.
-Keep that device orientation during a broadcast, or stop and
-start a new broadcast after turning the device.
-
A camera/microphone foreground service and a partial wake lock maintain the
broadcast when PostIt is backgrounded or the screen locks. Its ongoing
notification returns to the app and offers **Arreter et publier**. Stopping
@@ -185,13 +176,12 @@ camera; segments already received by the server remain available under the
interrupted-replay rules above. Device power policies can impose additional
restrictions and must be tested on the intended physical devices.
-**Native library compatibility:** the Android app now uses
-`VideoLAN.LibVLC.Android` 3.7.0-beta, which is the minimum compatible package
-for 16 KiB-page devices. Older 3.6.5 binaries can fail at runtime with
-`failed to load libc++_shared.so` or the linker error `XA0141` because the
-native libraries are not aligned for 16 KiB memory pages. A successful APK
-build or a test on a 4 KiB-page emulator does not establish compatibility
-for 16 KiB-page devices or Play distribution requiring that alignment.
+**Native library limitation:** bundled `VideoLAN.LibVLC.Android` 3.6.5 emits
+`XA0141`: its native libraries are not aligned for 16 KiB memory pages.
+Playback on 16 KiB-page devices and store distribution requiring this alignment
+are not validated/supported by this package choice. A compatible native LibVLC
+release is required before claiming that support; a successful APK build or
+a test on a 4 KiB-page emulator does not establish it.
Build with the Android workload and SDK configured:
diff --git a/doc/README.md b/doc/README.md
index 10e32b0c9..fb9bea943 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -16,7 +16,6 @@ La racine de l'architecture est [Architecture.md](Architecture.md).
| [architecture/offres-frontmatter.md](architecture/offres-frontmatter.md) | Offre fournisseur, ClasseFormulaire, ClasseDevis, parsing frontmatter |
| [architecture/postit-oidc.md](architecture/postit-oidc.md) | Client desktop PostIt, custom URI scheme, silent refresh |
| [architecture/postit.md](architecture/postit.md) | PostIt — topologie des projets, ViewLocator custo, navigation, DI, conventions de binding |
-| [architecture/notifications.md](architecture/notifications.md) | Notifications persistées, messages Web et événements temps réel côté serveur, Web et PostIt |
| [architecture/decoupage-organisation.md](architecture/decoupage-organisation.md) | Découpage des projets .NET (Abstract, Server, Org, Api, Blogs, Web, Org.Tests) |
| [testing.md](testing.md) | Stratégie de test : conventions des dossiers, EF Core in-memory, auth stubs, scaffold partagé |
| [onboarding-agents.md](onboarding-agents.md) | Parcours pas-à-pas pour prise en main agents IA + architecture + tests |
diff --git a/doc/architecture/notifications.md b/doc/architecture/notifications.md
deleted file mode 100644
index 8cf85cfb8..000000000
--- a/doc/architecture/notifications.md
+++ /dev/null
@@ -1,229 +0,0 @@
-# Notifications Yavsc : serveur, Web et PostIt
-
-Ce document décrit les mécanismes de notification actuellement présents
-dans le dépôt. Le terme « notification » recouvre plusieurs flux distincts :
-
-1. les **annonces persistées** en base, affichées dans le site Web et sur
- l'accueil de PostIt ;
-2. les **messages temporaires de l'interface Web**, attachés à une réponse
- MVC par `ViewBag.Notify` ;
-3. les **événements temps réel** du chat et les événements métier diffusés par
- SignalR.
-
-Ces flux n'ont ni le même stockage, ni le même cycle de vie, ni les mêmes
-clients.
-
-## Vue d'ensemble
-
-| Flux | Serveur / transport | Web | PostIt |
-|---|---|---|---|
-| Annonce persistée | Entité `Notification` en base, API HTTP | Affichée dans le layout et masquable | Liste sur `HomePage`, chargée par HTTP et masquable |
-| Message d'interface | Liste de portée requête dans `ViewBag.Notify` | Affichée comme alerte dans le layout | Non consommé |
-| Événement de chat | Hub SignalR authentifié à `/chathub` | Le site Web n'en consomme pas dans ses vues MVC | `notifyUser` et `notifyRoom` alimentent les journaux du chat |
-| Événement métier `push` | SignalR vers les connexions actives, plus e-mail | Pas de consommateur identifié dans les vues Web | Pas de gestionnaire `push` dans le client PostIt actuel |
-
-Les notifications persistées sont donc différentes d'une notification système
-native (notification du navigateur ou du système d'exploitation). Le client
-PostIt affiche une liste dans sa page d'accueil ; il ne demande pas de
-permission de notification native.
-
-## 1. Annonces persistées
-
-### Modèle et stockage
-
-L'entité partagée [`Notification`](../../src/Yavsc.Abstract/Messaging/Notification.cs)
-est enregistrée dans la table `Notification` via `ApplicationDbContext`.
-Elle contient :
-
-- `Id`, identifiant généré ;
-- `title` et `body`, obligatoires, limités respectivement à 1 024 et 512
- caractères ;
-- `icon`, `sound`, `tag`, `color`, propriétés optionnelles ;
-- `click_action`, obligatoire, utilisé comme libellé d'action dans les
- interfaces ;
-- `Target`, chaîne de ciblage. Les valeurs documentées par le modèle sont
- `null` (tout le monde), `user/{UserId}`, `pub/{topic}` et
- `administration`.
-
-Le masquage d'une annonce pour un utilisateur connecté est stocké dans
-`DismissClicked`, avec une clé composée de l'identifiant utilisateur et de
-l'identifiant de notification. Le même avis peut ainsi être masqué
-indépendamment par chaque utilisateur.
-
-### API
-
-[`NotificationsApiController`](../../src/Yavsc.Api/Controllers/Administration/NotificationsApiController.cs)
-expose les deux routes GET suivantes, sous le préfixe `/api/v1` :
-
-| Route | Accès | Résultat |
-|---|---|---|
-| `GET /api/v1/notifications` | Anonyme ou authentifié | Notifications visibles à l'appelant, non masquées |
-| `GET /api/v1/notifications/me` | Anonyme ou authentifié | Même action et mêmes règles que la route sans suffixe |
-
-La réponse est une liste JSON triée par `Id` décroissant. L'API exclut les
-notifications masquées par l'utilisateur authentifié, puis applique les
-règles d'audience : cible vide, cible `pub/…`, cible correspondant à
-`user/{identifiant courant}`, ou cible `administration` pour un administrateur.
-Une requête anonyme n'a ni identifiant utilisateur ni rôle administrateur.
-
-[`DismissClicksApiController`](../../src/Yavsc.Api/Controllers/Administration/DismissClicksApiController.cs)
-est réservé aux utilisateurs authentifiés :
-
-| Route | Effet |
-|---|---|
-| `GET /api/v1/dismiss` | Liste les identifiants masqués par l'utilisateur |
-| `POST /api/v1/dismiss/click/{notificationId}` | Masque l'avis pour l'utilisateur ; l'opération est idempotente |
-| `DELETE /api/v1/dismiss/click/{notificationId}` | Rétablit l'avis s'il était masqué ; renvoie `404` sinon |
-
-Le POST renvoie `404` si l'identifiant de notification n'existe pas. Le modèle
-de réponse est [`DismissedNotification`](../../src/Yavsc.Abstract/Messaging/DismissedNotification.cs).
-
-### Création et notifications métier
-
-Le contrôleur MVC
-[`NotificationsController`](../../src/Yavsc.Org/Controllers/Communicating/NotificationsController.cs)
-permet la gestion CRUD des enregistrements de notification.
-
-Le service [`YavscMessageSender`](../../src/Yavsc.Server/Services/YavscMessageSender.cs)
-crée aussi une notification persistée, ciblée sur `user/{id}`, pour les
-événements `RdvQueryEvent` et `ClientEstimateSignedEvent`. L'enregistrement
-est effectué avant l'envoi d'e-mail. Le même service tente ensuite d'envoyer
-un e-mail si l'adresse est disponible et confirmée, puis diffuse l'événement
-`push` aux connexions SignalR actives de l'utilisateur.
-
-Cette diffusion `push` est conditionnée par la présence de connexions actives ;
-l'avis stocké en base reste, lui, disponible lors d'une récupération ultérieure
-par l'API.
-
-## 2. Site Web
-
-### Annonces persistées sur l'accueil
-
-[`HomeController.Index`](../../src/Yavsc.Org/Controllers/HomeController.cs)
-charge les notifications non masquées et les place dans `ViewBag.Notify`.
-[`_Layout.cshtml`](../../src/Yavsc.Org/Views/Shared/_Layout.cshtml) les rend
-comme des alertes Bootstrap avec icône, titre, corps et action. Le titre et le
-corps passent par les composants Markdown du site.
-
-Le clic sur l'action appelle `POST /Home/DismissNotification/{id}` via
-[`site.js`](../../src/Yavsc.Org/wwwroot/js/site.js) :
-
-- pour un utilisateur connecté, le masquage est enregistré dans
- `DismissClicked` ;
-- pour un visiteur anonyme, les identifiants sont conservés dans la session
- Web (`clicked`).
-
-La route renvoie `404` si l'avis n'existe pas et `204` après le masquage.
-Comme l'API, l'accueil Web filtre `Target` : les cibles `user/{id}` ne sont
-visibles qu'à l'utilisateur correspondant, et la cible `administration`
-uniquement aux administrateurs. Un visiteur anonyme ne reçoit que les
-notifications publiques (`Target` vide ou préfixe `pub/`).
-
-### Messages temporaires par requête
-
-Les helpers [`NotifyInfo`, `NotifyWarning` et `Notify`](../../src/Yavsc.Org/Helpers/ControllerHelpers.cs)
-ajoutent des objets à `ViewBag.Notify`. Ce mécanisme n'écrit pas en base :
-il ne vit que dans la réponse MVC qui rend le layout. Les méthodes
-`NotifyInfo` et `NotifyWarning` partagent actuellement le même rendu générique
-`alert-info`.
-
-## 3. PostIt
-
-[`NotificationsApiClient`](../../src/Yavsc.Api.Client/NotificationsApiClient.cs)
-construit les routes à partir de la base d'API de l'hôte métier configuré.
-Il fournit les méthodes de lecture publique et authentifiée, ainsi que les
-opérations de lecture, masquage et restauration.
-
-Sur [`HomePage`](../../src/PostIt/PostIt/Views/Layout/HomePage.axaml),
-[`HomePageViewModel`](../../src/PostIt/PostIt/ViewModels/Layout/HomePageViewModel.cs)
-charge la liste :
-
-- sans session valide, il appelle la route publique
- `GET /api/v1/notifications` ;
-- avec une session valide, il appelle
- `GET /api/v1/notifications/me` avec le client HTTP authentifié.
-
-Le chargement est lancé à l'ouverture de la page et relancé lorsque l'état de
-connexion change. Un compteur de version ignore les réponses obsolètes si un
-chargement plus récent a déjà commencé. L'interface distingue l'état de
-chargement, la liste vide et l'erreur de chargement ; l'utilisateur peut aussi
-actualiser manuellement.
-
-Le bouton d'une notification utilise `click_action` comme libellé et masque
-l'élément. En session authentifiée, PostIt appelle
-`POST /api/v1/dismiss/click/{id}` avant de retirer l'élément de la liste. Si
-l'appel échoue, l'élément reste affiché et une erreur est présentée. Sans
-session, l'élément est retiré de la liste locale, sans persistance du
-masquage côté serveur.
-
-## 4. Événements temps réel
-
-### Hub du chat
-
-Le hub [`ChatHub`](../../src/Yavsc.Server/Hubs/ChatHub.cs) est publié par
-Yavsc.Api à la racine sous `/chathub` (et non sous `/api/v1`) et porte
-`[Authorize]`. Il s'appuie sur SignalR et sur `IConnexionManager` pour suivre
-les utilisateurs et les salons.
-
-Les événements de notification émis par le hub comprennent notamment :
-
-| Événement SignalR | Données | Utilisation PostIt |
-|---|---|---|
-| `notifyUser` | `type`, identifiant ou nom cible, message | Ajout au journal système |
-| `notifyRoom` | `type`, salon, utilisateur ou détail | Ajout au journal du salon ; met à jour la liste d'utilisateurs sur `UserJoin` |
-| `joint` | `ChatRoomInfo` | Initialise la vue du salon rejoint |
-| `ReceiveMessage` | message avec nom, salon et corps | Ajoute le message à l'historique du salon |
-| `notifyUserInRoom` | `type`, salon, message | Pas de gestionnaire correspondant dans `ChatViewModel` actuellement |
-
-Les constantes de types du chat sont déclarées dans
-[`NotificationTypes`](../../src/Yavsc.Abstract/Messaging/NotificationTypes.cs).
-Les messages `notifyUser` et `notifyRoom` ne sont pas enregistrés en base :
-ils décrivent l'état temps réel de connexion, de salon ou les erreurs de
-conversation.
-
-Le [`ChatViewModel`](../../src/PostIt/PostIt/ViewModels/Chat/ChatViewModel.cs)
-ouvre le hub avec le jeton d'accès PostIt, tente un renouvellement silencieux
-du jeton, et active la reconnexion automatique. Après reconnexion, il rejoint
-à nouveau le salon sélectionné, car la connexion SignalR précédente et ses
-groupes ne sont plus actifs. Les callbacks mettent à jour les collections sur
-le thread UI d'Avalonia.
-
-### Événement métier `push`
-
-En plus des événements du chat, `YavscMessageSender` utilise le même contexte
-SignalR pour émettre `push` avec le topic et une charge utile sérialisée. Ce
-nom d'événement est distinct de `notifyUser` et `notifyRoom`. Aucun
-gestionnaire `push` n'est présent dans le client PostIt actuel : les annonces
-métier persistées sont visibles dans PostIt lors du prochain chargement ou
-rafraîchissement HTTP.
-
-## 5. Points d'attention pour les évolutions
-
-- Conserver les règles d'audience alignées entre l'API et le site Web ; en
- particulier, appliquer un filtrage `Target` côté Web avant d'exposer les
- avis dans le layout.
-- Ne pas confondre masquage utilisateur (`DismissClicked`) et suppression
- globale de la notification : le masquage API est par utilisateur.
-- Les sessions anonymes du site Web et PostIt n'ont pas le même comportement :
- le site Web conserve le masquage en session, tandis que PostIt ne le garde
- que dans la liste affichée jusqu'au prochain rechargement.
-- Ajouter un nouveau type de cible ou un nouvel événement temps réel implique
- d'examiner séparément son filtrage, son transport et les clients qui
- l'écoutent.
-- Les références à GCM et le nom historique de `YavscMessageSender` ne
- signifient pas que PostIt reçoit une notification native hors ligne : le
- chemin observé ici est l'e-mail, l'événement SignalR temps réel et la
- notification persistée récupérée par HTTP.
-
-## Références d'implémentation
-
-- [`Notification`](../../src/Yavsc.Abstract/Messaging/Notification.cs)
-- [`NotificationsApiController`](../../src/Yavsc.Api/Controllers/Administration/NotificationsApiController.cs)
-- [`DismissClicksApiController`](../../src/Yavsc.Api/Controllers/Administration/DismissClicksApiController.cs)
-- [`NotificationsController`](../../src/Yavsc.Org/Controllers/Communicating/NotificationsController.cs)
-- [`HomeController`](../../src/Yavsc.Org/Controllers/HomeController.cs)
-- [`YavscMessageSender`](../../src/Yavsc.Server/Services/YavscMessageSender.cs)
-- [`ChatHub`](../../src/Yavsc.Server/Hubs/ChatHub.cs)
-- [`NotificationsApiClient`](../../src/Yavsc.Api.Client/NotificationsApiClient.cs)
-- [`HomePageViewModel`](../../src/PostIt/PostIt/ViewModels/Layout/HomePageViewModel.cs)
-- [`ChatViewModel`](../../src/PostIt/PostIt/ViewModels/Chat/ChatViewModel.cs)
diff --git a/doc/testing.md b/doc/testing.md
index 7b5de174f..8b5e8eff1 100644
--- a/doc/testing.md
+++ b/doc/testing.md
@@ -97,59 +97,6 @@ decodage authentifie du replay. Aucun FFmpeg n'est requis par ces tests ni
par l'application (le fichier d'entree peut provenir de n'importe quelle source).
Les tests materiels camera/microphone Windows/Linux restent manuels.
-### Rotation de la capture Android
-
-Le calcul capteur/ecran/camera avant et les quatre transformations de texture
-sont couverts sans appareil :
-
-```bash
-dotnet test --project src/PostIt/PostIt.Tests/PostIt.Tests.csproj \
- --filter-class '*CameraFrameOrientationTests' --filter-class '*CameraFrameClockTests'
-```
-
-Un test Android supplementaire verifie le chemin OpenGL et l'encodeur reels,
-sans ouvrir la camera, sans microphone et sans contacter l'API :
-
-```bash
-dotnet build src/PostIt/PostIt.Android/PostIt.Android.csproj -c Debug \
- -p:EmbedAssembliesIntoApk=true
-adb install -r -t src/PostIt/PostIt.Android/bin/Debug/net10.0-android/fr.pschneider.postit-Signed.apk
-adb shell am start -n fr.pschneider.postit/fr.pschneider.postit.CameraFrameRotationTestActivity
-adb shell run-as fr.pschneider.postit cat files/camera-rotation-test-result.txt
-```
-
-Attendre la fin du test : `RUNNING` doit devenir `PASS`. Il encode quatre
-quadrants colores en MPEG-TS pour 0, 90, 180 et 270 degres, decode une image et
-verifie les dimensions (640x480 ou 480x640) et les couleurs aux quatre positions.
-La tolerance de chaque composante RGB est de 40 pour tenir compte de H.264.
-Une erreur de rendu, d'encodage, de decodage ou de comparaison produit `FAIL`
-avec l'exception. Cette activite est exclue des builds Release.
-
-Le test synthetique ne couvre pas l'horloge Camera2 ni sa synchronisation avec
-le microphone. Avec l'accord de la personne utilisant le telephone, lancer
-aussi le test local reel (camera et microphone actifs, aucun envoi a l'API) :
-
-```bash
-adb shell am start -n fr.pschneider.postit/fr.pschneider.postit.PodcastCaptureTestActivity --es microphone true
-adb shell run-as fr.pschneider.postit cat files/podcast-capture-test-result.txt
-```
-
-Attendre `PASS` : au moins trois segments, 8 a 16 secondes capturees,
-pistes H.264 et AAC presentes, et progression des segments en arriere-plan.
-Ce test detecte notamment les captures de zero seconde dues au decalage entre
-l'horloge Camera2 et celle de MediaRecorder. Les fichiers restent dans le
-repertoire prive indique par le resultat pour verification locale.
-Le resultat inclut les angles capteur/ecran et la premiere matrice
-SurfaceTexture recue. Les tests unitaires couvrent notamment la matrice
-reelle `[0,-1,0,0,-1,0,0,0,0,0,1,0,1,1,0,1]` : pour un capteur a 90 degres
-et un ecran a 0, elle porte deja la rotation et ne doit pas recevoir 90 degres
-supplementaires. Le test synthetique seul ne detecte pas cette double rotation.
-
-Verifier aussi manuellement les cameras avant/arriere en portrait et paysage,
-le son, le direct et le replay, et la poursuite de l'emission en arriere-plan.
-L'orientation est fixee au demarrage d'une emission ; tourner le telephone
-pendant l'emission ne reconfigure pas le format encode.
-
## Quand ne PAS écrire de test
Un test qui ne détecte rien n'est pas un test. Si l'invariant
diff --git a/src/PostIt/Directory.Packages.props b/src/PostIt/Directory.Packages.props
index ae6708992..a6a656368 100644
--- a/src/PostIt/Directory.Packages.props
+++ b/src/PostIt/Directory.Packages.props
@@ -19,7 +19,7 @@
-
+
diff --git a/src/PostIt/PostIt.Android/PostIt.Android.csproj b/src/PostIt/PostIt.Android/PostIt.Android.csproj
index 5b7f4f968..0923e8a12 100644
--- a/src/PostIt/PostIt.Android/PostIt.Android.csproj
+++ b/src/PostIt/PostIt.Android/PostIt.Android.csproj
@@ -31,7 +31,6 @@
-