feat(backend): add knowledge base, innovation library and trends modules

Add knowledge item and innovation CRUD with search/filtering, published-only visibility for non-staff, admin publish/update, challenge dictionary, problem aggregation with trends (admin only) and canonical embedding text preparation for matchmaking.
This commit is contained in:
Rafał Tyński
2026-10-04 02:32:33 +02:00
parent fee137aee6
commit bad37a6ab9
19 changed files with 1074 additions and 0 deletions
@@ -64,3 +64,70 @@ internal sealed class CountRow
{
[CborProperty("count")] public int Count { get; set; }
}
internal sealed class ChallengeRow
{
[CborProperty("id")] public string Id { get; set; } = string.Empty;
[CborProperty("name")] public string Name { get; set; } = string.Empty;
[CborProperty("description")] public string Description { get; set; } = string.Empty;
[CborProperty("order")] public int Order { get; set; }
}
internal sealed class KnowledgeItemRow
{
[CborProperty("id")] public string Id { get; set; } = string.Empty;
[CborProperty("title")] public string Title { get; set; } = string.Empty;
[CborProperty("kind")] public string Kind { get; set; } = string.Empty;
[CborProperty("challenge")] public string? Challenge { get; set; }
[CborProperty("source_url")] public string? SourceUrl { get; set; }
[CborProperty("attachments")] public List<Dictionary<string, object?>> Attachments { get; set; } = [];
[CborProperty("published")] public bool Published { get; set; }
[CborProperty("updated_at")] public DateTimeOffset? UpdatedAt { get; set; }
}
internal sealed class InnovationRow
{
[CborProperty("id")] public string Id { get; set; } = string.Empty;
[CborProperty("title")] public string Title { get; set; } = string.Empty;
[CborProperty("summary")] public string Summary { get; set; } = string.Empty;
[CborProperty("description")] public string Description { get; set; } = string.Empty;
[CborProperty("challenge")] public string Challenge { get; set; } = string.Empty;
[CborProperty("stage")] public string Stage { get; set; } = string.Empty;
[CborProperty("cost")] public string? Cost { get; set; }
[CborProperty("contact")] public Dictionary<string, object?>? Contact { get; set; }
[CborProperty("media")] public List<Dictionary<string, object?>> Media { get; set; } = [];
[CborProperty("published")] public bool Published { get; set; }
[CborProperty("updated_at")] public DateTimeOffset? UpdatedAt { get; set; }
}
internal sealed class TrendRow
{
[CborProperty("challenge")] public string Challenge { get; set; } = string.Empty;
[CborProperty("count")] public int Count { get; set; }
}
internal sealed class TrendSubmissionRow
{
[CborProperty("challenge")] public string Challenge { get; set; } = string.Empty;
}