Constrain the blog page layout, separate list and article scrolling, and remove content height limits and nested editor scrolling. Add six headless regression cases and update the changelog and layout documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
45 KiB
Changelog
[1.0.8-rc24] - unstable
Added
- [PostIt] Reconnection automatique aux salons de discussion au reconnect
Changed
- [PostIt] La liste des billets et l'éditeur Markdown se partagent l'espace disponible et défilent séparément ; un séparateur permet de redimensionner les deux zones.
Fixed
- [PostIt] Défilement des articles longs en édition et en aperçu : suppression de la limite de hauteur qui masquait le contenu Markdown et du défilement imbriqué autour d'AvaloniaEdit. Six tests headless couvrent les barres automatiques, le redimensionnement et le défilement indépendant de la liste.
[1.0.8-rc23] - unstable
Added
- [PostIt] Badge « Publié » à côté du titre des billets publiés dans la liste, mis à jour lors de la publication ou du retour en brouillon.
- [PostIt] Gestion native du compte inspirée de
/Manage: modification du nom d'utilisateur, du nom complet et de l'adresse, téléversement d'avatar, confirmation e-mail, préférence de courriel mensuel, création ou changement de mot de passe et activation/désactivation de l'authentification à deux facteurs. - [PostIt][Yavsc.Api] Sélection d'un agenda Google, gestion séparée des comptes bancaires, dissociation des connexions externes et suppression du compte avec confirmation du nom d'utilisateur.
- [PostIt] Configuration du profil professionnel et des activités, navigation vers les cercles et les publications depuis le compte.
- [PostIt][Yavsc.Api] Administration des utilisateurs avec recherche dans les métadonnées du profil et consultation de la consommation de ressources.
- [Yavsc.Server][Yavsc.Api][Yavsc.Blogs] Suivi de la consommation de
ressources, API de synthèse et migration
ResourceUsageRecords. - [Tests] Couverture des parcours profil et professionnel, de l'API de consommation de ressources et du renouvellement des jetons : rotation à usage unique, appels simultanés, réponses 401 concurrentes et rejet d'un jeton de renouvellement révoqué.
Changed
- [PostIt] Réorganisation de la page de compte en sections de profil, sécurité et préférences ; actions de modification désactivées tant que le profil n'est pas chargé ou qu'une opération est en cours.
- [PostIt] Utilisation de
PlaceholderTextà la place deWatermarkdans les pages de profil et de configuration professionnelle. - [Yavsc.Api]
GET account/merenvoie le DTO partagé attendu par PostIt, avec l'état de sécurité, les connexions externes, les comptes bancaires et les compteurs du compte.
Fixed
- [Yavsc.Api] Enregistrement des services ASP.NET Identity et des stores
EF nécessaires à
UserManager<ApplicationUser>: leur absence empêchait l'activation du contrôleur de compte et provoquait une 500. - [Yavsc.Api] Chargement du profil : réponse adaptée lorsqu'un jeton ne contient pas d'identifiant utilisateur ou que le compte n'existe plus, au lieu d'une exception serveur.
- [PostIt] Synchronisation de tous les chemins de renouvellement des
jetons, y compris après une 401 et au démarrage : les appels
concurrents ne réutilisent plus le même
refresh_token. Un rejetinvalid_grantefface la session et invite à se reconnecter. - [PostIt] Effacement des informations obsolètes après un échec de rechargement du profil et normalisation des valeurs de calendrier lors de la sauvegarde.
- [PostIt][Yavsc.Api] Préservation de l'identité du profil professionnel lors de son enregistrement.
- [Yavsc.Api] Les coordonnées bancaires ne sont plus modifiées à partir d'un résumé agrégé : opérations dédiées avec contrôle de propriété et validation de longueur des champs.
Known limitations
- [PostIt] L'ajout d'un nouveau fournisseur OAuth et la gestion des crédits ne sont pas encore disponibles dans l'interface native.
[1.0.8-rc22] - unstable
Fixed
User experience login into PostIt
[1.0.8-rc21] - unstable
Fixed
User experience editing the blog article.
[1.0.8-rc20] - unstable
Chat SignalR fonctionnel de bout en bout (connexion, salons multiples, envoi/réception de messages), enregistreur audio et localisation dans PostIt, intégration Live.Avalonia démarrée, et reverse-proxy nginx apprêté pour WebSocket.
Added
- [PostIt] Interface de chat : page
ChatPage(connexion au hub, saisie du nom de salon, liste des messages et des membres présents), entrée depuis la page d'accueil. - [PostIt] Envoi de messages dans un salon joint : DTO
ChatMessage(Name/Room/Message) pour l'événementReceiveMessage, saisie avec envoi surEnter, commande inactive tant qu'aucune salle n'est en focus (le hub refuse l'envoi hors salon,LabNoJoinNoSend). - [PostIt] Modèle multi-salles côté client :
JoinedRooms,SelectedRoom(salle en focus), messages et utilisateurs indexés par salle (FocusedMessages/FocusedUsers), ComboBox de choix de la salle active ; unJoinsur une salle déjà jointe ne fait que changer le focus. - [PostIt] Enregistreur audio (
AudioRecorder, interfaceIPCMProcessor) et ressources de localisation (Resources.{resx,en-EN,pt-PT}). - [PostIt][WIP] Début d'intégration Live.Avalonia (preview XAML à chaud ; encore KO).
- [contrib] Bloc
location /chathubdanstemplate.vhost: upgrade WebSocket (Upgrade/Connection),proxy_read_timeout 3600setproxy_buffering off— sans quoi la connexion SignalR tombait au premier silence ou l'upgrade échouait derrière nginx.
Changed
- [PostIt]
StatusNoticedéplacé deModelsversViewModelset enrichi d'une commande d'action optionnelle (CheckCommand+CheckCommandLabel, interfaceIWithLabel) : le bandeau de statut propose désormais l'action contextuelle (Connecter / Déconnecter / Reconnecter / Vérifier la connexion). - [PostIt]
ChatViewModelsuit le cycle de vie complet de la connexion : handlersReconnecting/Reconnected/CloseddeWithAutomaticReconnect, pour refléter l'état réel au lieu d'unIsConnectedoptimiste. - [Yavsc.Api]
AddSignalR().AddJsonProtocol(IncludeFields = true):ChatRoomInfon'expose que des champs publics, que System.Text.Json ne sérialise pas par défaut — le client recevait des objets vides (Namenull,Usersvide) et la liste des salons joints n'était jamais alimentée. - [Yavsc.Server]
IConnexionManager.OnConnectedprend leuserNameen paramètre (résolu depuis les claims dansChatHub) au lieu de le relire depuis un dictionnaire jamais alimenté. - [PostIt.Android]
network_security_config.xmldéplacé sousResources/xml/(chemin canonique Android).
Fixed
- [Yavsc.Server]
KeyNotFoundExceptiondansHubConnectionManager.OnConnectedà chaque connexion SignalR :ChatUserNames(etChatCxIds) n'étaient jamais alimentés — relique d'unSetUserNamedisparu lors d'une refactorisation. L'exception dansOnConnectedAsyncfaisait fermer la connexion par le hub, et PostIt affichait « Déconnecté (The server closed the connection…) » immédiatement après la connexion. - [PostIt] URL du hub SignalR : retrait du préfixe
/api/v1deApiUrlavant d'apposerConstants.ChatHubPath(le hub est mappé à la racine du service, pas sous le préfixe versionné). - [PostIt] La
StatusBarde la page chat référençaitGrid.Row="4"sur une grille à 3 rangées (rangée hors limites, bandeau invisible).
[1.0.8-rc19] - unstable
[PostIt] Blogs UX
Fixed
La saisie du billet est maintenant plutôt possible, en petit écran.
1.0.8-rc18 - unstable
-
[PostIt] Page "About" avec lines vers le dépôt et les issues Forgejo
-
Accès aux fichiers personnels PostIt rendu fonctionnel de bout en bout (arbre de stockage indexé par le login, pas par le
sub), boutons d'action des listes réparés (binding$parent), revendicationnameenfin présente dans les access tokens (branchement duProfileService), et négociation HTTP/3 côté client PostIt.
Added
- [PostIt] Négociation HTTP/3 (QUIC) pour les appels API Yavsc :
DefaultRequestVersion = 3.0,DefaultVersionPolicy = RequestVersionOrLowersur leHttpClientpartagé deYavscApiClient, avec repli h2/h1.1 où QUIC n'est pas disponible (WASM fetch, Android/ desktop sans libmsquic). - [Tests]
MyFilesPageHeadlessTests: monteMyFilesPageviaNavigationPage+Window.Show()et vérifie que chaque bouton de ligne (Télécharger / Supprimer) a saCommandliée, est armé (CanExecute) et déclenche l'appel API au clic. - [Tests]
Remoting.PasswordToken_carries_name_claim_equal_to_login: mint un vrai JWT via le token endpoint IdentityServer (password grant,openid profile) et asserte que l'access token portename=login et queGetUserName()résout vers ce login. - [Tests]
FileSystemApiTests.Get_fs_lists_files_stored_under_the_user_login: découplesubet login, téléverse sous le login, et asserte queGET /api/v1/fsretourne le fichier (et que le répertoire nommé d'après lesubn'existe pas).
Changed
- [Yavsc.Org] Branchement du
ProfileServicecustom (AddProfileService<ProfileService>()aprèsAddAspNetIdentity<ApplicationUser>()). La classe était du code mort : IdentityServer8 retombait sur son profile service par défaut, qui n'émet que les claims listés dans lesUserClaimsdes API resources.namen'en faisait jamais partie, donc tout access token était sansnameetGetUserName()résolvait ànullsur les hosts ressources (Blogs/Api) — cause du 500 sur l'upload MyFiles et duUser.Identity.Nameinjoignable. Le service émet désormaisname=user.UserName,emailet les rôles pour tout client dont lesAllowedScopescontiennentprofile, indépendamment du caller. - [Yavsc.Server]
ServiceExtensions:NameClaimType = JwtClaimTypes.Name,MapInboundClaims = false(conserver les noms courts de claims tels qu'émis). - [Yavsc.Blogs]
FileSystemHelpers.EnsureDestinationDirectoryutiliseGetUserName()(claimname) au lieu deUser.Identity.Namepour la racine de stockage par utilisateur. - [Tests]
WebServerFixture:AccessTokenType = 0(Jwt dans IS8 ; 1 = Reference, l'inverse de Duende) ;openid+profilesur le client de test ; réensemencement des identity resources openid/profile dansReseedAuthTestData(unResetAndMigrateDatabasevide le store in-memory partagé et les laissait absentes →invalid_scope). - [Tests]
TestTokenIssuer.Issuegagne un paramètrenameoptionnel (défaut = subject) pour refléter la forme production oùsub(GUID) ≠name(login). - [Tests]
BillingServiceTests:[Collection("Yavsc Server")]pour sérialiser avec le build d'hôte qui mute les registres statiquesBillingService/Config(race parallèle pré-existante).
Fixed
- [Yavsc.Blogs] La liste
GET /api/v1/fscherchait sous{Blog}/{sub-GUID}(User.GetUserId()), alors que l'arbre de stockage perso est indexé par le login partout ailleurs (EnsureDestinationDirectoryécrit sous{Blog}/{name-claim}, le endpoint de téléchargement et les avatars utilisentuser.UserName). Une fois l'upload corrigé, les fichiers atterrissaient sous{Blog}/{login}tandis que la liste cherchait sous{Blog}/{GUID}— un arbre vide — d'où la page PostIt « Mes fichiers » qui ne listait rien.GetDirrésout désormais l'utilisateur en base et liste soususer.UserName.UploadedFile.OwnerIdrestesub, doncEnrichWithFileIdsinterpole toujours paruid. - [PostIt] Boutons d'action des lignes de liste grisés et inactifs au
clic (Télécharger / Supprimer / Joindre sur MyFiles ; download/detach
sur les listes de pièces jointes de
BillingQueryDetailsPageetEstimateEditionPage). Le binding$parent[vm:XxxViewModel].Cmdcherchait un ancêtre CONTRÔLE de typeXxxViewModel— un viewmodel, pas un contrôle — donc résolvait ànullet leButtonrestait désactivé (grisé) et inerte au clic. Corrigé en$parent[ContentPage].((vm:XxxViewModel)DataContext).Cmd(syntaxe déjà en vigueur dansCirclesPage/EstimateListPage). - [PostIt] Les messages de la barre de statut (
StatusBar) n'étaient pas sélectionnables/copiables : le texte était unTextBlock(non sélectionnable dans Avalonia). Remplacé parSelectableTextBlock. - [Yavsc.Blogs] La suppression d'un fichier (
DELETE api/v1/fs/{name}) renvoyait un 40x alors que le fichier était bien supprimé du disque.DeleteUserDirOrFile(etDeleteUserFile) lisaientFileInfo.Lengthaprèsfi.Delete(); orFileInfo.LengthlèveFileNotFoundExceptionune fois le fichier disparu — lecatchdu contrôleur transformait cette exception en 400, d'où le message perçu « le fichier n'existe pas sur le serveur » tandis que la suppression avait réussi. La taille est désormais capturée avant la suppression. - PostIt default settings
1.0.8-rc17 - unstable
Fichiers utilisateur et pièces jointes sur les devis/demandes (PostIt +
API), système de génération contrib (vhosts nginx HTTP/3 edge +
appsettings jq + QUIC logiciel Kestrel), et correction du bug de
production où IsPublished disparaissait du payload de liste du blog API.
Added
- [PostIt] Espace de stockage personnel (« MyFiles ») : page de gestion des fichiers de l'utilisateur, entrée depuis la page d'accueil.
- [PostIt] Pièces jointes aux devis et aux demandes : attachement depuis le détail de demande et la page d'édition de devis.
- [Yavsc.Api] Endpoints d'attachement de fichiers sur les devis
(
EstimateApiController) et les demandes front-office (FrontOfficeApiController). - [Yavsc.Api.Client]
UserFilesApiClient+ DTOs associés ; méthodes d'attachement surEstimateApiClientetFrontOfficeApiClient. - [Yavsc.Server] Modèles
EstimateAttachedFile,QueryAttachedFile,BlogAttachedFile,AttachFileRequest; migration EF CoreUserFileAttachments. - [contrib] Système de génération
Makefile: vhosts nginx HTTP/3 edge (template.vhost,QUIC_OPTS), appsettings générés via jq (template.appsettings-{org,api,blogs}.json, échappement JSON-safe des secrets), QUIC logiciel Kestrel (Http1AndHttp2AndHttp3), etREADME.nginx.md. - [Tests] Projet
Yavsc.Server.Tests: tests du serviceBlogSpotService.Details+ServerServicesFixture(SQLite:memory:par défaut, Npgsql opt-in viaYAVSC_SERVER_TEST_DB_PROVIDER). - [Tests]
IBlogPostWireShapeTests(forme du wire blog),EstimateAttachmentsApiTests,FrontOfficeQueryAttachmentsApiTests,FileSystemApiTests(pièces jointes et stockage perso). - [CI] Intégration Gitleaks / analyse de secrets (
.pre-commit-config.yaml).
Changed
- [contrib]
QUIC_OPTS(reuseport) désormais activé uniquement en production sur le vhost Org. La preprod et la prod partageant la même IP,reuseport— légal une seule fois paraddr:port(443/udp) — serait sinon en conflit entre preprod-Org et prod-Org et ferait refuser la config par nginx. - [Yavsc.Api.Test]
ApiWebServerFixture: la connexion admin PostgreSQL provient de la variable d'environnementYAVSC_API_TEST_NPGSQL_ADMIN_CONNECTION; plus de mot de passe en source.
Fixed
- [Yavsc.Blogs] Bug de production :
IsPublishedétait absent du payload de la liste du blog API. Le endpointGetBlogspotretourneIEnumerable<IBlogPost>sérialisé par System.Text.Json d'après le type déclaré (l'interface), qui omet les propriétés du type concret —IsPublishedvivait surBlogPost/BlogPostDtomais pas surIBlogPost. PostIt lisait doncIsPublished == falsepour tout billet, y compris publiés (https://yavsc.pschneider.fr/BlogSpot/Details/13). Corrigé en déclarantIsPublishedsurIBlogPost. - [Yavsc.Org] Accès au Swagger UI : les actions MVC scaffoldées de
CommentsController(Index/Details/…) atterrissaient sur la même routePOST api/v1/blogcommentsque l'action d'APIPost, provoquant uneSwaggerGeneratorException(conflit method/path) au chargement de/swagger. Corrigé par[ApiExplorerSettings(IgnoreApi = true)]sur les actions scaffoldées.
1.0.8-rc16 - unstable
Flux de signature et de génération de devis : un devis peut désormais être signé par les deux parties (fournisseur et client) puis téléchargé en PDF ou TeX depuis PostIt, avec les signatures dessinées en vecteur.
Added
- [PostIt] Pad de signature sur la page de validation d'un devis : on valide ou on refuse en joignant une signature (côté fournisseur ou client), capturée au format filaire PostIt (strokes) et envoyée sur l'acceptation.
- [Yavsc.Api] Finalisation de
POST /api/v1/front/query/acceptet.../reject: autorisation selon le rôle (fournisseur/client/admin), signature optionnelle persistée sur l'estimate avec horodatageProviderValidationDate/ClientValidationDateselon le côté signataire. - [Yavsc.Api]
QueryStatus.Acceptedéclaté enProAccepted/ClientAcceptedpour distinguer l'acceptation de chaque partie. - [Yavsc.Api] Endpoints de devis
GET /api/v1/front/query/{id}/estimate.texetestimate.pdf(clé par id de query). Le flux de génération TeX/PDF est rapatrié de Yavsc.Org vers Yavsc.Api (TeXHelpers,PdfGenerationViewModel,BillViewComponent, modèles Bill/Estimate,_ViewImports;Program.cscâbleAddControllersWithViews+SiteSettings). - [Yavsc.Api] Signatures du devis dessinées en TikZ vectoriel
(
TeXHelpers.SignatureToTikz) en bas du document, fournisseur et client côte à côte dans deux minipages ; plus de dépendance à un PNG de signature. - [Yavsc.Api.Client]
DownloadAsyncsur le client +GetEstimateTexAsync/GetEstimatePdfAsync; boutons « Télécharger PDF » / « Télécharger TeX » dans PostIt sur la page de validation du devis et le détail de commande, avec un helperStorageProviderd'enregistrement de fichier. - [PostIt] La liste des devis se rafraîchit au retour de navigation (pop-back), de sorte qu'un devis validé quitte immédiatement la liste du signataire.
- [PostIt] Renommage des titres de liste : « Devis en attente de signature fournisseur » / « Devis en attente de signature client ».
- [Yavsc.Abstract]
SignatureTypedéplacé dansYavsc.Abstract.Billing. - [CLI] Option
-c configuration-file.jsonau lancement. - [Tests]
EstimatePdfGenerationTests: tests unitaires du pipeline signature → TikZ → PDF (devis signé des deux côtés), assertant que le PDF existe au chemin de sortie attendu et que seul le PDF persiste (aux/log nettoyés) ; skip propre silualatexest absent. - [README] Dépendances système au runtime pour la génération PDF :
texlive-binaries(lualatex),texlive-luatex(luaotfload),texlive-pictures(tikz),texlive-fonts-extra(bera).
Changed
- [Yavsc.Api]
GetOngoingEstimatesAsProviderfiltre désormais surProviderValidationDate: un devis signé par le fournisseur quitte sa liste « en attente ». - [Yavsc.Api] La génération PDF compile via le
lualatexsystème, le TeX fourni sur l'entrée standard (/dev/stdin), le PDF écrit directement dans le répertoire des factures (Site.Bills), les artefacts.aux/.lognettoyés afin que seul le.pdfpersiste.
Fixed
- [Yavsc.Api]
Emergency stopà la génération PDF :lualatexsans argument fichier lit stdin en mode terminal et s'arrête après la première ligne d'un document multi-lignes. Corrigé en passant/dev/stdincomme nom de fichier d'entrée — stdin est alors traité comme un fichier régulier et le document multi-lignes compile. C'était la cause racine de l'échec en production, pasberaniluaotfload(problèmes réels mais séparés, comblés côté paquets). - [Yavsc.Api]
I can't write on file 'estimate-1.log': le chemin relatifSite.Bills("bills") était imbriqué quand il servait à la fois de-output-directoryet de répertoire de travail ; résolu en chemin absolu. - [Yavsc.Api] NRE dans
RenderViewToString(RouteData /ViewData.Modelnuls) : reconstruit sur leControllerContextdu contrôleur ;IViewEnginerésolu viaIRazorViewEngine(.NET 10 n'enregistre pas deIViewEngineunique). - [Yavsc.Api]
Layout = "null"(chaîne) dans les modèles TeX cherchaitnull.cshtml; corrigé enLayout = null(null C#). - [Yavsc.Api]
texi2pdf(outil Texinfo, inadapté au LaTeX) remplacé parlualatex. - [Yavsc.Api] Les diagnostics lualatex étaient perdus (écrits dans le
.logqu'on supprimait) ; stdout/stderr sont désormais capturés dans le message d'erreur, et le.logest conservé en cas d'échec.
1.0.8-rc15 - unstable
Added
- [PostIt] Saisie et envoi de pieces jointes sur un billet de blog: le client monte les fichiers en
multipart/form-datalors duSave, ajoute un lien Markdown par piece jointe a l'article, puis re-PUT le billet. Une collectionDraftAttachmentsporte les fichiers en cours d'edition. - [PostIt] Apercu Markdown dans l'editeur de blogs (integration
MarkdownViewer.Core) avec bascule edition/preview surBlogsPage. - [PostIt] Gestion des devis: page de liste
EstimateListPage(vues client et prestataire), page d'editionEstimateEditionPageavec lignes de devis (EstimateLineItemViewModel), et flux de validation d'un devis. - [PostIt] Flux des requetes en cours cote prestataire (
ProviderOngoingRequestsPage) avec tri persistant. - [Yavsc.Api] Endpoints devis
GET /api/v1/estimate/asclientetGET /api/v1/estimate/asproviderpour lister les devis en cours selon le role. - [Yavsc.Api] Endpoint
GET /api/v1/billing/provider/ongoingetPOST /api/v1/billing/prosign/{billingCode}/{id}pour le flux prestataire. - [Yavsc.Api.Client]
EstimateApiClient+ DTOs (EstimateDto,EstimateLineDto) pour le pipeline devis cote client lourd. - [Yavsc.Api.Client] Reprise de l'upload de fichiers blog dans
BlogApiClient(CreateMultipartContent,BlogUploadFile) — la meme forme filaire que PostIt utilise en production. - [Yavsc.Abstract]
FileServerUrlHelperspour deriver les URLs publiques des fichiers utilisateur depuis l'autorite OIDC (alignement surUserFilesPath). - [Yavsc.Server]
BlogSpotService.AttachFiles: ecrit les pieces jointes sous la racine des fichiers utilisateur ({UserFilesDirName}/{user}/blogs/{postId}/{fileName}). - [Yavsc.Blogs]
BlogApiControlleracceptemultipart/form-data(champblog+ partsfile) surPOSTetPUT /api/v1/blogspot, en plus du payload JSON existant. - [PostIt] Variable d'environnement
POSTIT_SETTINGS_JSONpour surcharger les parametres au lancement (utile en CI/test). - [Yavsc.Server] Migration EF
fileACL:CircleAuthorizationToFilegagneOwnerId+Accesset un graphe proprieetaire, base du controle d'acces fichier par cercle. - [Yavsc.Server] Migration EF
genericEstimate:Estimate.Querypasse deRdvQueryaNominativeServiceCommand?pour supporter des devis non lies a un RDV. - [Yavsc.Server] Migrations EF
NominativeServiceCommandetAddHairCutQueryLocationId(localisation de la coupe). - [CI] Integration du scan de secrets Gitleaks dans le pipeline Forgejo +
.gitleaksignore. - [Tests] Non-regressions: round-trip multipart blog (
BlogApiTests,CreateMultipartContentTestsforme + serveur),BlogAttachmentLinkTests,FileServerUrlHelpersTests,EstimateApiControllerTests, VMsEstimateList/EstimateEdition/ProviderOngoingRequests,BillingControllerTests(filtrage par utilisateur),GetOpenIdConfigurationcontre l'hote de test.
Changed
- [PostIt] Renommage
MainPage->BlogsPage(etPushMainPageAsync->PushBlogsPageAsync) pour refletter le role de la page. - [PostIt] Refacto des
SiteSettings: reorganisation des parametres, nouvelles valeurs par defaut, et indications plus claires dans lesappsettings. - [Yavsc.Api]
BillingControllerne liste plus que les codes billing de l'utilisateur authentifie (filtre parUserId), au lieu de l'ensemble des requetes prestataire. - [Yavsc.Api] Mutualisation d'un
YavscMessageSenderpartage dans l'hote API (au lieu d'une instance par controller). - [Yavsc.Org] La detection du doublon d'email a l'inscription utilise desormais le code erreur generic
DbException23505 (fournisseur-agnostique) au lieu dePostgresException, pour rester correct en test SQLite. - [PostIt]
YavscApiClienttolere les corps vides (204 No ContentsurPUT /blogspot/{id}) au lieu de lever unJsonException. - [CI] Le pipeline compile avant les tests, installe les dependances natives, et retire le
ItemGroup.Using Include=Xunitsuperflu.
Fixed
- [PostIt] Suppression d'un faux message d'erreur affiche apres un
PUT /blogspot/{id}reussi (204 traite comme succes, plus comme une reponse vide invalide). - [PostIt] Correction de la creation des liens de pieces jointes (
TryAppendAttachmentLinks) : segment proprietaire et cheminblogs/{id}/{fileName}alignes sur ce queAttachFilesecrit reellement. - [Yavsc.Blogs] Correction de l'upload / de la persistance des pieces jointes (
FileSystemHelpers+BlogApiControllermultipart). - [Tests] Stabilisation des suites: seeds billing avec metadonnees d'audit,
GetOpenIdConfiguration_returns_okcontre l'hote de test, retraits d'assertions abusives, tests SQLite verts. - [PostIt] Nettoyage de fichiers temporaires accidentels et ignore des repertoires
tmpdans le depot.
[1.0.8-rc14] - unstable
Added
- [PostIt] Ajout d'un
BillingQueryDetailsPageViewModelet de sa page associee pour afficher le detail d'une commande billing depuis l'historique. - [PostIt] Ajout d'un mode detail avec section metier (statut, date, description, motif, infos) et section technique repliable (code, client, provision, lieu, prestations).
- [PostIt] Ajout d'un badge de statut enrichi (couleur + pictogramme) sur le detail d'une commande pour visualiser l'etat en un coup d'oeil.
- [PostIt] Ajout d'un bloc d'actions rapide en tete du detail (
Retour,Ouvrir en edition) pour eviter le scroll jusqu'au bas de page. - [PostIt] Ajout d'un style monospace sur les metadonnees techniques (code billing, client, provision, lieu, prestations) pour faciliter la lecture des identifiants et valeurs brutes.
Changed
- [PostIt] Le bouton d'ouverture depuis la liste billing ouvre maintenant une page de detail dediee avant l'eventuelle edition.
- [PostIt] Amelioration UX des pages billing: badges de statut colores, actions remontees en haut de page, et typographie monospace sur les metadonnees techniques.
Fixed
- [Yavsc.Api] Correction d'un 500 sur le refresh du catalogue d'activites lorsque
Activity.DescriptionestNULLen base (nullabilite explicite + projection null-safe + gardes sur codes vides). - [Yavsc.Api] Correction des erreurs 400/500 sur les routes billing (
Rdv,Brush,MBrush) en imposantClientIddepuis l'utilisateur authentifie et en ignorant les champs server-owned lors de la validation modele. - [Yavsc.Api] Correction du
PUT /api/v1/billing/Rdv/{id}: mise a jour controlee de l'entite existante (et non remplacement brut du graphe JSON), ce qui supprime lesBadRequestparasites. - [Yavsc.Api] Correction PostgreSQL
timestamptzsur RDV: normalisation UTC deEventDatesurPOST/PUT /api/v1/billing/Rdvpour eviter l'erreurCannot write DateTime with Kind=Local. - [Yavsc.Api] Correction du flux FrontOffice accept/reject de query: sauvegarde avec contexte utilisateur et fallback d'injection pour
IBillingServiceafin d'eviter les erreurs serveur en environnement de test. - [Yavsc.Blogs] Correction des
BadRequestsurPOST/PUT /api/v1/blogspotavec payload JSON (PostIt): les proprietes de navigation/serveur (Author,Tags,Comments, audit) ne bloquent plus la validation. - [Yavsc.Org] Correction du flux MVC de creation de commentaire:
SaveChangesAsync(userId)est utilise pour renseigner les champs d'audit requis (UserCreated/UserModified). - [Yavsc.Api.Test] Stabilisation des fixtures de seed billing: remplissage des metadonnees d'audit (
UserCreated,UserModified, dates) pour eviter les echecs SQLiteNOT NULL.
[1.0.8-rc13] - unstable
Added
- [PostIt] Integration d'un selecteur de lieu RDV base sur Mapsui (carte interactive dans le formulaire
Rdv). - [PostIt] Ajout d'un marqueur de position et d'une action de recentrage sur la carte RDV.
- [PostIt] Ajout d'un service de reverse geocoding pour suggerer une adresse a partir des coordonnees carte.
- [PostIt] Cache et debounce des resolutions d'adresse RDV pour limiter les appels reseau et lisser l'UX.
- [PostIt.Tests] Nouvelles non-regressions sur le panneau d'adresse suggeree RDV et le comportement de la carte.
- [Yavsc.Abstract] Activation de
#nullable enable annotationssur les fichiers legacy avec annotations nullable. - [Yavsc.Server] Activation de
#nullable enable annotationssur les fichiers legacy avec annotations nullable.
Changed
- [PostIt] Generalisation de la barre de statut d'action (severite explicite) sur pages principales, dialogues et formulaires billing.
- [PostIt] Harmonisation des messages de statut utilisateur en francais.
- [PostIt] Renforcement des gardes de navigation dans les flux de gestion des membres de cercle.
- [PostIt] Le flux RDV conserve l'adresse saisie manuellement et propose l'adresse resolue comme suggestion explicite.
- [PostIt] Le flux de geolocalisation RDV tolere les positions proches dans le cache de suggestion d'adresse.
Fixed
- [PostIt.Desktop] Correction d'un crash au demarrage OIDC (
No authority specified) via durcissement des valeurs par defaut de configuration d'authentification. - [PostIt] Correction de la persistance des settings: l'etat runtime de statut n'est plus serialize dans le JSON utilisateur.
- [PostIt.Tests] Ajout d'un verrou de non-regression sur le premier chargement des settings.
- [PostIt] Correction du binding de la date RDV:
DatePicker.SelectedDateest aligne sur un proxyDateTimeOffset?(EventDateSelection).
[1.0.8-rc12] - unstable
Added
- [PostIt] Nouveau helper d'image
ImageHelperpour charger des bitmaps depuis les ressources et depuis le web. - [PostIt] Affichage de l'avatar XS dans la liste des performers d'activites, avec fallback visuel (initiale utilisateur).
- [PostIt.Tests] Nouveaux tests autour des URLs avatar et de la source d'autorite.
- [contrib] Ajout d'un
README.mdutilitaire pour les symboles/icones.
Changed
- [PostIt] Les avatars ne sont plus relies en string sur
Image.Source: ils sont telecharges et lies enBitmap. - [Yavsc.Api.Client]
ActivityApiClientaccepte une base d'avatar dediee et construit les URLs avatar depuis l'autorite d'identification. - [PostIt] Les clients Activites/Billing utilisent maintenant
ApiUrlen lecture dynamique: un changement via Parametres prend effet sans redemarrer l'application (apres sauvegarde et rafraichissement de la page). - [PostIt] Le header de
MainPagen'utilise plusScrollViewer; remplacement par une barre de commandes basee surWrapPanel. - [PostIt] Alignement de la navigation blogs: renommage
PushMainPageAsync->PushBlogsPageAsyncet ajustement deHomePageViewModel.
Fixed
- [PostIt.Android] Correction d'un 404 sur la page Activites au premier lancement: la configuration embarquee pointait
ApiUrlvers le host Blogs au lieu de l'API metier. - [PostIt] Correction du bouton Sauver de la page Parametres: binding vers
SaveCommandpour persister correctementApiUrl/BlogsApiUrl.
[1.0.8-rc11] - unstable
Added
nothing
Changed
- [Yavsc.Api.Test] Mise a jour de
Microsoft.EntityFrameworkCore.Sqlitevers10.0.11afin de supprimer l'alerte NU1903 liee aSQLitePCLRaw.lib.e_sqlite32.1.11. - [Yavsc.Org] Nettoyage de la configuration NuGet pour le restore: suppression du fichier local
Directory.Packages.propsau profit du fichier racine centralise. - [Yavsc.Org] Suppression de references de packages redondantes dans le projet, sans impact fonctionnel attendu.
Fixed
- [Yavsc.Api.Test] Le restore n'emet plus le warning de vulnerabilite
NU1903surSQLitePCLRaw.lib.e_sqlite3. - [Yavsc.Org] Suppression d'une vulnerabilite de severite elevee sur AutoMapper apres publication et consommation de la nouvelle version candidate de
HigginsSoft.IdentityServer8.
[1.0.8-rc10] - unstable
Added
- [PostIt] Une page d'historique des commandes billing permet maintenant d'ouvrir une commande existante.
- [PostIt] Une vue "Demandes en cours" en lecture seule est disponible pour le performer, filtrée sur les statuts actifs (Inserted, Accepted, InProgress).
- [Yavsc.Org] Nouvelles entités
CountryetPerformerCodeInputValidationpour piloter la validation du code entreprise performer par pays.
Changed
- [PostIt] La page détail billing se préremplit depuis une commande existante (Rdv, Brush, MBrush) et passe en mode mise à jour.
- [Yavsc.Org] Le formulaire
Manage/SetActivityinclut désormais le pays d'exercice (fr,en,pt) et applique la regex associée au champSIREN. - [Yavsc.Org] La vérification externe du numéro d'entreprise est conservée uniquement pour le pays
fr.
Fixed
- [PostIt] Le flux historique n'est plus limité à une simple liste: l'action d'ouverture charge la commande cible puis navigue vers la page détail.
- [Yavsc.Org] Le champ
SIRENn'est plus validé avec une règle unique indépendante du pays d'exercice.
[1.0.8-rc9] - unstable
Added
nothing
Changed
masquage non-owner côté backend de l'ACL du billet
Fixed
On a maintenant le comportement attendu bout en bout:
ACL chargée depuis le BlogPostDto noms de cercles affichés dans le dialogue ACL côté PostIt
[1.0.8-rc8] - unstable
Added
nothing
Changed
nothing
Fixed
The PostIt publish toggle button
[1.0.8-rc7] - unstable
Added
- [PostIt] The search pattern now persists
Changed
- The blog spot path is now
/api/v1/blogspot(yet in last release)
Fixed
- [Yavsc.Org] (Ticket #45) La forme de l'email de l'utilisateur est maintenant validée avant l'envoi du formulaire d'enregistrement
[1.0.8-rc6] - unstable
Added
- a code cleanup,
- a first Xamarin.UITest is successful, but disabled, because breaking the actual CI process,
- Android app starts, the login process succeeds
Changed
L'identifiant de l'application client Android a changé, il passe en minuscules :
fr.pschneider.postit
Fixed
a bug posting and retrieving ACL from the backend, the ACL now comes along with the article, [TODO][PostIt] keep ACL along with the article
1.0.8-rc1 - unstable
Added
-
BlogAclApiTests.PostCircleAuthorization_returns_201_when_payload_mirrors_PostIt_shape_against_existing_circle_named_test- test de non-régression qui épingle la forme exacte du payload
que PostIt envoie à
POST /api/v1/blogacl(un objetPostAccessControlRulePayloadavecCircleIdetBlogPostId). C'est le verrou côté test du fix applicatif PostIt + serveur.
BlogAclApiTests.PostCircleAuthorization_never_returns_500: une[Theory]couvrant quatre shapes de payload ({ circleId }, corps vide,{ blogPostId }seul,{ circleId, blogPostId: 0 }) qui doivent tous retourner un statut différent de 500. Toute réintroduction d'un chemin 500 dans le futur fera rougir ce test.BlogAclApiTests.PostCircleAuthorization_dosent_return_500et..._dosent_return_500_on_success: entry points[Fact]qui appellent la[Theory]ci-dessus avec un payload spécifique chacun, pour pouvoir filtrer en isolation depuis la ligne de commande ou le CI.- Règle « Pas de
objectdans le code source applicatif » ajoutée àCONTRIBUTING.md: types de retour, paramètres, champs, propriétés, variables locales doivent être typés statiquement.dynamicest interdit pour les mêmes raisons.
Changed
BlogAclApiController.CheckOwnerdevientCheckOwnerAsyncet utiliseFirstOrDefaultAsyncau lieu deFirst, supprimant l'appel LINQ synchrone sur le fil de la requête et retournantfalsesur cercle manquant (le contrôleur mappe déjà cela versChallengeResult).BlogsWebServerFixtureseedalice, sonCircleet sonBlogPostune seule fois au démarrage du host, sur laSqliteConnectionpartagée (Cache=Shared). Le précédentEnsureDeletedau début de chaque test fermait la connexion statique et détruisait le store:memory:pour tous les autresDbContext; il est retiré au profit d'unEnsureCreatedidempotent.
Fixed
POST /api/v1/blogaclne retourne plus 500 sur les payloads dontBlogPostIdest absent ou à zéro. Le contrôleur rejetteBlogPostId <= 0avec400 BadRequestavant que la requête n'atteigneSaveChangesAsync. L'incident de prod du 2026-08-21 sur mercure (PostIt envoyant seulementcircleId, le serveur voyantBlogPostId = default(long) = 0et EF Core levantInvalidOperationExceptionsur l'INSERT) n'est plus atteignable.- PostIt
PostAclDialogViewModel.AddAsyncenvoie désormais le payload explicitePostAccessControlRulePayload { CircleId, BlogPostId }au lieu de l'ancienCircleAuthorization { CircleId }. Le DTO serveurPostAccessControlRulePayloadest introduit dansYavsc.Abstractpour porter le contrat.
1.0.7 - preview
Added
- Per-post ACL in PostIt: a new “Manage ACL” page, opened from the ACL
button on a selected post, lets the post author grant or revoke
grants for individuals or circles. The server scopes each grant
operation to
caller == post.AuthorIdand returns404(not403) for posts the caller does not own, so the existence of another user's post is not leaked. - Circle membership API + UI: three new REST endpoints under
/api/circle/{id}/members(GETlist,POSTadd,DELETEremove) and a new “Members” column on the My Circles page with an “Add a member” button that opens a search modal. The search modal reusesIUserDirectory(introduced by theIContactServicesplit in this same release) — exactly the use case the abstraction was carved out for. - Publish toggle for blog posts: a new
PUT /api/BlogApi/{id}/publishendpoint, and aPublishedcheckbox in the post toolbar that toggles aBlogSpotPublicationrow for the post. The publish signal flows through the pre-existingPermissionHandler.IsPublicpath, so no new column was needed and the server-side authorisation logic is unchanged. UserSearchApiControllerinYavsc.Blogs:GET /api/user-search?q=...&e=...&take=.... Any-authenticated- caller endpoint that exposes the user's email under a closed- community assumption (documented in the controller's XML doc). Wired to the PostIt Desktop address book so the user search modal picks it up.IYavscApiClientabstraction inYavsc.Api.Client. The transport for the blog/circle/blog-acl/user-search clients is now accessed through this interface, soPostIt.Testscan stub the HTTP layer without spinning up a real WebAPI host.- Forgejo Actions release workflow: a
.forgejo/workflows/release.ymlpipeline that builds and publishes a release with the PostIt APK on tag push. Written in pure bash (the runner image has no Node), usesjqfor JSON body construction and response parsing, uses the runner-providedGITHUB_TOKEN(no repo-level secret needed), validates the CHANGELOG section heading before allowing the tag to ship. make release V=<version>target: creates arelease/<V>branch frommain, bumps the<Version>property in every.csprojviadotnet-gitversion /updateprojectfiles, commits the bump on the release branch, and pushes toorigin. Fails fast if the working tree is dirty or ifHEADis not onmain.- Forgejo status badges in the README.
Changed
- The new Publish toggle replaces the “Visibility enum” approach
originally drafted in this branch: the existing
BlogSpotPublicationtable already carried enough information to expose a publish switch, so no schema change was needed. The originalfeat(blog): add Visibility { Private, Public }commit and its EF migration were reverted in favour of the endpoint-only toggle. BlogPostDTO andIBlogPostmoved fromPostIt.ModelstoYavsc.Abstract.Blogspot, the shared assembly where the server-side entity and the wire DTO both live. RenamedYavsc.Blogspot.BlogPosttoBlogPostDtoto make the wire/entity distinction explicit.BlogAclApiControllerandCircleApiControllermoved fromYavsc.Api(not yet enabled in production) toYavsc.Blogs, where they belong next to theBlogSpotServicethey depend on.IContactServicesplit fromIUserDirectory: the two interfaces previously conflated the local address-book access (mobile-only, viaContacts.Default) and the Yavsc user-search access (Desktop-only, via/api/user-search) behind a single facade. The split restores theContactDto.Emailsmulti-value shape that was being silently flattened to a single string before.- CI: the Forgejo Actions build now compiles
.csprojprojects directly inside the runner container (which ships the .NET SDK + Android workload), instead of relying on a separate Docker build step. Node-based third-party actions were replaced with bash + curljq. The validate-release job parses the CHANGELOG section heading to derive the channel (stable/preview/unstable) rather than the patch-version parity alone.
Fixed
CircleApiControllerused to read the caller's user id viaFindFirstValue(ClaimTypes.NameIdentifier), which does not match when JWT Bearer middleware hasMapInboundClaims = false. Switched toUser.GetUserId()(triessubfirst, thenClaimTypes.NameIdentifier, thennameid). This was a latent bug visible in tests but easy to ship to production if a host ever disabled the remap.CircleApiControllerandBlogAclApiControllerreads and writes were not always scoped to the caller's own data. Tightened the authorisation checks: cross-user reads now return404, not the raw record.validate-releaseCHANGELOG channel check used to parse the patch-version parity only, which disagreed with the channel suffix in the section heading (e.g.## [1.0.7] - previewwould be flagged asstablefrom the parity alone). The job now inspects the heading line and trusts the suffix when present..forgejo/workflows/release.yml: the asset-upload URL now carries the asset name as a query-string parameter instead of acurlpositional argument. The previous shape triggered Forgejo's “Missingnameparameter” 400 in some cases.
Removed
- The
## [Unreleased]block has been moved into this section. - The abandoned
Visibility { Private, Public }enum and its EF migration, reverted in this release. The publish toggle covers the same user-visible switch without a schema change.
1.0.6 - stable
Added
- Self-hosted Forgejo Actions runner now drives the CI build for the
yavsc repository, using the
pazof/yavsc-build-env:debian12-dotnet10-android36-v2image pulled from Docker Hub. Workflow runs end-to-end: clone, restore, build, test, with NuGet.config picking up theisn.pschneider.frfeed. - The build-env image now ships
jq(Debian package, ≥ 1.7), so the release workflow can build JSON bodies and parse API responses without a hand-rolledsed-based extractor that was matching the wrongidfield on minified responses.
Changed
- CI workflow
.forgejo/workflows/buildAndTest.ymlno longer relies onactions/checkout(the runner image has no Node); clones yavsc viagit, fetches the ref under test, and initializes submodules over HTTPS.
Fixed
DockerfileandDockerfile.backendno longer carry a redundantdotnet nuget add sourcestep that conflicted with the GitHub Actions APK build (--allow-insecure-connectionson an HTTPS endpoint, exit 1).NuGet.configat the repo root supplies theisn.pschneider.frfeed for every restore, including inside Docker..forgejo/workflows/release.yml: PATCH on/releases/{id}no longer 404s on existing releases. The previoussed-basedjson_fieldmatched the lastidon the line (the author's), so it tried to PATCH/releases/1(the first user of the instance) instead of the actual release id. Switched tojqfor both body construction and field extraction.