Skip to content

Commit

Permalink
feat: 🎸 #24 change persons to users table (#25)
Browse files Browse the repository at this point in the history
* feat: 🎸 Replace persons with users table, add new table fields

BREAKING CHANGE: 🧨 The database `persons` table has been replaced with `users` table and
new fields have been introduced to the existing tables.

* feat: 🎸 Create Theme enum

* refactor: 💡 Update files to reflect database changes

Updated models, interfaces, controllers and dtos to reflect new database
changes

BREAKING CHANGE: 🧨 The `Person` model has been replaced with the `User` model.

---------

Co-authored-by: Said Alisic <[email protected]>
  • Loading branch information
Said-Alisic and Said Alisic authored Jan 9, 2024
1 parent e10bf05 commit 98463f9
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 110 deletions.
61 changes: 38 additions & 23 deletions sql/init-scripts/01-database-setup.sql
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Create CalendarEvent table
CREATE TABLE "calendarEvent" (
"id" uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
"dateAndTime" TIMESTAMP NOT NULL,
"title" VARCHAR(255) NOT NULL,
"location" VARCHAR(255) NOT NULL,
"status" VARCHAR(50) NOT NULL
);
-- Create theme enum type
CREATE TYPE themeEnum AS ENUM ('SYSTEM', 'DARK', 'LIGHT');

-- Create users table
CREATE TABLE
"users" (
"id" uuid DEFAULT uuid_generate_v4 () PRIMARY KEY,
"firstname" VARCHAR(255) NOT NULL,
"lastname" VARCHAR(255) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"theme" themeEnum NOT NULL DEFAULT 'SYSTEM',
"notificationsEnabled" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP NOT NULL DEFAULT NOW (),
"updatedAt" TIMESTAMP NOT NULL DEFAULT NOW ()
);

-- Create Person table
CREATE TABLE "person" (
"id" uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
"firstname" VARCHAR(255) NOT NULL,
"lastname" VARCHAR(255) NOT NULL,
"email" VARCHAR(255) NOT NULL
);
-- Create calendarEvents table
CREATE TABLE
"calendarEvents" (
"id" uuid DEFAULT uuid_generate_v4 () PRIMARY KEY,
"dateAndTime" TIMESTAMP NOT NULL,
"title" VARCHAR(255) NOT NULL,
"location" VARCHAR(255) NOT NULL,
"status" VARCHAR(50) NOT NULL,
"description" VARCHAR(500),
"createdAt" TIMESTAMP NOT NULL DEFAULT NOW (),
"updatedAt" TIMESTAMP NOT NULL DEFAULT NOW ()
);

