Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create paginated, filtered endpoints for WrittenSource, Persons, City #34

Merged
merged 8 commits into from
Feb 22, 2025
22 changes: 18 additions & 4 deletions backend/Controllers/CityController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ namespace Mappa.Controllers;
[Route("[controller]")]
public class CityController : ControllerBase
{
private readonly IComplexEntityService<City, CityGeneralDto, CityDetailDto,
CityCreateRequest, CityUpdateRequest>
private readonly ICityService
_service;

public CityController(IComplexEntityService<City, CityGeneralDto,
CityDetailDto, CityCreateRequest, CityUpdateRequest> service)
public CityController(ICityService service)
{
_service = service;
}
Expand All @@ -27,6 +25,14 @@ public async Task<IActionResult> GetAll()
return Ok(items);
}

[HttpGet]
[Route("filter")]
public async Task<IActionResult> GetAllFiltered(CityFilterDto filter)
{
var items = await _service.GetAllFilteredAsync(filter);
return Ok(items);
}

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
Expand Down Expand Up @@ -105,4 +111,12 @@ public async Task<IActionResult> Delete(int id)
}
}

[HttpGet]
[Route("map")]
public async Task<IActionResult> GetAllForMapAsync()
{
var items = await _service.GetAllForMapAsync();
return Ok(items);
}

}
42 changes: 39 additions & 3 deletions backend/Controllers/OrdinaryPersonController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ namespace Mappa.Controllers;
public class OrdinaryPersonController : ControllerBase
{
private readonly IComplexEntityService<OrdinaryPerson, OrdinaryPersonGeneralDto,
OrdinaryPersonDetailDto, OrdinaryPersonCreateRequest, OrdinaryPersonUpdateRequest>
OrdinaryPersonDetailDto, OrdinaryPersonCreateRequest,
OrdinaryPersonUpdateRequest, OrdinaryPersonFilterDto, OrdinaryPersonFilterResponseDto,
OrdinaryPersonGraphDto>
_service;

public OrdinaryPersonController(IComplexEntityService<OrdinaryPerson, OrdinaryPersonGeneralDto,
OrdinaryPersonDetailDto, OrdinaryPersonCreateRequest, OrdinaryPersonUpdateRequest> service)
public OrdinaryPersonController(IComplexEntityService<OrdinaryPerson,
OrdinaryPersonGeneralDto, OrdinaryPersonDetailDto, OrdinaryPersonCreateRequest,
OrdinaryPersonUpdateRequest, OrdinaryPersonFilterDto, OrdinaryPersonFilterResponseDto,
OrdinaryPersonGraphDto>
service)
{
_service = service;
}
Expand All @@ -27,6 +32,37 @@ public async Task<IActionResult> GetAll()
return Ok(items);
}

[HttpGet]
[Route("graph")]
public async Task<IActionResult> GetAllForGraph()
{
var items = await _service.GetAllForGraphAsync();
return Ok(items);
}

