Перейти до вмісту

Проби та вмілості

Модуль відстежує складання проб і здобуття вмілостей членами куреня. Каталог (вимоги проб, перелік вмілостей, зображення) не зберігається в базі: його віддає сервіс каталогу (https://catalog.rostyslav-mukha.dev, опис API — /docs).

Секція Catalog в appsettings:

  • BaseUrl — адреса сервісу каталогу;
  • Krai — лише записи цього краю (?krai=); порожнє — увесь каталог;
  • RefreshMinutes — як часто питати сервіс знову (незмінений каталог коштує відповідь 304);
  • TimeoutSeconds — тайм-аут одного запиту;
  • SnapshotPath — копія останньої вдалої відповіді на диску (відносний шлях — від теки застосунку).

CatalogSyncBackgroundService під час старту читає копію з диска; якщо її немає, чекає першої відповіді сервісу, щоб API не відкрився з порожнім каталогом. Якщо й сервіс не відповів, API бере копію, вбудовану в збірку (ProjectK.Infrastructure/Services/Catalog/Seed/catalog.json). Ця копія ніколи не пишеться на диск. Невдалий запит лишає те, що вже завантажено, а відповідь без жодної вмілості й проби не замінює наявний каталог.

Поки сервіс не відповів жодного разу (а копії з диска немає), API питає знову частіше: за хвилину, далі вдвічі довше після кожної невдачі, але не рідше за RefreshMinutes. Після першої вдалої відповіді — звичайний інтервал.

Вбудовану копію оновлюй перед релізом: bash scripts/update-catalog-seed.sh (або pwsh scripts/update-catalog-seed.ps1). Скрипт перевіряє, що каталог говорить схемою 2.

Сервіс каталогу стоїть за Cloudflare. Bot Fight Mode на зоні rostyslav-mukha.dev відповідає запитам з адрес дата-центрів (Azure, раннери GitHub) перевіркою, яку HttpClient не пройде, тож API лишається без каталогу. Bot Fight Mode на зоні вимкнений; правилами WAF його не обійти, пропускають повз нього лише IP Access Rules.

Зображення вмілостей — абсолютні адреси каталогу, браузер бере їх напряму. Зображення відзначень API віддає за старою адресою /api/awards/images/{level}, беручи їх із каталогу.

  • ProbesCatalogController — каталог проб;
  • BadgesCatalogController — каталог вмілостей;
  • MemberProgressController — проби й вмілості конкретного члена;
  • черга розгляду вмілостей куреня — KurinController.GetBadgeReviewQueue.
  • ProbeProgress — проба члена; ProbePointProgress — кожна точка проби з підписом того, хто її прийняв;
  • BadgeProgress — вмілість;
  • ProbeProgressAuditEvent / BadgeProgressAuditEvent — журнал змін.

Права: підписати точку і розглянути вмілість може впорядник у своїх гуртках (OwnGroups) або Звʼязковий у всьому курені (KurinWide) — гранти на ProbeProgress і BadgeProgress у RolePermissionMap мають лише вони й адміністратор. Провід куреня (курінний, писар, скарбник) цих грантів не має: усі записи MemberProgressController захищені ResourceAuthorize по учаснику.

Екрани в kurinModule: member-probe-page (проба з точками), skills-review-page (черга на розгляд), картка члена (member-card) із вкладками проби й вмілостей.

Кнопка «Деталі» стоїть зліва від кнопок дій біля кожної вмілості: у діалогах «Усі вмілості» й «Додати вмілість» та в черзі розгляду. Вона відкриває badge-details-dialog — картку вмілості, як на сайті каталогу: край, рівень, улад, спеціалізація, вимоги по пунктах, вимоги до інструктора, автор і дата оновлення. Картка бере вмілість за badgeId із кешованого BadgesCatalogService.getById. Позначки **…** з каталогу показуються жирним без innerHTML. Поля requirements, author і ulady API додає до вмілості окремо; seekerRequirements лишається тим самим суцільним текстом для старих клієнтів.