-- Create participant table
CREATE TABLE "participant" (
"calendarEventId" uuid NOT NULL,
"personId" uuid NOT NULL,
PRIMARY KEY ("calendarEventId", "personId"),
FOREIGN KEY ("calendarEventId") REFERENCES "calendarEvent" ("id") ON DELETE CASCADE,
FOREIGN KEY ("personId") REFERENCES "person" ("id") ON DELETE CASCADE
);
-- Create participants table
CREATE TABLE
"participants" (
"calendarEventId" uuid NOT NULL,
"userId" uuid NOT NULL,
"createdAt" TIMESTAMP NOT NULL DEFAULT NOW (),
"updatedAt" TIMESTAMP NOT NULL DEFAULT NOW (),
PRIMARY KEY ("calendarEventId", "userId"),
FOREIGN KEY ("calendarEventId") REFERENCES "calendarEvents" ("id") ON DELETE CASCADE,
FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE
);
69 changes: 36 additions & 33 deletions sql/init-scripts/02-database-seed.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
-- Insert CalendarEvent seed data
INSERT INTO "calendarEvent" ("id", "dateAndTime", "title", "location", "status")
-- Insert users seed data
INSERT INTO "users" ("id", "firstname", "lastname", "email", "password", "theme", "notificationsEnabled")
VALUES
('39bf5de4-4049-4463-bdbb-007d2ee02474', 'John', 'Doe', '[email protected]', 'password', 'SYSTEM', false),
('d1aef966-6661-4959-8d53-957265ee04a0', 'Jane', 'Doe', '[email protected]', 'password', 'SYSTEM', false),
('7777c377-4dd6-4346-8f52-75a96992f078', 'Alice', 'Smith', '[email protected]', 'password', 'SYSTEM', false),
('3a84c478-24dd-4bba-9fae-fee48788c35f', 'Bob', 'Johnson', '[email protected]', 'password', 'SYSTEM', false),
('9e9ebd4e-7224-4c08-8d1a-d42b3fb367e2', 'Emily', 'Williams', '[email protected]', 'password', 'SYSTEM', false),
('94a9a324-d827-4b90-88b6-90dc62d3d5ce', 'Michael', 'Brown', '[email protected]', 'password', 'SYSTEM', false),
('7d0879a0-d33e-4925-a98c-128c5f8f7cef', 'Sophia', 'Jones', '[email protected]', 'password', 'SYSTEM', false),
('4499c71a-83e2-4413-8eb6-d64038f1cf99', 'David', 'Taylor', '[email protected]', 'password', 'SYSTEM', false),
('026bc1e8-2c93-4d4c-8f1f-4de64b3fbfc2', 'Olivia', 'Martinez', '[email protected]', 'password', 'SYSTEM', false),
('3294cc62-9b9e-4330-af3b-d9060320e4a1', 'Daniel', 'Anderson', '[email protected]', 'password', 'SYSTEM', false),
('7e48612c-19fc-4ccc-9651-2782e4a9a1f5', 'Emma', 'Thomas', '[email protected]', 'password', 'SYSTEM', false),
('d1adfbf6-06f1-4016-90aa-5dccdd41fb89', 'Christopher', 'Harris', '[email protected]', 'password', 'SYSTEM', false),
('ff6ba20e-0900-4c15-a39e-6baab5d2d8a4', 'Ava', 'Clark', '[email protected]', 'password', 'SYSTEM', false),
('58d65c8b-3fd1-4738-b863-4a7b4abf74d3', 'Matthew', 'Lewis', '[email protected]', 'password', 'SYSTEM', false),
('bee967a7-0c2a-44f8-8044-d73f588a2c02', 'Madison', 'Moore', '[email protected]', 'password', 'SYSTEM', false),
('fa0f4d15-1a42-4bfd-a315-a3e59249367a', 'Ethan', 'White', '[email protected]', 'password', 'SYSTEM', false),
('63017c5e-f2d1-4719-a3b9-3bc6917020d7', 'Sophie', 'Scott', '[email protected]', 'password', 'SYSTEM', false),
('ab252f7d-ac3e-4db3-9d4d-a184fe337d7c', 'Justin', 'King', '[email protected]', 'password', 'SYSTEM', false),
('dbc820cc-1fae-48fd-987d-043050c8028c', 'Victoria', 'Young', '[email protected]', 'password', 'SYSTEM', false),
('3129e20f-484a-4c55-b482-8d7e9d30ede5', 'William', 'Hill', '[email protected]', 'password', 'SYSTEM', false),
('ec45a75d-8bb2-4149-ad05-03b07e0efa9e', 'Isabella', 'Miller', '[email protected]', 'password', 'SYSTEM', false),
('338ab2d0-9e09-41a5-a423-98b6c6cc468c', 'James', 'Allen', '[email protected]', 'password', 'SYSTEM', false);

-- Insert calendarEvents seed data
INSERT INTO "calendarEvents" ("id", "dateAndTime", "title", "location", "status")
VALUES
('407714b2-6d85-4d71-b23a-d4d6609ffab7', '2023-01-01 08:00:00', 'Event 1', 'Location 1', 'ACTIVE'),
('91e42a53-d6a3-40a7-bebc-7eb91e1e36cd', '2023-02-02 12:30:00', 'Event 2', 'Location 2', 'COMPLETED'),
Expand All @@ -20,39 +46,16 @@ VALUES
('b771ae7e-7768-40f4-89cb-1a880bd0a63d', '2024-05-05 16:30:00', 'Event 17', 'Location 17', 'COMPLETED'),
('57236a59-5e12-44e0-893a-c0a5c957ff8d', '2024-06-06 18:55:00', 'Event 18', 'Location 18', 'CANCELLED'),
('3e06c69e-ac9d-4c62-955c-d61dc9856bdb', '2024-07-07 09:00:00', 'Event 19', 'Location 19', 'ACTIVE'),
('d0136348-63d6-41be-96db-6e95fd8e345b', '2024-08-08 15:40:00', 'Event 20', 'Location 20', 'COMPLETED');



