articles.md 5.9 KB

ArticlesService

Назначение

Сервис управляет статьями контент-раздела (инфо-материалы, новости, акции). Все статьи имеют уникальные ID из одной последовательности, но различаются по типу (ArticleTypeEnum). Создание и изменение выполняется единым методом UpdateAsync: если Id == 0, создаётся новая статья заданного типа; иначе обновляются изменяемые поля существующей. Запрет на несоответствие типа и Id (например, передача статьи одного типа с Id от другого) приводит к ошибке валидности данных. Контроль доступа - по данным сессии (NBSession).

Публичные методы

  • ArchiveAsync(articleId): void - пометка статьи как архивной.
  • SetPublishedAsync(articleId, isPublished): void - переключение статуса публикации.
  • UpdateAsync(article): Article - создание или обновление статьи.
  • GetArticlesAsync(type, skip = 0, take = 12, onlyIsPublished = true): ArticlesList - выборка статей по типу с пагинацией; onlyIsPublished = false допустимо только для админов.
  • GetArticleAsync(id): Article - получить статью по идентификатору.

Модели

Article

int Id – идентификатор статьи
ArticleTypeEnum Type – тип статьи (Unknown = 0, Info = 1, News = 2, Sale = 3)
string Alias – псевдоним для SEO/ссылок
string MetaKeywords – SEO ключевые слова
string MetaDescription – SEO описание
string Title – заголовок статьи
string Tag – тег или рубрика
string DescriptionShort – краткое описание
string ContentHTML – полный контент в формате HTML
FileDescriptor Foto – основное изображение
FileDescriptor FotoTile – изображение для тайла/превью
int ExpectReadTimeMinutes – ожидаемое время чтения в минутах
long ShowedCount – счётчик просмотров
int DiscountCategoryId – id категории, связанной с акцией
int[] DiscountProductIds – список id товаров для промо
DateTimeOffset StartTime – дата начала публикации
DateTimeOffset? EndTime – дата окончания публикации (опционально)
DateTimeOffset Created – дата создания статьи
bool IsPublished – признак опубликованности
bool IsArchived – признак архивирования
bool IsActive – вычисляемое поле, актуальность статьи (не хранится в БД)

ArticlesList

int TotalCount – общее количество статей по запросу
Article[] List – список статей на текущей странице

ArticleTypeEnum

Unknown = 0 – неопределённый тип
Info = 1 – информационный материал
News = 2 – новость
Sale = 3 – акция/промо

Правила и инварианты

  • Единая последовательность ID: все типы статей разделяют один счётчик идентификаторов, тип задаётся отдельно. Любая попытка «сменить тип под старым Id» должна блокироваться валидаторами.
  • Публикация vs активность: IsPublished и IsArchived управляются отдельными методами сервиса; IsActive - вычисляемое поле по времени окна публикации (StartTime/EndTime) и статусам, не хранится в БД.
  • Контроль доступа: операции чтения/управления учитывают сессионные права; параметр onlyIsPublished=false игнорируется для не-админов.
  • Медиа через файловый сервис: Foto/FotoTile - FileDescriptor из FilesDirectoryService; при обновлении статьи сервис должен валидировать наличие/категорию файлов согласно правилам файлового сервиса.
  • Потокобезопасность: операции CheckActive и Update используют внутренний lock, что исключает гонки при одновременных обновлениях и вычислении активности.

DB

Содержит таблицы и индексы

-- Migration 1
articles (
    Id INTEGER PRIMARY KEY AUTOINCREMENT,
    Type INTEGER NOT NULL DEFAULT 1,

    Alias TEXT NOT NULL,
    MetaKeywords TEXT NOT NULL,
    MetaDescription TEXT NOT NULL,
    Title TEXT NOT NULL,
    Tag TEXT NOT NULL,
    DescriptionShort TEXT NOT NULL,
    ContentHTML TEXT NOT NULL,

    Foto TEXT NOT NULL DEFAULT '{}',
    FotoTile TEXT NOT NULL DEFAULT '{}',
    ExpectReadTimeMinutes INTEGER NOT NULL DEFAULT 0,
    ShowedCount INTEGER NOT NULL DEFAULT 0,

    DiscountCategoryId INTEGER NOT NULL DEFAULT 0,
    DiscountProductIds TEXT NOT NULL DEFAULT '[]',

    StartTime NUMBER NOT NULL,
    EndTime NUMBER NOT NULL,
    Created NUMBER NOT NULL,

    IsPublished BOOLEAN NOT NULL DEFAULT FALSE,
    IsArchived BOOLEAN NOT NULL DEFAULT FALSE,
    IsActive BOOLEAN NOT NULL DEFAULT FALSE
)

Назад