[HttpGet]
[Route("page")]
public async Task<IActionResult> GetPage([FromBody] PaginationRequest<OrdinaryPersonFilterDto> filter)
{
if (filter.PageNumber < 1 || filter.PageSize < 1)
{
return BadRequest("Page number and page size must be greater than 0.");
}

try
{
var paginatedResult = await _service.GetPageAsync(filter.PageNumber,
filter.PageSize, filter.Filter);

return Ok(paginatedResult);
}
catch(ArgumentException ex) when (ex.Message.Contains($"Filter is not provided."))
{
return BadRequest(new { Message = ex.Message });
}

}

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
Expand Down
11 changes: 8 additions & 3 deletions backend/Controllers/SecondarySourceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ namespace Mappa.Controllers;
[Route("[controller]")]
public class SecondarySourceController : ControllerBase
{
private readonly IComplexEntityService<SecondarySource, SecondarySourceGeneralDto, SecondarySourceDetailDto, SecondarySourceCreateRequest, SecondarySourceUpdateRequest>
private readonly IComplexEntityService<SecondarySource, SecondarySourceGeneralDto,
SecondarySourceDetailDto, SecondarySourceCreateRequest,
SecondarySourceUpdateRequest, SecondarySourceFilterDto, SecondarySourceFilterResponseDto,
SecondarySourceGraphDto>
_service;

public SecondarySourceController(IComplexEntityService<SecondarySource, SecondarySourceGeneralDto,
SecondarySourceDetailDto, SecondarySourceCreateRequest, SecondarySourceUpdateRequest> service)
public SecondarySourceController(IComplexEntityService<SecondarySource,
SecondarySourceGeneralDto, SecondarySourceDetailDto,
SecondarySourceCreateRequest, SecondarySourceUpdateRequest,
SecondarySourceFilterDto, SecondarySourceFilterResponseDto, SecondarySourceGraphDto> service)
{
_service = service;
}
Expand Down
42 changes: 39 additions & 3 deletions backend/Controllers/UnordinaryPersonController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ namespace Mappa.Controllers;
[Route("[controller]")]
public class UnordinaryPersonController : ControllerBase
{
private readonly IComplexEntityService<UnordinaryPerson, UnordinaryPersonGeneralDto, UnordinaryPersonDetailDto, UnordinaryPersonCreateRequest, UnordinaryPersonUpdateRequest>
private readonly IComplexEntityService<UnordinaryPerson, UnordinaryPersonGeneralDto,
UnordinaryPersonDetailDto, UnordinaryPersonCreateRequest,
UnordinaryPersonUpdateRequest, UnordinaryPersonFilterDto, UnordinaryPersonFilterResponseDto,
UnordinaryPersonGraphDto>
_service;

public UnordinaryPersonController(IComplexEntityService<UnordinaryPerson, UnordinaryPersonGeneralDto,
UnordinaryPersonDetailDto, UnordinaryPersonCreateRequest, UnordinaryPersonUpdateRequest> service)
public UnordinaryPersonController(IComplexEntityService<UnordinaryPerson,
UnordinaryPersonGeneralDto, UnordinaryPersonDetailDto,
UnordinaryPersonCreateRequest, UnordinaryPersonUpdateRequest,
UnordinaryPersonFilterDto, UnordinaryPersonFilterResponseDto, UnordinaryPersonGraphDto>
service)
{
_service = service;
}
Expand All @@ -26,6 +32,36 @@ public async Task<IActionResult> GetAll()
return Ok(items);
}

[HttpGet]
[Route("graph")]
public async Task<IActionResult> GetAllForGraph()
{
var items = await _service.GetAllForGraphAsync();
return Ok(items);
}

[HttpGet]
[Route("page")]
public async Task<IActionResult> GetPage([FromBody] PaginationRequest<UnordinaryPersonFilterDto> filter)
{
if (filter.PageNumber < 1 || filter.PageSize < 1)
{
return BadRequest("Page number and page size must be greater than 0.");
}

try
{
var paginatedResult = await _service.GetPageAsync(filter.PageNumber,
filter.PageSize, filter.Filter);

return Ok(paginatedResult);
}
catch(ArgumentException ex) when (ex.Message.Contains($"Filter is not provided."))
{
return BadRequest(new { Message = ex.Message });
}
}

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
Expand Down
33 changes: 30 additions & 3 deletions backend/Controllers/WrittenSourceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ namespace Mappa.Controllers;
[Route("[controller]")]
public class WrittenSourceController : ControllerBase
{
private readonly IComplexEntityService<WrittenSource, WrittenSourceGeneralDto, WrittenSourceDetailDto, WrittenSourceCreateRequest, WrittenSourceUpdateRequest>
private readonly IComplexEntityService<WrittenSource, WrittenSourceGeneralDto,
WrittenSourceDetailDto, WrittenSourceCreateRequest, WrittenSourceUpdateRequest,
WrittenSourceFilterDto, WrittenSourceFilterResponseDto, WrittenSourceGraphDto>
_service;

public WrittenSourceController(IComplexEntityService<WrittenSource, WrittenSourceGeneralDto,
WrittenSourceDetailDto, WrittenSourceCreateRequest, WrittenSourceUpdateRequest> service)
public WrittenSourceController(IComplexEntityService<WrittenSource,
WrittenSourceGeneralDto,WrittenSourceDetailDto, WrittenSourceCreateRequest,
WrittenSourceUpdateRequest, WrittenSourceFilterDto, WrittenSourceFilterResponseDto,
WrittenSourceGraphDto>
service)
{
_service = service;
}
Expand All @@ -26,6 +31,28 @@ public async Task<IActionResult> GetAll()
return Ok(items);
}

[HttpGet]
[Route("page")]
public async Task<IActionResult> GetPage([FromBody] PaginationRequest<WrittenSourceFilterDto> filter)
{
if (filter.PageNumber < 1 || filter.PageSize < 1)
{
return BadRequest("Page number and page size must be greater than 0.");
}

try
{
var paginatedResult = await _service.GetPageAsync(filter.PageNumber,
filter.PageSize, filter.Filter);

return Ok(paginatedResult);
}
catch(ArgumentException ex) when (ex.Message.Contains($"Filter is not provided."))
{
return BadRequest(new { Message = ex.Message });
}
}

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
Expand Down
50 changes: 50 additions & 0 deletions backend/Db/AppDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.Intrinsics.X86;
using System.Threading.Tasks.Dataflow;
using Mappa.Entities;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
Expand Down Expand Up @@ -44,5 +45,54 @@ protected override void OnModelCreating(ModelBuilder builder)
e => e.HasOne<UnordinaryPerson>().WithMany().HasForeignKey(e => e.PersonIdA),
e => e.HasOne<UnordinaryPerson>().WithMany().HasForeignKey(e => e.PersonIdB)
);

builder.Entity<OrdinaryPerson>()
.HasMany(o => o.InteractionsWithUnordinary)
.WithMany(u => u.InteractionsWithOrdinary);

