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>
43 lines
1.6 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|