yavsc/CHANGELOG.md
Paul Schneider 1ec7c7a75a
All checks were successful
Forgejo Release / release (push) Successful in 4m39s
postit: add billing query details page and refresh rc14 changelog
2026-09-06 20:31:42 +01:00

19 KiB

Changelog

[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.

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.