using System;
using System.Collections.Generic;
using Ban.Sdaid.Notation.Documents;
namespace Ban.Sdaid.Icd.Domain.Access
{
/// <summary>Пользователь Сервиса — учётная запись, через которую выполняется вход и определяются полномочия.</summary>
[DomainEntity]
public class User
{
/// <summary>Идентификатор пользователя.</summary>
public Guid Id { get; init; }
/// <summary>ФИО пользователя (для отображения).</summary>
public string Name { get; init; }
/// <summary>Логин (уникален).</summary>
public string Login { get; init; }
/// <summary>
/// Пароль. На этапе разработки хранится открытым текстом (сид-данные);
/// до продакшна заменяется на хеш + соль (см. ADR-SRV-006, «отложено»).
/// </summary>
public string Password { get; init; }
/// <summary>Членство в группах полномочий — через него пользователь получает права.</summary>
[Relation(Kind = RelationKind.Composition)]
public IReadOnlyList<UserGroup> Groups { get; init; }
/// <summary>Активные (выписанные и не отозванные) токены пользователя.</summary>
[Relation(Kind = RelationKind.Composition)]
public IReadOnlyList<UserActiveToken> ActiveTokens { get; init; }
/// <summary>Отозванные токены пользователя (чёрный список).</summary>
[Relation(Kind = RelationKind.Composition)]
public IReadOnlyList<UserInvalidatedToken> InvalidatedTokens { get; init; }
}
/// <summary>Членство пользователя в группе полномочий (связь «пользователь — группа»).</summary>
[DomainEntity]
public class UserGroup
{
/// <summary>Идентификатор членства.</summary>
public Guid Id { get; init; }
/// <summary>Группа полномочий.</summary>
[Relation]
public Group Group { get; init; }
}
/// <summary>Описание доменной сущности <see cref="User"/>.</summary>
public class UserSpec : IDomainEntityDocument
{
public Type Entity => typeof(User);
public string Name => "Пользователь";
public string Description =>
@"Учётная запись Сервиса: через неё выполняется вход, и от её членства в группах зависят полномочия. Роли видения — хранитель и администратор — выражаются набором групп, а не отдельным полем.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new string[0];
public static string S1_Purpose = """
## Назначение
Пользователь — субъект доступа. Он входит по логину и паролю, получает токен сессии и на
каждый защищённый вызов предъявляет свои полномочия. Сами полномочия у пользователя не
хранятся напрямую — они выводятся из групп, в которые он входит (группа → функции →
claim-значения).
Роли из видения (хранитель, администратор) — это **не отдельное поле**, а удобные наборы
групп/функций: «хранитель» = функции ввода и проверки, «администратор» = функции
конфигурации и управления доступом.
""";
public static string S2_Invariants = """
## Инварианты
- Логин уникален.
- Полномочия задаются только через членство в группах; прямых прав у пользователя нет.
- Пароль на этапе разработки — открытым текстом (сид); до продакшна — хеш + соль.
- Поля истории (`CreatedByUserId` / `AssignedToUserId` пакета) ссылаются на пользователя
по идентификатору и заполняются из контекста вошедшего.
""";
public static string S99_Related = $"""
## Связанные артефакты
- {nameof(Ban.Sdaid.Icd.Arch.Adr.ADR_011_AbacAuthorization)} — модель доступа (claims → функции → группы).
- {nameof(Ban.Sdaid.Icd.Arch.Tech.CSharp.ADR_SRV_006_AuthImplementation)} — вход, токен, контекст, хранение пароля.
- {nameof(Ban.Sdaid.Icd.Arch.Adr.ADR_004_CreatorVsAssignee)} — поля пользователя в истории пакета.
""";
}
}