634 lines
36 KiB
Markdown
634 lines
36 KiB
Markdown
# Changelog
|
|
|
|
## [1.0.8-rc18] - unstable
|
|
|
|
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`), revendication `name`
|
|
enfin présente dans les access tokens (branchement du `ProfileService`),
|
|
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 =
|
|
RequestVersionOrLower` sur le `HttpClient` partagé de `YavscApiClient`,
|
|
avec repli h2/h1.1 où QUIC n'est pas disponible (WASM fetch, Android/
|
|
desktop sans libmsquic).
|
|
* [Tests] `MyFilesPageHeadlessTests` : monte `MyFilesPage` via
|
|
`NavigationPage` + `Window.Show()` et vérifie que chaque bouton de
|
|
ligne (Télécharger / Supprimer) a sa `Command` lié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 porte `name`=login et
|
|
que `GetUserName()` résout vers ce login.
|
|
* [Tests] `FileSystemApiTests.Get_fs_lists_files_stored_under_the_user_login` :
|
|
découple `sub` et login, téléverse sous le login, et asserte que
|
|
`GET /api/v1/fs` retourne le fichier (et que le répertoire nommé d'après
|
|
le `sub` n'existe pas).
|
|
|
|
### Changed
|
|
|
|
* [Yavsc.Org] Branchement du `ProfileService` custom
|
|
(`AddProfileService<ProfileService>()` après
|
|
`AddAspNetIdentity<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 les `UserClaims` des API resources.
|
|
`name` n'en faisait jamais partie, donc tout access token était sans
|
|
`name` et `GetUserName()` résolvait à `null` sur les hosts ressources
|
|
(Blogs/Api) — cause du 500 sur l'upload MyFiles et du
|
|
`User.Identity.Name` injoignable. Le service émet désormais
|
|
`name`=`user.UserName`, `email` et les rôles pour tout client dont
|
|
les `AllowedScopes` contiennent `profile`, indépendamment du caller.
|
|
* [Yavsc.Server] `ServiceExtensions` : `NameClaimType =
|
|
JwtClaimTypes.Name`, `MapInboundClaims = false` (conserver les noms
|
|
courts de claims tels qu'émis).
|
|
* [Yavsc.Blogs] `FileSystemHelpers.EnsureDestinationDirectory` utilise
|
|
`GetUserName()` (claim `name`) au lieu de `User.Identity.Name` pour
|
|
la racine de stockage par utilisateur.
|
|
* [Tests] `WebServerFixture` : `AccessTokenType = 0` (Jwt dans IS8 ;
|
|
1 = Reference, l'inverse de Duende) ; `openid`+`profile` sur le client
|
|
de test ; réensemencement des identity resources openid/profile dans
|
|
`ReseedAuthTestData` (un `ResetAndMigrateDatabase` vide le store
|
|
in-memory partagé et les laissait absentes → `invalid_scope`).
|
|
* [Tests] `TestTokenIssuer.Issue` gagne un paramètre `name` optionnel
|
|
(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 statiques
|
|
`BillingService`/`Config` (race parallèle pré-existante).
|
|
|
|
### Fixed
|
|
|
|
* [Yavsc.Blogs] La liste `GET /api/v1/fs` cherchait 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 utilisent
|
|
`user.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. `GetDir` résout désormais
|
|
l'utilisateur en base et liste sous `user.UserName`.
|
|
`UploadedFile.OwnerId` reste `sub`, donc `EnrichWithFileIds`
|
|
interpole toujours par `uid`.
|
|
* [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 `BillingQueryDetailsPage` et
|
|
`EstimateEditionPage`). Le binding `$parent[vm:XxxViewModel].Cmd`
|
|
cherchait un ancêtre CONTRÔLE de type `XxxViewModel` — un viewmodel,
|
|
pas un contrôle — donc résolvait à `null` et le `Button` restait
|
|
désactivé (grisé) et inerte au clic. Corrigé en
|
|
`$parent[ContentPage].((vm:XxxViewModel)DataContext).Cmd` (syntaxe
|
|
déjà en vigueur dans `CirclesPage` / `EstimateListPage`).
|
|
|
|
## [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 sur `EstimateApiClient` et `FrontOfficeApiClient`.
|
|
* [Yavsc.Server] Modèles `EstimateAttachedFile`, `QueryAttachedFile`,
|
|
`BlogAttachedFile`, `AttachFileRequest` ; migration EF Core
|
|
`UserFileAttachments`.
|
|
* [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`), et
|
|
`README.nginx.md`.
|
|
* [Tests] Projet `Yavsc.Server.Tests` : tests du service
|
|
`BlogSpotService.Details` + `ServerServicesFixture` (SQLite `:memory:`
|
|
par défaut, Npgsql opt-in via `YAVSC_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 par `addr: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'environnement
|
|
`YAVSC_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 endpoint `GetBlogspot` retourne
|
|
`IEnumerable<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 —
|
|
`IsPublished` vivait sur `BlogPost` / `BlogPostDto` mais pas sur
|
|
`IBlogPost`. PostIt lisait donc `IsPublished == false` pour tout billet,
|
|
y compris publiés (https://yavsc.pschneider.fr/BlogSpot/Details/13).
|
|
Corrigé en déclarant `IsPublished` sur `IBlogPost`.
|
|
* [Yavsc.Org] Accès au Swagger UI : les actions MVC scaffoldées de
|
|
`CommentsController` (Index/Details/…) atterrissaient sur la même route
|
|
`POST api/v1/blogcomments` que l'action d'API `Post`, provoquant une
|
|
`SwaggerGeneratorException` (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/accept` et `.../reject` :
|
|
autorisation selon le rôle (fournisseur/client/admin), signature optionnelle
|
|
persistée sur l'estimate avec horodatage `ProviderValidationDate` /
|
|
`ClientValidationDate` selon le côté signataire.
|
|
* [Yavsc.Api] `QueryStatus.Accepted` éclaté en `ProAccepted` / `ClientAccepted`
|
|
pour distinguer l'acceptation de chaque partie.
|
|
* [Yavsc.Api] Endpoints de devis `GET /api/v1/front/query/{id}/estimate.tex` et
|
|
`estimate.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.cs`
|
|
câble `AddControllersWithViews` + `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] `DownloadAsync` sur 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 helper `StorageProvider` d'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] `SignatureType` déplacé dans `Yavsc.Abstract.Billing`.
|
|
* [CLI] Option `-c configuration-file.json` au 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 si `lualatex` est 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] `GetOngoingEstimatesAsProvider` filtre désormais sur
|
|
`ProviderValidationDate` : un devis signé par le fournisseur quitte sa liste
|
|
« en attente ».
|
|
* [Yavsc.Api] La génération PDF compile via le `lualatex` systè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`/`.log` nettoyés
|
|
afin que seul le `.pdf` persiste.
|
|
|
|
### Fixed
|
|
|
|
* [Yavsc.Api] `Emergency stop` à la génération PDF : `lualatex` sans 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/stdin` comme 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, pas
|
|
`bera` ni `luaotfload` (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 relatif
|
|
`Site.Bills` (`"bills"`) était imbriqué quand il servait à la fois de
|
|
`-output-directory` et de répertoire de travail ; résolu en chemin absolu.
|
|
* [Yavsc.Api] NRE dans `RenderViewToString` (RouteData / `ViewData.Model`
|
|
nuls) : reconstruit sur le `ControllerContext` du contrôleur ; `IViewEngine`
|
|
résolu via `IRazorViewEngine` (.NET 10 n'enregistre pas de `IViewEngine`
|
|
unique).
|
|
* [Yavsc.Api] `Layout = "null"` (chaîne) dans les modèles TeX cherchait
|
|
`null.cshtml` ; corrigé en `Layout = null` (null C#).
|
|
* [Yavsc.Api] `texi2pdf` (outil Texinfo, inadapté au LaTeX) remplacé par
|
|
`lualatex`.
|
|
* [Yavsc.Api] Les diagnostics lualatex étaient perdus (écrits dans le `.log`
|
|
qu'on supprimait) ; stdout/stderr sont désormais capturés dans le message
|
|
d'erreur, et le `.log` est 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-data` lors du `Save`, ajoute un lien Markdown par piece jointe a l'article, puis re-PUT le billet. Une collection `DraftAttachments` porte les fichiers en cours d'edition.
|
|
* [PostIt] Apercu Markdown dans l'editeur de blogs (integration `MarkdownViewer.Core`) avec bascule edition/preview sur `BlogsPage`.
|
|
* [PostIt] Gestion des devis: page de liste `EstimateListPage` (vues client et prestataire), page d'edition `EstimateEditionPage` avec 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/asclient` et `GET /api/v1/estimate/asprovider` pour lister les devis en cours selon le role.
|
|
* [Yavsc.Api] Endpoint `GET /api/v1/billing/provider/ongoing` et `POST /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] `FileServerUrlHelpers` pour deriver les URLs publiques des fichiers utilisateur depuis l'autorite OIDC (alignement sur `UserFilesPath`).
|
|
* [Yavsc.Server] `BlogSpotService.AttachFiles` : ecrit les pieces jointes sous la racine des fichiers utilisateur (`{UserFilesDirName}/{user}/blogs/{postId}/{fileName}`).
|
|
* [Yavsc.Blogs] `BlogApiController` accepte `multipart/form-data` (champ `blog` + parts `file`) sur `POST` et `PUT /api/v1/blogspot`, en plus du payload JSON existant.
|
|
* [PostIt] Variable d'environnement `POSTIT_SETTINGS_JSON` pour surcharger les parametres au lancement (utile en CI/test).
|
|
* [Yavsc.Server] Migration EF `fileACL`: `CircleAuthorizationToFile` gagne `OwnerId` + `Access` et un graphe proprieetaire, base du controle d'acces fichier par cercle.
|
|
* [Yavsc.Server] Migration EF `genericEstimate`: `Estimate.Query` passe de `RdvQuery` a `NominativeServiceCommand?` pour supporter des devis non lies a un RDV.
|
|
* [Yavsc.Server] Migrations EF `NominativeServiceCommand` et `AddHairCutQueryLocationId` (localisation de la coupe).
|
|
* [CI] Integration du scan de secrets Gitleaks dans le pipeline Forgejo + `.gitleaksignore`.
|
|
* [Tests] Non-regressions: round-trip multipart blog (`BlogApiTests`, `CreateMultipartContentTests` forme + serveur), `BlogAttachmentLinkTests`, `FileServerUrlHelpersTests`, `EstimateApiControllerTests`, VMs `EstimateList`/`EstimateEdition`/`ProviderOngoingRequests`, `BillingControllerTests` (filtrage par utilisateur), `GetOpenIdConfiguration` contre l'hote de test.
|
|
|
|
### Changed
|
|
|
|
* [PostIt] Renommage `MainPage` -> `BlogsPage` (et `PushMainPageAsync` -> `PushBlogsPageAsync`) pour refletter le role de la page.
|
|
* [PostIt] Refacto des `SiteSettings` : reorganisation des parametres, nouvelles valeurs par defaut, et indications plus claires dans les `appsettings`.
|
|
* [Yavsc.Api] `BillingController` ne liste plus que les codes billing de l'utilisateur authentifie (filtre par `UserId`), au lieu de l'ensemble des requetes prestataire.
|
|
* [Yavsc.Api] Mutualisation d'un `YavscMessageSender` partage 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 `DbException` 23505 (fournisseur-agnostique) au lieu de `PostgresException`, pour rester correct en test SQLite.
|
|
* [PostIt] `YavscApiClient` tolere les corps vides (`204 No Content` sur `PUT /blogspot/{id}`) au lieu de lever un `JsonException`.
|
|
* [CI] Le pipeline compile avant les tests, installe les dependances natives, et retire le `ItemGroup.Using Include=Xunit` superflu.
|
|
|
|
### 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 chemin `blogs/{id}/{fileName}` alignes sur ce que `AttachFiles` ecrit reellement.
|
|
* [Yavsc.Blogs] Correction de l'upload / de la persistance des pieces jointes (`FileSystemHelpers` + `BlogApiController` multipart).
|
|
* [Tests] Stabilisation des suites: seeds billing avec metadonnees d'audit, `GetOpenIdConfiguration_returns_ok` contre l'hote de test, retraits d'assertions abusives, tests SQLite verts.
|
|
* [PostIt] Nettoyage de fichiers temporaires accidentels et ignore des repertoires `tmp` dans le depot.
|
|
|
|
## [1.0.8-rc14] - unstable
|
|
|
|
### Added
|
|
|
|
* [PostIt] Ajout d'un `BillingQueryDetailsPageViewModel` et 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.Description` est `NULL` en 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 imposant `ClientId` depuis 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 les `BadRequest` parasites.
|
|
* [Yavsc.Api] Correction PostgreSQL `timestamptz` sur RDV: normalisation UTC de `EventDate` sur `POST/PUT /api/v1/billing/Rdv` pour eviter l'erreur `Cannot write DateTime with Kind=Local`.
|
|
* [Yavsc.Api] Correction du flux FrontOffice accept/reject de query: sauvegarde avec contexte utilisateur et fallback d'injection pour `IBillingService` afin d'eviter les erreurs serveur en environnement de test.
|
|
* [Yavsc.Blogs] Correction des `BadRequest` sur `POST/PUT /api/v1/blogspot` avec 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 SQLite `NOT 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 annotations` sur les fichiers legacy avec annotations nullable.
|
|
* [Yavsc.Server] Activation de `#nullable enable annotations` sur 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.SelectedDate` est aligne sur un proxy `DateTimeOffset?` (`EventDateSelection`).
|
|
|
|
## [1.0.8-rc12] - unstable
|
|
|
|
### Added
|
|
|
|
* [PostIt] Nouveau helper d'image `ImageHelper` pour 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.md` utilitaire pour les symboles/icones.
|
|
|
|
### Changed
|
|
|
|
* [PostIt] Les avatars ne sont plus relies en string sur `Image.Source`: ils sont telecharges et lies en `Bitmap`.
|
|
* [Yavsc.Api.Client] `ActivityApiClient` accepte une base d'avatar dediee et construit les URLs avatar depuis l'autorite d'identification.
|
|
* [PostIt] Les clients Activites/Billing utilisent maintenant `ApiUrl` en lecture dynamique: un changement via Parametres prend effet sans redemarrer l'application (apres sauvegarde et rafraichissement de la page).
|
|
* [PostIt] Le header de `MainPage` n'utilise plus `ScrollViewer`; remplacement par une barre de commandes basee sur `WrapPanel`.
|
|
* [PostIt] Alignement de la navigation blogs: renommage `PushMainPageAsync` -> `PushBlogsPageAsync` et ajustement de `HomePageViewModel`.
|
|
|
|
### Fixed
|
|
|
|
* [PostIt.Android] Correction d'un 404 sur la page Activites au premier lancement: la configuration embarquee pointait `ApiUrl` vers le host Blogs au lieu de l'API metier.
|
|
* [PostIt] Correction du bouton Sauver de la page Parametres: binding vers `SaveCommand` pour persister correctement `ApiUrl`/`BlogsApiUrl`.
|
|
|
|
## [1.0.8-rc11] - unstable
|
|
|
|
### Added
|
|
|
|
nothing
|
|
|
|
### Changed
|
|
|
|
* [Yavsc.Api.Test] Mise a jour de `Microsoft.EntityFrameworkCore.Sqlite` vers `10.0.11` afin de supprimer l'alerte NU1903 liee a `SQLitePCLRaw.lib.e_sqlite3` 2.1.11.
|
|
* [Yavsc.Org] Nettoyage de la configuration NuGet pour le restore: suppression du fichier local `Directory.Packages.props` au 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 `NU1903` sur `SQLitePCLRaw.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 `Country` et `PerformerCodeInputValidation` pour 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/SetActivity` inclut désormais le pays d'exercice (`fr`, `en`, `pt`) et applique la regex associée au champ `SIREN`.
|
|
* [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 `SIREN` n'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 objet
|
|
`PostAccessControlRulePayload` avec `CircleId` et `BlogPostId`).
|
|
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_500` et
|
|
`..._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 `object` dans le code source applicatif » ajoutée
|
|
à `CONTRIBUTING.md` : types de retour, paramètres, champs,
|
|
propriétés, variables locales doivent être typés statiquement.
|
|
`dynamic` est interdit pour les mêmes raisons.
|
|
|
|
### Changed
|
|
- `BlogAclApiController.CheckOwner` devient `CheckOwnerAsync` et
|
|
utilise `FirstOrDefaultAsync` au lieu de `First`, supprimant
|
|
l'appel LINQ synchrone sur le fil de la requête et retournant
|
|
`false` sur cercle manquant (le contrôleur mappe déjà cela vers
|
|
`ChallengeResult`).
|
|
- `BlogsWebServerFixture` seed `alice`, son `Circle` et son
|
|
`BlogPost` une seule fois au démarrage du host, sur la
|
|
`SqliteConnection` partagée (`Cache=Shared`). Le précédent
|
|
`EnsureDeleted` au début de chaque test fermait la connexion
|
|
statique et détruisait le store `:memory:` pour tous les autres
|
|
`DbContext` ; il est retiré au profit d'un `EnsureCreated`
|
|
idempotent.
|
|
|
|
### Fixed
|
|
- `POST /api/v1/blogacl` ne retourne plus 500 sur les payloads
|
|
dont `BlogPostId` est absent ou à zéro. Le contrôleur rejette
|
|
`BlogPostId <= 0` avec `400 BadRequest` avant que la requête
|
|
n'atteigne `SaveChangesAsync`. L'incident de prod du 2026-08-21
|
|
sur mercure (PostIt envoyant seulement `circleId`, le serveur
|
|
voyant `BlogPostId = default(long) = 0` et EF Core levant
|
|
`InvalidOperationException` sur l'INSERT) n'est plus atteignable.
|
|
- PostIt `PostAclDialogViewModel.AddAsync` envoie désormais le
|
|
payload explicite `PostAccessControlRulePayload { CircleId,
|
|
BlogPostId }` au lieu de l'ancien `CircleAuthorization {
|
|
CircleId }`. Le DTO serveur `PostAccessControlRulePayload` est
|
|
introduit dans `Yavsc.Abstract` pour 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.AuthorId` and returns `404` (not `403`)
|
|
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` (`GET` list, `POST` add, `DELETE`
|
|
remove) and a new “Members” column on the *My Circles* page with an
|
|
“Add a member” button that opens a search modal. The search modal
|
|
reuses `IUserDirectory` (introduced by the `IContactService` split
|
|
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}/publish`
|
|
endpoint, and a `Published` checkbox in the post toolbar that
|
|
toggles a `BlogSpotPublication` row for the post. The publish
|
|
signal flows through the pre-existing `PermissionHandler.IsPublic`
|
|
path, so no new column was needed and the server-side authorisation
|
|
logic is unchanged.
|
|
- `UserSearchApiController` in `Yavsc.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.
|
|
- `IYavscApiClient` abstraction in `Yavsc.Api.Client`. The transport
|
|
for the blog/circle/blog-acl/user-search clients is now accessed
|
|
through this interface, so `PostIt.Tests` can stub the HTTP layer
|
|
without spinning up a real WebAPI host.
|
|
- Forgejo Actions release workflow: a `.forgejo/workflows/release.yml`
|
|
pipeline that builds and publishes a release with the PostIt APK
|
|
on tag push. Written in pure bash (the runner image has no Node),
|
|
uses `jq` for JSON body construction and response parsing, uses the
|
|
runner-provided `GITHUB_TOKEN` (no repo-level secret needed),
|
|
validates the CHANGELOG section heading before allowing the tag
|
|
to ship.
|
|
- `make release V=<version>` target: creates a `release/<V>` branch
|
|
from `main`, bumps the `<Version>` property in every `.csproj` via
|
|
`dotnet-gitversion /updateprojectfiles`, commits the bump on the
|
|
release branch, and pushes to `origin`. Fails fast if the working
|
|
tree is dirty or if `HEAD` is not on `main`.
|
|
- Forgejo status badges in the README.
|
|
|
|
### Changed
|
|
- The new Publish toggle replaces the “Visibility enum” approach
|
|
originally drafted in this branch: the existing `BlogSpotPublication`
|
|
table already carried enough information to expose a publish
|
|
switch, so no schema change was needed. The original `feat(blog):
|
|
add Visibility { Private, Public }` commit and its EF migration
|
|
were reverted in favour of the endpoint-only toggle.
|
|
- `BlogPost` DTO and `IBlogPost` moved from `PostIt.Models` to
|
|
`Yavsc.Abstract.Blogspot`, the shared assembly where the server-side
|
|
entity and the wire DTO both live. Renamed `Yavsc.Blogspot.BlogPost`
|
|
to `BlogPostDto` to make the wire/entity distinction explicit.
|
|
- `BlogAclApiController` and `CircleApiController` moved from
|
|
`Yavsc.Api` (not yet enabled in production) to `Yavsc.Blogs`, where
|
|
they belong next to the `BlogSpotService` they depend on.
|
|
- `IContactService` split from `IUserDirectory`: the two interfaces
|
|
previously conflated the local address-book access (mobile-only,
|
|
via `Contacts.Default`) and the Yavsc user-search access
|
|
(Desktop-only, via `/api/user-search`) behind a single facade. The
|
|
split restores the `ContactDto.Emails` multi-value shape that was
|
|
being silently flattened to a single string before.
|
|
- CI: the Forgejo Actions build now compiles `.csproj` projects
|
|
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 + curl
|
|
+ `jq`. The validate-release job parses the CHANGELOG section
|
|
heading to derive the channel (`stable` / `preview` / `unstable`)
|
|
rather than the patch-version parity alone.
|
|
|
|
### Fixed
|
|
- `CircleApiController` used to read the caller's user id via
|
|
`FindFirstValue(ClaimTypes.NameIdentifier)`, which does not match
|
|
when JWT Bearer middleware has `MapInboundClaims = false`. Switched
|
|
to `User.GetUserId()` (tries `sub` first, then
|
|
`ClaimTypes.NameIdentifier`, then `nameid`). This was a latent
|
|
bug visible in tests but easy to ship to production if a host
|
|
ever disabled the remap.
|
|
- `CircleApiController` and `BlogAclApiController` reads and writes
|
|
were not always scoped to the caller's own data. Tightened the
|
|
authorisation checks: cross-user reads now return `404`, not the
|
|
raw record.
|
|
- `validate-release` CHANGELOG 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] - preview`
|
|
would be flagged as `stable` from 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 a `curl`
|
|
positional argument. The previous shape triggered Forgejo's
|
|
“Missing `name` parameter” 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.
|
|
|
|
[Unreleased]: https://forgejo.pschneider.fr/notazof/yavsc/compare/HEAD
|
|
[1.0.8-rc16]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.8-rc15...1.0.8-rc16
|
|
[1.0.8-rc17]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.8-rc16...1.0.8-rc17
|
|
[1.0.8-rc18]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.8-rc17...1.0.8-rc18
|
|
[1.0.8-rc15]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.8-rc14...1.0.8-rc15
|
|
[1.0.8-rc1]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.7...1.0.8-rc1
|
|
[1.0.7]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.6...1.0.7
|
|
[1.0.6]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.5...1.0.6
|
|
|
|
## [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-v2` image pulled
|
|
from Docker Hub. Workflow runs end-to-end: clone, restore, build,
|
|
test, with NuGet.config picking up the `isn.pschneider.fr` feed.
|
|
- 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-rolled `sed`-based extractor that was matching the
|
|
wrong `id` field on minified responses.
|
|
|
|
### Changed
|
|
- CI workflow `.forgejo/workflows/buildAndTest.yml` no longer relies on
|
|
`actions/checkout` (the runner image has no Node); clones yavsc via
|
|
`git`, fetches the ref under test, and initializes submodules over
|
|
HTTPS.
|
|
|
|
### Fixed
|
|
- `Dockerfile` and `Dockerfile.backend` no longer carry a redundant
|
|
`dotnet nuget add source` step that conflicted with the GitHub
|
|
Actions APK build (`--allow-insecure-connections` on an HTTPS
|
|
endpoint, exit 1). `NuGet.config` at the repo root supplies the
|
|
`isn.pschneider.fr` feed for every restore, including inside Docker.
|
|
- `.forgejo/workflows/release.yml`: PATCH on `/releases/{id}` no longer
|
|
404s on existing releases. The previous `sed`-based `json_field`
|
|
matched the last `id` on 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 to `jq` for both body construction and
|
|
field extraction.
|
|
|
|
[1.0.6]: https://forgejo.pschneider.fr/notazof/yavsc/compare/1.0.5...1.0.6
|