Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTOs/CustomerGetDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace api_cinema_challenge.DTOs;

public class CustomerGetDto
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public string Email { get; set; } = null!;
public string Phone { get; set; } = null!;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace api_cinema_challenge.DTOs;

public class CustomerPostDto
{
public required string Name { get; set; }
public required string Email { get; set; }
public required string Phone { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace api_cinema_challenge.DTOs;

public class CustomerUpdateDto
{
public string? Name { get; set; }
public string? Email { get; set; }
public string? Phone { get; set; }
}
12 changes: 12 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTOs/MovieGetDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace api_cinema_challenge.DTOs;

public class MovieGetDto
{
public int Id { get; set; }
public string Title { get; set; }
public double Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public DateTime UpdatedAt { get; set; }
public DateTime CreatedAt { get; set; }
}
12 changes: 12 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTOs/MoviePostDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using api_cinema_challenge.Models;

namespace api_cinema_challenge.DTOs;

public class MoviePostDto
{
public required string Title { get; set; }
public required double Rating { get; set; }
public required string Description { get; set; }
public required int RuntimeMins { get; set; }
public required ICollection<MoviePostScreeningDto> Screenings { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace api_cinema_challenge.DTOs;

public class MoviePostScreeningDto
{
public int ScreenNumber { get; set; }

public int Capacity { get; set; }

public DateTime StartsAt { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace api_cinema_challenge.DTOs;

public class MovieUpdateDto
{
public string? Title { get; set; }
public double? Rating { get; set; }
public string? Description { get; set; }
public int? RuntimeMins { get; set; }
}
6 changes: 6 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTOs/NumSeatsDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace api_cinema_challenge.DTOs;

public class NumSeatsDto
{
public required int NumSeats { get; set; }
}
11 changes: 11 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/DTOs/ScreeningGetDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace api_cinema_challenge.DTOs;

public class ScreeningGetDto
{
public int Id { get; set; }
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace api_cinema_challenge.DTOs;

public class ScreeningPostDto
{
public required int ScreenNumber { get; set; }
public required int Capacity { get; set; }
public required DateTime StartsAt { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace api_cinema_challenge.DTOs;

public class TicketGetDto
{
public int Id { get; set; }
public int NumSeats { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
26 changes: 0 additions & 26 deletions api-cinema-challenge/api-cinema-challenge/Data/CinemaContext.cs

This file was deleted.

61 changes: 61 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Data/CinemaDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Diagnostics;
using api_cinema_challenge.Models;
using Microsoft.EntityFrameworkCore;

namespace api_cinema_challenge.Data
{
public sealed class CinemaDbContext : DbContext
{
private readonly string _connectionString;

public CinemaDbContext(DbContextOptions<CinemaDbContext> options) : base(options)
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnection")!;
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Seeder seeds = new Seeder();

// One-to-many relationships
// One customer to many tickets
modelBuilder.Entity<Customer>()
.HasMany(c => c.Tickets)
.WithOne(t => t.Customer)
.HasForeignKey(t => t.CustomerId)
.OnDelete(DeleteBehavior.Cascade);

//Many tickets to one screening
modelBuilder.Entity<Screening>()
.HasMany(c => c.Tickets)
.WithOne(t => t.Screening)
.HasForeignKey(t => t.ScreeningId)
.OnDelete(DeleteBehavior.Cascade);

// Many screenings to one movie
modelBuilder.Entity<Movie>()
.HasMany(m => m.Screenings)
.WithOne(s => s.Movie)
.HasForeignKey(s => s.MovieId)
.OnDelete(DeleteBehavior.Cascade);

// Seed data
modelBuilder.Entity<Movie>().HasData(seeds.Movies);
modelBuilder.Entity<Customer>().HasData(seeds.Customers);
modelBuilder.Entity<Screening>().HasData(seeds.Screenings);
modelBuilder.Entity<Ticket>().HasData(seeds.Tickets);
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_connectionString);
optionsBuilder.LogTo(message => Debug.WriteLine(message));
}

public DbSet<Movie> Movies { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Screening> Screenings { get; set; }
public DbSet<Ticket> Tickets { get; set; }
}
}
112 changes: 112 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Data/CustomerSeed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Data/CustomerSeeder.cs

using System.Linq;
using api_cinema_challenge.Models;

namespace api_cinema_challenge.Data;
public class CustomerSeed
{
private List<string> _firstNames =
[
"John", "Jane", "Alice", "Bob", "Charlie", "Diana", "Ethan", "Fiona",
"George", "Hannah", "Ian", "Julia", "Kevin", "Laura", "Mike", "Nina"
];

private List<string> _lastNames =
[
"Smith", "Doe", "Johnson", "Brown", "Williams", "Miller", "Davis", "Wilson",
"Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson"
];

private List<string> _domain = new List<string>()
{
"bbc.co.uk",
"google.com",
"theworld.ca",
"something.com",
"tesla.com",
"nasa.org.us",
"gov.us",
"gov.gr",
"gov.nl",
"gov.ru"
};

// Builds a deterministic list of customers with unique emails and phone numbers.
public List<Customer> Get(int take = 10)
{
var customers = new List<Customer>(take);
int id = 1;

foreach (var first in _firstNames)
{
foreach (var last in _lastNames)
{
if (customers.Count >= take) return customers;

var domain = _domain[(id - 1) % _domain.Count];

customers.Add(new Customer
{
Id = id,
Name = first + " " + last,
Email = BuildEmail(first, last, id, domain),
Phone = BuildPhone(id, domain)
});

id++;
}
}

// If 'take' exceeds the name combinations, keep cycling
while (customers.Count < take)
{
var first = _firstNames[(id - 1) % _firstNames.Count];
var last = _lastNames[(id - 1) % _lastNames.Count];
var domain = _domain[(id - 1) % _domain.Count];

customers.Add(new Customer
{
Id = id,
Name = first + " " + last,
Email = BuildEmail(first, last, id, domain),
Phone = BuildPhone(id, domain)
});

id++;
}

return customers;
}

private static string BuildEmail(string first, string last, int id, string domain)
{
string Slug(string s) => new string(s.ToLowerInvariant().Where(char.IsLetterOrDigit).ToArray());
return $"{Slug(first)}.{Slug(last)}{id}@{domain}";
}

private static string BuildPhone(int id, string domain)
{
// Map TLD to a country code; default to +47 (Norway)
var tld = domain.Split('.').Last();
var cc = tld switch
{
"us" => "1",
"uk" => "44",
"ca" => "1",
"gr" => "30",
"nl" => "31",
"ru" => "7",
"com" => "1",
"org" => "1",
_ => "47"
};

// Deterministic 3-3-4 style digits to ensure uniqueness and validity-like length
int a = (id * 7919) % 900 + 100; // 3 digits
int b = (id * 104729) % 900 + 100; // 3 digits
int c = (id * 13007) % 9000 + 1000; // 4 digits

return $"+{cc}{a}{b}{c}";
}
}
31 changes: 31 additions & 0 deletions api-cinema-challenge/api-cinema-challenge/Data/MovieSeed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//Brought to you by ChatGPT
using api_cinema_challenge.Models;

namespace api_cinema_challenge.Data;

public static class MovieSeed
{
public static List<Movie> Get() =>
[
new Movie { Id = 1, Title = "The Shawshank Redemption", Description = "A banker forms an unlikely friendship in prison while quietly plotting freedom.", RuntimeMins = 142, Rating = 9.3 },
new Movie { Id = 2, Title = "The Godfather", Description = "A powerful crime family faces shifting loyalties as a reluctant son takes the reins.", RuntimeMins = 175, Rating = 9.2 },
new Movie { Id = 3, Title = "The Dark Knight", Description = "Batman confronts a chaotic new foe whose plans push Gotham and its hero to the brink.", RuntimeMins = 152, Rating = 9.0 },
new Movie { Id = 4, Title = "Pulp Fiction", Description = "Intertwined tales of hitmen, a boxer, and a briefcase collide in offbeat fashion.", RuntimeMins = 154, Rating = 8.9 },
new Movie { Id = 5, Title = "Inception", Description = "A thief who steals secrets through dreams attempts one last, impossible heist.", RuntimeMins = 148, Rating = 8.8 },
new Movie { Id = 6, Title = "The Matrix", Description = "A hacker discovers a hidden reality and fights to free humanity from control.", RuntimeMins = 136, Rating = 8.7 },
new Movie { Id = 7, Title = "Parasite", Description = "Two families from different worlds become entangled in a sharp social thriller.", RuntimeMins = 132, Rating = 8.5 },
new Movie { Id = 8, Title = "Spirited Away", Description = "A girl navigates a spirit world to rescue her parents and find her courage.", RuntimeMins = 125, Rating = 8.6 },
new Movie { Id = 9, Title = "Gladiator", Description = "A betrayed general rises as a gladiator seeking justice against a corrupt emperor.", RuntimeMins = 155, Rating = 8.5 },
new Movie { Id = 10, Title = "Interstellar", Description = "Explorers venture through a wormhole to secure a future for humanity.", RuntimeMins = 169, Rating = 8.6 },
new Movie { Id = 11, Title = "The Lord of the Rings: The Fellowship of the Ring", Description = "A humble hero leads allies on a perilous quest to destroy a corrupting ring.", RuntimeMins = 178, Rating = 8.8 },
new Movie { Id = 12, Title = "The Silence of the Lambs", Description = "An FBI trainee seeks a killer’s profile with help from an imprisoned genius.", RuntimeMins = 118, Rating = 8.6 },
new Movie { Id = 13, Title = "Forrest Gump", Description = "A kind-hearted man unwittingly drifts through historic moments while chasing love.", RuntimeMins = 142, Rating = 8.8 },
new Movie { Id = 14, Title = "Fight Club", Description = "An insomniac’s underground club spirals into a manifesto against modern life.", RuntimeMins = 139, Rating = 8.8 },
new Movie { Id = 15, Title = "The Social Network", Description = "Friendships fracture as the creation of a global platform triggers legal battles.", RuntimeMins = 120, Rating = 7.8 },
new Movie { Id = 16, Title = "Whiplash", Description = "An ambitious drummer faces a ruthless mentor in a battle of will and rhythm.", RuntimeMins = 107, Rating = 8.5 },
new Movie { Id = 17, Title = "Mad Max: Fury Road", Description = "A high-octane desert chase pits rebels against a tyrant’s armored war party.", RuntimeMins = 120, Rating = 8.1 },
new Movie { Id = 18, Title = "La La Land", Description = "An actress and a jazz pianist chase dreams and reckon with the cost of ambition.", RuntimeMins = 128, Rating = 8.0 },
new Movie { Id = 19, Title = "The Grand Budapest Hotel", Description = "A fastidious concierge and his protégé dash through a caper over a priceless painting.", RuntimeMins = 100, Rating = 8.1 },
new Movie { Id = 20, Title = "Get Out", Description = "A weekend visit unravels into a sharp, unsettling examination of control and identity.", RuntimeMins = 104, Rating = 7.8 }
];
}
Loading