Refactoring

This commit is contained in:
Tara Wilson 2024-12-05 20:27:49 -05:00
parent 683085b5d3
commit 924cee4e0f
14 changed files with 130 additions and 44 deletions

View File

@ -0,0 +1,35 @@
using api.Interfaces;
using Microsoft.AspNetCore.Mvc;
using models.Response;
namespace api.Controllers;
/// <summary>
/// Endpoints for Ticket Scanning
/// </summary>
/// <param name="ticketManager">Injected Ticket Manager Service</param>
[ApiController]
[Route("[controller]")]
public class ScanController(ITicketManager ticketManager) : ControllerBase
{
/// <summary>
/// Searches for a ticket with a given ticketId and validates it against the event associated with it.
/// </summary>
/// <param name="ticketId">A string representing a GUID value</param>
/// <returns>Ticket Search Result</returns>
[HttpGet]
public ActionResult<TicketSearch> Get(Guid ticketId)
{
//TODO: Protect Endpoint
try
{
var result = ticketManager.SearchTicket(ticketId);
return Ok(result);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
}

View File

@ -62,19 +62,17 @@ public class TicketController(
} }
/// <summary> /// <summary>
/// Searches for a ticket with a given ticketId and validates it against the event associated with it. /// Gets the MintResponse for a saved ticket
/// </summary> /// </summary>
/// <param name="ticketId">A string representing a GUID value</param> /// <param name="ticketId">Ticket Id</param>
/// <returns>Ticket Search Result</returns> /// <returns></returns>
[HttpGet] [HttpGet]
public ActionResult<TicketSearch> Get(string ticketId) public ActionResult<MintResponse> Get(Guid ticketId)
{ {
//TODO: Protect Endpoint
try try
{ {
var result = ticketManager.SearchTicket(ticketId); var response = ticketManager.GetMintResponse(ticketId);
return Ok(result); return Ok(response);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -7,5 +7,6 @@ public interface ITicketManager
{ {
void SaveMintedTicket(Ticket ticket); void SaveMintedTicket(Ticket ticket);
TicketSearch SearchTicket(string ticketId); TicketSearch SearchTicket(Guid ticketId);
MintResponse GetMintResponse(Guid ticketId);
} }

View File

@ -0,0 +1,8 @@
@api_HostAddress = http://localhost:5168
@ticketId = fe21c683-b607-4da7-8e9b-76b199a4b76c
###
GET {{api_HostAddress}}/scan?ticketId={{ticketId}}
Accept: application/json
Content-Type: application/json

View File

@ -1,5 +1,5 @@
@api_HostAddress = http://localhost:5168 @api_HostAddress = http://localhost:5168
@ticketId = 59ae05ea-fd07-481a-9a6b-663444cc426d @ticketId = fe21c683-b607-4da7-8e9b-76b199a4b76c
@eventId = b9f4478b-701b-4223-9aaa-042b6f53b83a @eventId = b9f4478b-701b-4223-9aaa-042b6f53b83a
POST {{api_HostAddress}}/ticket POST {{api_HostAddress}}/ticket

View File

@ -13,7 +13,7 @@ public class TicketManager : ITicketManager
new data.Events.AddTicket().Execute(ticket.Id, ticket.EventId); new data.Events.AddTicket().Execute(ticket.Id, ticket.EventId);
} }
public TicketSearch SearchTicket(string ticketId) public TicketSearch SearchTicket(Guid ticketId)
{ {
var ticket = new data.Tickets.Find().Execute(ticketId); var ticket = new data.Tickets.Find().Execute(ticketId);
@ -38,6 +38,22 @@ public class TicketManager : ITicketManager
return result; return result;
} }
public MintResponse GetMintResponse(Guid ticketId)
{
var ticket = new data.Tickets.Find().Execute(ticketId);
if (ticket == null)
{
throw new Exception("Ticket not found");
}
return new MintResponse()
{
QrCode = ticket.QrCode,
Type = ticket.Type,
};
}
private static TicketValidity DetermineValidity(Event @event) private static TicketValidity DetermineValidity(Event @event)
{ {
if (@event.Date < DateTime.Now) if (@event.Date < DateTime.Now)

View File

@ -5,11 +5,11 @@ namespace data.Tickets;
public class Find public class Find
{ {
public Ticket Execute(string ticketId) public Ticket Execute(Guid ticketId)
{ {
var database = MongoFactory.GetDatabase(); var database = MongoFactory.GetDatabase();
var collection = database.GetCollection<Ticket>("tickets"); var collection = database.GetCollection<Ticket>("tickets");
var filter = Builders<Ticket>.Filter.Eq("Id", ticketId); var filter = Builders<Ticket>.Filter.Eq(t => t.Id, ticketId);
return collection.Find(filter).FirstOrDefault(); return collection.Find(filter).FirstOrDefault();
} }
} }

View File

@ -4,6 +4,6 @@ namespace models.Response;
public class MintResponse public class MintResponse
{ {
public required string QrCode {get;set;} public required string QrCode { get; set; }
public TicketType Type { get; set; } public TicketType Type { get; set; }
} }

View File

@ -1,6 +1,7 @@
import { Component } from '@angular/core'; import {Component, inject} from '@angular/core';
import {ZXingScannerModule} from '@zxing/ngx-scanner'; import {ZXingScannerModule} from '@zxing/ngx-scanner';
import {ScanResultComponent} from '../../scan-result/scan-result.component'; import {ScanResultComponent} from '../../scan-result/scan-result.component';
import {ScanService} from '../../services/scan.service';
@Component({ @Component({
selector: 'app-scan', selector: 'app-scan',
@ -10,9 +11,11 @@ import {ScanResultComponent} from '../../scan-result/scan-result.component';
}) })
export class ScanComponent { export class ScanComponent {
public hideScanner: boolean = false; public hideScanner: boolean = false;
private scan = inject(ScanService);
public onCodeResult(resultString: string): void { public onCodeResult(resultString: string): void {
this.hideScanner = false; this.hideScanner = false;
this.scan.searchTicket(resultString);
console.log(resultString); console.log(resultString);
} }
} }

View File

@ -1,7 +1,7 @@
import {Component, inject} from '@angular/core'; import {Component, inject} from '@angular/core';
import {TicketService} from '../services/ticket.service';
import {TicketValidity} from '../../models/enums/ticket-validity.enum'; import {TicketValidity} from '../../models/enums/ticket-validity.enum';
import {TicketTypeEnum} from '../../models/enums/ticket-type.enum'; import {TicketTypeEnum} from '../../models/enums/ticket-type.enum';
import {ScanService} from '../services/scan.service';
@Component({ @Component({
selector: 'app-scan-result', selector: 'app-scan-result',
@ -10,9 +10,9 @@ import {TicketTypeEnum} from '../../models/enums/ticket-type.enum';
styleUrl: './scan-result.component.scss' styleUrl: './scan-result.component.scss'
}) })
export class ScanResultComponent { export class ScanResultComponent {
private ticket = inject(TicketService); private scan = inject(ScanService);
public ticketValidity = this.ticket.ticketValid$; public ticketValidity = this.scan.ticketValid$;
public ticketType = this.ticket.ticketType$; public ticketType = this.scan.ticketType$;
protected readonly TicketValidity = TicketValidity; protected readonly TicketValidity = TicketValidity;
protected readonly TicketTypeEnum = TicketTypeEnum; protected readonly TicketTypeEnum = TicketTypeEnum;
} }

View File

@ -1,7 +1,7 @@
import {HttpHeaders, HttpParams} from '@angular/common/http'; import {HttpHeaders, HttpParams} from '@angular/common/http';
export class ApiUtils { export class ApiUtils {
public setHttpRequestOptions(params?: any): any { protected setHttpRequestOptions(params?: any): any {
let headers: HttpHeaders = new HttpHeaders(); let headers: HttpHeaders = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json'); headers = headers.set('Content-Type', 'application/json');

View File

@ -0,0 +1,41 @@
import {inject, Injectable, signal, WritableSignal} from '@angular/core';
import {TicketValidity} from '../../models/enums/ticket-validity.enum';
import {TicketTypeEnum} from '../../models/enums/ticket-type.enum';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../environments/environment';
import {Endpoints} from '../../models/endpoints';
import {TicketSearch} from '../../models/response/ticket-search';
import {catchError, map, of} from 'rxjs';
import {ApiUtils} from './api-utils';
@Injectable({
providedIn: 'root'
})
export class ScanService extends ApiUtils {
public ticketValid$: WritableSignal<TicketValidity> = signal(TicketValidity.Null);
public ticketType$: WritableSignal<TicketTypeEnum> = signal(TicketTypeEnum.Null);
private httpClient = inject(HttpClient);
constructor() {
super();
}
public searchTicket(ticketId: string): void {
const options = this.setHttpRequestOptions();
const url = environment.apiBase + Endpoints.TICKET_SEARCH(ticketId);
this.httpClient.get<TicketSearch>(url, options)
.pipe(
map((response: any) => response.body),
catchError(error => {
console.log(error);
return of(undefined);
})
).subscribe((res: TicketSearch) => {
if (res !== undefined) {
this.ticketType$.set(res.ticketType);
this.ticketValid$.set(res.ticketValidity)
}
});
}
}

View File

@ -6,8 +6,6 @@ import {MintResponse} from '../../models/response/mint-response';
import {Endpoints} from '../../models/endpoints'; import {Endpoints} from '../../models/endpoints';
import {MintRequest} from '../../models/request/mint-request'; import {MintRequest} from '../../models/request/mint-request';
import {ApiUtils} from './api-utils'; import {ApiUtils} from './api-utils';
import {TicketValidity} from '../../models/enums/ticket-validity.enum';
import {TicketTypeEnum} from '../../models/enums/ticket-type.enum';
import {TicketSearch} from '../../models/response/ticket-search'; import {TicketSearch} from '../../models/response/ticket-search';
@Injectable({ @Injectable({
@ -15,8 +13,6 @@ import {TicketSearch} from '../../models/response/ticket-search';
}) })
export class TicketService extends ApiUtils { export class TicketService extends ApiUtils {
public dataSignal$: WritableSignal<string> = signal(''); public dataSignal$: WritableSignal<string> = signal('');
public ticketValid$: WritableSignal<TicketValidity> = signal(TicketValidity.Null);
public ticketType$: WritableSignal<TicketTypeEnum> = signal(TicketTypeEnum.Null);
private httpClient = inject(HttpClient); private httpClient = inject(HttpClient);
constructor() { constructor() {
@ -40,23 +36,4 @@ export class TicketService extends ApiUtils {
} }
}); });
} }
public searchTicket(ticketId: string): void {
const options = this.setHttpRequestOptions();
const url = environment.apiBase + Endpoints.TICKET_SEARCH(ticketId);
this.httpClient.get<TicketSearch>(url, options)
.pipe(
map((response: any) => response.body),
catchError(error => {
console.log(error);
return of(undefined);
})
).subscribe((res: TicketSearch) => {
if (res !== undefined) {
this.ticketType$.set(res.ticketType);
this.ticketValid$.set(res.ticketValidity)
}
});
}
} }

View File

@ -2,9 +2,16 @@ export class Endpoints {
/* Ticket Routes */ /* Ticket Routes */
public static readonly TICKET: string = 'ticket'; public static readonly TICKET: string = 'ticket';
public static QR_CODE_SEARCH(ticketId: string): string {
return `${Endpoints.TICKET}?ticketId=${ticketId}`;
}
/* Scan Routes */
public static readonly SCAN: string = 'scan';
/* Calculated Routes */ /* Calculated Routes */
public static TICKET_SEARCH(ticketId: string): string { public static TICKET_SEARCH(ticketId: string): string {
return `${Endpoints.TICKET}?ticketId=${ticketId}`; return `${Endpoints.SCAN}?ticketId=${ticketId}`;
} }
/* Event Routes */ /* Event Routes */