Thomas Fransolet 4e17c572ba Nom d'app, drapeau QR et liens stores par application
ApplicationInstance porte désormais AppName (traductions, jsonb),
IsQRCodeEnabled (défaut true) et les liens App Store / Play Store.
Une ligne existe par (instance, type d'app) : chaque réglage vaut
donc séparément pour le mobile et pour le web.

Les liens stores ne sont modifiables que par un SuperAdmin — c'est
Unov qui publie les apps —, contrôlé côté API et pas seulement masqué
dans l'UI.

La liste anonyme des apps expose le slug web et le nom de l'instance :
la page /download de visitapp-web n'a que l'instanceId d'un QR imprimé.

Réserve les slugs download, demo et api : un segment statique de
visitapp-web l'emporte sur [slug], l'instance serait inaccessible.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 11:42:07 +02:00

43 lines
1.6 KiB
C#

using ManagerService.Data;
using System.Linq;
using System.Text.RegularExpressions;
namespace ManagerService.Helpers
{
public static class SlugHelper
{
/// <summary>
/// Premiers segments d'URL déjà pris par des routes de visitapp-web : un segment
/// statique l'emporte sur [slug], l'instance serait donc inaccessible.
/// </summary>
private static readonly string[] ReservedSlugs = { "download", "demo", "api" };
public static bool IsTaken(MyInfoMateDbContext db, string slug) =>
ReservedSlugs.Contains(slug) || db.Instances.Any(i => i.WebSlug == slug);
/// <summary>
/// Generate a URL-safe slug from a name, appending "-1", "-2", etc. until unique among Instances.WebSlug.
/// </summary>
public static string GenerateUniqueSlug(MyInfoMateDbContext db, string name)
{
var slug = name.ToLowerInvariant();
slug = Regex.Replace(slug, @"[àáâãäå]", "a");
slug = Regex.Replace(slug, @"[èéêë]", "e");
slug = Regex.Replace(slug, @"[ìíîï]", "i");
slug = Regex.Replace(slug, @"[òóôõö]", "o");
slug = Regex.Replace(slug, @"[ùúûü]", "u");
slug = Regex.Replace(slug, @"[ç]", "c");
slug = Regex.Replace(slug, @"[ñ]", "n");
slug = Regex.Replace(slug, @"[^a-z0-9\s-]", "");
slug = Regex.Replace(slug, @"[\s-]+", "-").Trim('-');
var baseSlug = slug;
var counter = 1;
while (IsTaken(db, slug))
slug = $"{baseSlug}-{counter++}";
return slug;
}
}
}