builder.Entity<WrittenSource>().HasMany(ws => ws.OrdinaryPersons)
.WithMany(p => p.Sources);

builder.Entity<WrittenSource>().HasMany(ws => ws.UnordinaryPersons)
.WithMany(p => p.Sources);

builder.Entity<Religion>().HasMany(ws => ws.FormerOrdinaryPersons)
.WithOne(p => p.FormerReligion);

builder.Entity<OrdinaryPerson>().HasOne(op => op.Religion)
.WithMany();

builder.Entity<UnordinaryPerson>().HasOne(up => up.Religion)
.WithMany();

// Translated Languages

builder.Entity<WrittenSource>().HasMany(ws => ws.TranslatedLanguages)
.WithMany();

builder.Entity<SecondarySource>().HasMany(ss => ss.TranslatedLanguages)
.WithMany();

// ----------- <City Mappings> --------------

builder.Entity<OrdinaryPerson>().HasOne(op => op.Location)
.WithMany(c => c.LocationOf);

builder.Entity<OrdinaryPerson>().HasOne(op => op.BackgroundCity)
.WithMany(c => c.BackgroundCityOf);

builder.Entity<UnordinaryPerson>().HasOne(up => up.BirthPlace)
.WithMany(c => c.BirthPlaceOf);

builder.Entity<UnordinaryPerson>().HasOne(up => up.DeathPlace)
.WithMany(c => c.DeathPlaceOf);

builder.Entity<WrittenSource>().HasMany(ws => ws.CitiesMentionedByTheSource)
.WithMany(c => c.SourcesMentioningTheCity);

builder.Entity<WrittenSource>().HasMany(ws => ws.CitiesWhereSourcesAreWritten)
.WithMany(c => c.SourcesWrittenInTheCity);

// ----------- </City Mappings> --------------
}
}
61 changes: 56 additions & 5 deletions backend/Dtos/CityDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,84 @@ namespace Mappa.Dtos;
public class CityBaseDto
{
public int Id { get; set; }
public string AsciiName { get; set; }
public string? AsciiName { get; set; }
public string Name {get; set;}
}

public class CityGeneralDto : CityBaseDto
{
}
public class CityGeneralDto : CityBaseDto {}

public class CityDetailDto : CityGeneralDto
{
public string? GeoNamesId {get; set;}
public List<string>? AlternateNames {get; set;}
public string? CountryCode {get; set;}
public double? Latitude {get; set;}
public double? Longitude {get; set;}
// OrdinaryPerson Ids
public List<OrdinaryPersonBaseDto>? LocationOf {get; set;}
public List<OrdinaryPersonBaseDto>? BackgroundCityOf {get; set;}
// UnordinaryPerson Ids
public List<UnordinaryPersonBaseDto>? BirthPlaceOf {get; set;}
public List<UnordinaryPersonBaseDto>? DeathPlaceOf {get; set;}
// WrittenSource Ids
public List<WrittenSourceBaseDto>? SourcesMentioningTheCity {get; set;}
public List<WrittenSourceBaseDto>? SourcesWrittenInTheCity {get; set;}
}

public class CityCreateRequest
{
[Required]
public string AsciiName { get; set; }
public string Name {get; set;}
public string? AsciiName { get; set; }
public string? GeoNamesId { get; set; }
public List<string>? AlternateNames { get; set; }
public string? CountryCode { get; set; }
public double? Latitude {get; set;}
public double? Longitude {get; set;}
}

public class CityUpdateRequest
{
public string? AsciiName { get; set; }
public string? Name {get; set;}
public string? GeoNamesId { get; set; }
public List<string>? AlternateNames { get; set; }
public string? CountryCode { get; set; }
public double? Latitude {get; set;}
public double? Longitude {get; set;}
}

public class CityFilterDto
{
// This includes both AsciiName and AlternateNames
public string? Name { get; set; }
// OrdinaryPerson Ids
public List<int>? LocationOf {get; set;}
public List<int>? BackgroundCityOf {get; set;}
// UnordinaryPerson Ids
public List<int>? BirthPlaceOf {get; set;}
public List<int>? DeathPlaceOf {get; set;}
// WrittenSource Ids
public List<int>? SourcesMentioningTheCity {get; set;}
public List<int>? SourcesWrittenInTheCity {get; set;}
}

public class CityFilterResponseDto : CityDetailDto {}

public class CityMapDto
{
public int Id { get; set; }
public string? AsciiName { get; set; }
public string Name {get; set;}
public double? Latitude {get; set;}
public double? Longitude {get; set;}
// OrdinaryPerson Ids
public int? NumberOfLocationOf {get; set;}
public int? NumberOfBackgroundCityOf {get; set;}
// UnordinaryPerson Ids
public int? NumberOfBirthPlaceOf {get; set;}
public int? NumberOfDeathPlaceOf {get; set;}
// WrittenSource Ids
public int? NumberOfSourcesMentioningTheCity {get; set;}
public int? NumberOfSourcesWrittenInTheCity {get; set;}
}
Loading