-- Insert Person seed data
INSERT INTO "person" ("id", "firstname", "lastname", "email")
VALUES
('39bf5de4-4049-4463-bdbb-007d2ee02474', 'John', 'Doe', '[email protected]'),
('d1aef966-6661-4959-8d53-957265ee04a0', 'Jane', 'Doe', '[email protected]'),
('7777c377-4dd6-4346-8f52-75a96992f078', 'Alice', 'Smith', '[email protected]'),
('3a84c478-24dd-4bba-9fae-fee48788c35f', 'Bob', 'Johnson', '[email protected]'),
('9e9ebd4e-7224-4c08-8d1a-d42b3fb367e2', 'Emily', 'Williams', '[email protected]'),
('94a9a324-d827-4b90-88b6-90dc62d3d5ce', 'Michael', 'Brown', '[email protected]'),
('7d0879a0-d33e-4925-a98c-128c5f8f7cef', 'Sophia', 'Jones', '[email protected]'),
('4499c71a-83e2-4413-8eb6-d64038f1cf99', 'David', 'Taylor', '[email protected]'),
('026bc1e8-2c93-4d4c-8f1f-4de64b3fbfc2', 'Olivia', 'Martinez', '[email protected]'),
('3294cc62-9b9e-4330-af3b-d9060320e4a1', 'Daniel', 'Anderson', '[email protected]'),
('7e48612c-19fc-4ccc-9651-2782e4a9a1f5', 'Emma', 'Thomas', '[email protected]'),
('d1adfbf6-06f1-4016-90aa-5dccdd41fb89', 'Christopher', 'Harris', '[email protected]'),
('ff6ba20e-0900-4c15-a39e-6baab5d2d8a4', 'Ava', 'Clark', '[email protected]'),
('58d65c8b-3fd1-4738-b863-4a7b4abf74d3', 'Matthew', 'Lewis', '[email protected]'),
('bee967a7-0c2a-44f8-8044-d73f588a2c02', 'Madison', 'Moore', '[email protected]'),
('fa0f4d15-1a42-4bfd-a315-a3e59249367a', 'Ethan', 'White', '[email protected]'),
('63017c5e-f2d1-4719-a3b9-3bc6917020d7', 'Sophie', 'Scott', '[email protected]'),
('ab252f7d-ac3e-4db3-9d4d-a184fe337d7c', 'Justin', 'King', '[email protected]'),
('dbc820cc-1fae-48fd-987d-043050c8028c', 'Victoria', 'Young', '[email protected]'),
('3129e20f-484a-4c55-b482-8d7e9d30ede5', 'William', 'Hill', '[email protected]'),
('ec45a75d-8bb2-4149-ad05-03b07e0efa9e', 'Isabella', 'Miller', '[email protected]'),
('338ab2d0-9e09-41a5-a423-98b6c6cc468c', 'James', 'Allen', '[email protected]');
('d0136348-63d6-41be-96db-6e95fd8e345b', '2024-01-01 07:20:00', 'Event 20', 'Location 20', 'COMPLETED'),
('68effe54-6290-4a34-b796-997f655b5489', '2024-01-01 11:45:00', 'Event 21', 'Location 21', 'ACTIVE'),
('10dca8e0-1508-4170-b25c-8938c407d3d4', '2024-01-01 12:30:00', 'Event 22', 'Location 22', 'ACTIVE'),
('7e4f61c9-dd74-4204-8a8b-4d32f9ad4194', '2024-01-01 13:10:00', 'Event 23', 'Location 23', 'CANCELLED'),
('c4c23208-bd42-454d-a358-10067319e96f', '2024-01-01 20:00:00', 'Event 24', 'Location 24', 'COMPLETED'),
('7ccfe662-521c-46f2-88bf-7243c37078d1', '2024-01-01 23:05:00', 'Event 25', 'Location 25', 'ACTIVE');


-- Insert Participant seed data
INSERT INTO "participant" ("calendarEventId", "personId")
-- Insert participants seed data
INSERT INTO "participants" ("calendarEventId", "userId")
VALUES
('407714b2-6d85-4d71-b23a-d4d6609ffab7', '39bf5de4-4049-4463-bdbb-007d2ee02474'),
('407714b2-6d85-4d71-b23a-d4d6609ffab7', '4499c71a-83e2-4413-8eb6-d64038f1cf99'),
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Dto/GetCalendarEventResponseDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ public class GetCalendarEventResponseDto : IGetCalendarEventResponseDto

public string Status { get; set; }

public List<Person>? EventParticipants { get; set; }
public List<User>? EventParticipants { get; set; }
};
10 changes: 10 additions & 0 deletions src/Common/Enums/Theme.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace API.Common.Enums
{
public enum Theme
{
SYSTEM,

DARK,
LIGHT
}
}
2 changes: 1 addition & 1 deletion src/Common/Interfaces/IGetCalendarEventResponseDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ public interface IGetCalendarEventResponseDto
public string Location { get; set; }
public string Status { get; set; }

List<Person>? EventParticipants { get; set; }
List<User>? EventParticipants { get; set; }
}
22 changes: 11 additions & 11 deletions src/Controllers/CalendarEventsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,18 @@ public async Task<

