takttusur / takt-media

Check our news and participate to competitions and other events
MIT License
0 stars 0 forks source link

Implement News functionality #3

Open RegiKein opened 11 months ago

RegiKein commented 11 months ago

API for latest news

As a user I want to read latest news of TAKT club So that to know about last updates of club life

Acceptance criteria

Stage one: Models

  1. TaktTusur.Media.Domain.News namespace contains Article class, it has:
    1. long Id - unique identifier of article
    2. string Title - the headline of article
    3. string Text - article text
    4. string TitlePictureUrl - the URL of title picture, which will be shown after the title
    5. DateTime CreatedAt - date of creation
    6. DateTime ModifiedAt - date of latest modification
    7. ExternalArticleLink? ExternalArticleLink - if this article was imported from another source - the link to that, can be null
  2. TaktTusur.Media.Domain.News namespace contains ExternalArticleLink class, it has:
    1. Article Article - the article, which was imported
    2. ExternalSource ExternalSource - external source(vk group, table, instagram etc.)
    3. string? OriginalUrl - URL to original article(post at VK group), can be null
    4. DateTime AccessDate - date and time of access to the original url/original article
  3. TaktTusur.Media.Domain.ExternalSource namespace contains ExternalSource class, it has:
    1. long Id - unique identifier of source
    2. string Title - name of source
    3. string URL - URL to access
    4. bool IsEnabled - enabled or disabled
    5. SourceType SourceType - the type of external source(VK group, instagram etc.)
  4. TaktTusur.Media.Domain.ExternalSource namespace contains SourceType enum, it can be:
    1. SourceType.Undefined = 0 - undefined source type
    2. SourceType.VkGroup = 1 - VK.com group

Stage two: Database

  1. TaktTusur.Media.Infrastructure.MediaDatabase contains MediaDatabaseContext
  2. The `MediaDatabaseContext has DbSets:
    1. DbSet<Article> Articles
    2. DbSet<ExternalArticleLink> ExternalArticleLinks
    3. DbSet<ExternalSource> ExternalSources
  3. The OnModelCreating(...) method in MediaDatabaseContext should execute Entity Type Configurations:
    1. class ArticleEntityTypeConfiguration: IEntityTypeConfiguration<Article> - Article model mapping to SQL
    2. class ExternalArticleLinkEntityTypeConfiguration: IEntityTypeConfiguration<ExternalArticleLink> - ExternalArticleLink model mapping to SQL
    3. class ExternalSourceEntityTypeConfiguration : IEntityTypeConfiguration<ExternalSource> - ExternalSource model mapping to SQL
  4. Each model mapping from p.3 has Configure method, which describes the mapping from C# class to SQL following this rules EF Core | Microsoft Learn

Stage three: PgSQL

  1. Add PostgreSQL database support(with Entity Framework Core)
  2. The appsettings.json contains ConnectionString property
  3. The real connection string should be placed in dotnet user secrets
  4. Add pgsql container to docker-compose file, to make testing easier

Stage four: Services

  1. NewsRepository should provide access to Articles in DB using MediaDatabaseContext
  2. NewsReadService provides a page model:
    1. Page model has short information about articles
    2. Page model has total articles count
    3. Page model has information about skipped articles
  3. The News controller provides HTTP GET method to take articles, using NewsReadService
  4. Swagger UI provides testing UI for getting some articles

Stage five: Crawling

  1. The TaktTusur.Media.BackgroundCrawler project is responsible for crawling and adding latest news from VK Group to the DB
  2. appsettings.json of TaktTusur.Media.BackgroundCrawler has NewsCrawling section, which is array
  3. Each entry in NewsCrawling contains:
    1. long Id - identifier of external source
    2. string Title - title of external source
    3. string URL - URL of external source
    4. bool IsEnabled - external source should be parsed or no
    5. SourceType SourceType - the source type of source(see p.4 of stage one)
    6. string ApiKey - the API key to access to the source
  4. appsettings.json of TaktTusur.Media.BackgroundCrawler has UpdateIntervalInMinutes parameter:
    1. Data type - integer
  5. appsettings.json of TaktTusur.Media.BackgroundCrawler has NewsCrawlingDeepth parameter:
    1. Data type - integer
  6. When the project is started, it compares the data from appconfig.json with DB:
    1. Find the ExternalSource object by Id in DB
    2. Compare it with appsettings.json
    3. The object in DB should be updated, following appsettings.json
    4. If the object is not exists, it should be created
  7. Each X minutes(from UpdateIntervalInMinutes) updates for each source should be requested:
    1. At one time only one source could be in process
    2. Crawler makes request to source and get X latest articles(using NewsCrawlingDeepth variable)
    3. If the response contains articles, which are not in DB - it should be added to DB
  8. All data structures for this stage should be placed in TaktTusur.Media.BackgroundCrawler -> NewsCrawling directory

Technical details

classDiagram
    class INewsRepository{
        + GetAll() IQueryable~Article~
        + GetById(id)  ~Article~
    }
    class NewsRepository
    class INewsReadService{
        + GetPage(skip, take) PageModel~ShortArticleModel~
    }
    class NewsReadService
    class PageModel~T~{
        + Items List~T~
        + TotalCount int
        + Skipped int
    }
    class ShortArticleModel
    class NewsController
    NewsRepository --|> INewsRepository
    INewsReadService --> PageModel
    INewsReadService --> ShortArticleModel
    INewsReadService ..> INewsRepository
    NewsReadService --|> INewsReadService
    NewsController ..> INewsReadService

Out of scope

We don't have to make any authorisation for this

andreygolubkow commented 8 months ago

Can be started after #6