if (!omitEventParticipants)
{
List<Guid> participantsPersonIds =
List<Guid> participantsUserIds =
await _apiDbContext
.Participants.Where(item => item.CalendarEventId.Equals(calendarEventId))
.Select(item => item.PersonId)
.Select(item => item.UserId)
.ToListAsync() ?? null;

// If participants' personIds were found, search database for those persons and add it to the response
if (participantsPersonIds != null && participantsPersonIds.Any())
// If participants' userIds were found, search database for those users and add it to the response
if (participantsUserIds != null && participantsUserIds.Any())
{
List<Person> eventParticipants =
List<User> eventParticipants =
await _apiDbContext
.Persons.Where(item => participantsPersonIds.Contains(item.Id))
.Users.Where(item => participantsUserIds.Contains(item.Id))
.ToListAsync() ?? null;

response = _mapper.Map<GetCalendarEventResponseDto>(calendarEvent);
Expand All @@ -113,7 +113,7 @@ await _apiDbContext
[HttpPost, Route("")]
public async Task<ActionResult<CreateCalendarEventDto>> CreateCalendarEvent(
[FromBody] CalendarEvent calendarEvent,
[FromQuery(Name = "personIds[]")] string[] personIds
[FromQuery(Name = "userIds[]")] string[] userIds
)
{
if (calendarEvent == null)
Expand All @@ -136,16 +136,16 @@ public async Task<ActionResult<CreateCalendarEventDto>> CreateCalendarEvent(
CalendarEvent = createdCalendarEvent.Entity as CalendarEvent
};

if (personIds != null && personIds.Any())
if (userIds != null && userIds.Any())
{
List<Participant> participants = personIds
List<Participant> participants = userIds
.Distinct()
.Select(
personId =>
userId =>
new Participant
{
CalendarEventId = calendarEvent.Id,
PersonId = Guid.Parse(personId)
UserId = Guid.Parse(userId)
}
)
.ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,38 @@

namespace API.Controllers
{
[Route("api/persons")]
[Route("api/Users")]
[ApiController]
public class PersonsController : Controller
public class UsersController : Controller
{
private readonly ApiDbContext _apiDbContext;

public PersonsController(ApiDbContext apiDbContext)
public UsersController(ApiDbContext apiDbContext)
{
_apiDbContext = apiDbContext;

_apiDbContext.Database.EnsureCreated();
}

// TODO: Add regex matching for the `email` query param
[HttpGet, Route(""),]
public async Task<ActionResult<IEnumerable<Person>>> GetPersons([FromQuery] string? email)
public async Task<ActionResult<IEnumerable<User>>> GetUsers([FromQuery] string? email)
{
IQueryable<Person> query = _apiDbContext.Persons;
IQueryable<User> query = _apiDbContext.Users;

if (Request.Query.ContainsKey("email"))
{
query = query.Where(item => item.Email.Equals(email));
}

Person[] persons = await query.ToArrayAsync() ?? Array.Empty<Person>();
User[] Users = await query.ToArrayAsync() ?? Array.Empty<User>();

if (persons == null || persons.Length == 0)
if (Users == null || Users.Length == 0)
{
return NotFound();
}

return Ok(persons);
return Ok(Users);
}
}
}
4 changes: 2 additions & 2 deletions src/Data/ApiDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public ApiDbContext(DbContextOptions<ApiDbContext> options)

public DbSet<Participant> Participants { get; set; }

public DbSet<Person> Persons { get; set; }
public DbSet<User> Users { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Participant>().HasKey(p => new { p.CalendarEventId, p.PersonId });
modelBuilder.Entity<Participant>().HasKey(p => new { p.CalendarEventId, p.UserId });
}
}
}
8 changes: 7 additions & 1 deletion src/Models/CalendarEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace API.Models
{
[Table("calendarEvent")]
[Table("calendarEvents")]
public class CalendarEvent
{
[Key]
Expand Down Expand Up @@ -34,5 +34,11 @@ public class CalendarEvent
)]
[Column("status", TypeName = "varchar(50)")]
public string Status { get; set; }

[Column("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;

[Column("updatedAt")]
public DateTime UpdatedAt { get; set; } = DateTime.Now;
}
}
16 changes: 11 additions & 5 deletions src/Models/Participant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@

namespace API.Models
{
[Table("participant")]
[Table("participants")]
public class Participant
{
[ForeignKey("CalendarEvent")]
[Required(ErrorMessage = "CalendarEventId is required")]
[Column("calendarEventId", TypeName = "uuid")]
public Guid CalendarEventId { get; set; }

[ForeignKey("Person")]
[Required(ErrorMessage = "PersonId is required")]
[Column("personId", TypeName = "uuid")]
public Guid PersonId { get; set; }
[ForeignKey("User")]
[Required(ErrorMessage = "UserId is required")]
[Column("userId", TypeName = "uuid")]
public Guid UserId { get; set; }

[Column("createdAt")]
public DateTime CreatedAt { get; set; } = DateTime.Now;

[Column("updatedAt")]
public DateTime UpdatedAt { get; set; } = DateTime.Now;
}
}
25 changes: 0 additions & 25 deletions src/Models/Person.cs

This file was deleted.

Loading

0 comments on commit 98463f9

Please sign in to comment.