Skip to content

Commit ef3aa30

Browse files
authored
Update porfolio (#14)
1 parent 8283f8d commit ef3aa30

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

Sources/Grodt/Application/routes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ func routes(_ app: Application) async throws {
8484
.daily()
8585
.at(3, 0)
8686
app.queues.add(LoggingJobEventDelegate(logger: app.logger))
87+
88+
let userTokenCleanerJob = UserTokenClearUpJob(userTokenClearing: UserTokenClearer(database: app.db))
89+
app.queues.schedule(userTokenCleanerJob)
90+
.hourly()
91+
8792
try app.queues.startScheduledJobs()
8893
try app.queues.startInProcessJobs()
8994
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Vapor
2+
import Queues
3+
4+
struct UserTokenClearUpJob: AsyncScheduledJob, @unchecked Sendable {
5+
private let userTokenClearer: UserTokenClearing
6+
7+
init(userTokenClearing: UserTokenClearing) {
8+
self.userTokenClearer = userTokenClearing
9+
}
10+
11+
func run(context: Queues.QueueContext) async throws {
12+
try await userTokenClearer.clearExpiredTokens()
13+
}
14+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Fluent
2+
import Foundation
3+
4+
protocol UserTokenClearing {
5+
func clearExpiredTokens() async throws
6+
}
7+
8+
class UserTokenClearer: UserTokenClearing {
9+
private let database: Database
10+
11+
init(database: Database) {
12+
self.database = database
13+
}
14+
15+
func clearExpiredTokens() async throws {
16+
let allTokens = try await UserToken.query(on: database).all()
17+
let expiredTokens = allTokens.filter { !$0.isValid }
18+
for token in expiredTokens {
19+
try await token.delete(on: database)
20+
}
21+
}
22+
}

Sources/Grodt/Controllers/PortfoliosController.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct PortfoliosController: RouteCollection {
2626

2727
portfolios.group(":id") { portfolio in
2828
portfolio.get(use: portfolioDetail)
29+
portfolio.put(use: update)
2930
portfolio.delete(use: delete)
3031

3132
portfolio.group("historicalPerformance") { pref in
@@ -77,6 +78,31 @@ struct PortfoliosController: RouteCollection {
7778
return try await dataMapper.portfolio(from: portfolio)
7879
}
7980

81+
func update(req: Request) async throws -> PortfolioDTO {
82+
let id = try req.requiredID()
83+
guard let userID = req.auth.get(User.self)?.id else {
84+
throw Abort(.badRequest)
85+
}
86+
87+
let updateDTO = try req.content.decode(UpdatePortfolioRequestDTO.self)
88+
89+
guard var portfolio = try await portfolioRepository.portfolio(for: userID, with: id) else {
90+
throw Abort(.notFound)
91+
}
92+
93+
portfolio.name = updateDTO.name
94+
95+
if portfolio.currency.code != updateDTO.currency {
96+
guard let newCurrency = try await currencyRepository.currency(for: updateDTO.currency) else {
97+
throw Abort(.badRequest)
98+
}
99+
portfolio.currency = newCurrency
100+
}
101+
102+
let updatedPortfolio = try await portfolioRepository.update(portfolio)
103+
return try await dataMapper.portfolio(from: updatedPortfolio)
104+
}
105+
80106
func delete(req: Request) async throws -> HTTPStatus {
81107
let id = try req.requiredID()
82108

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Foundation
2+
3+
struct UpdatePortfolioRequestDTO: Codable {
4+
let name: String
5+
let currency: String
6+
}

Sources/Grodt/Persistency/Repositories/PortfolioRepository.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ protocol PortfolioRepository {
55
func allPortfolios(for userID: User.IDValue) async throws -> [Portfolio]
66
func portfolio(for userID: User.IDValue, with id: Portfolio.IDValue) async throws -> Portfolio?
77
func create(_ portfolio: Portfolio) async throws -> Portfolio
8+
func update(_ portfolio: Portfolio) async throws -> Portfolio
89
func delete(for userID: User.IDValue, with id: Portfolio.IDValue) async throws
10+
911
func historicalPerformance(with id: Portfolio.IDValue) async throws -> HistoricalPortfolioPerformance
1012
func updateHistoricalPerformance(_ historicalPerformance: HistoricalPortfolioPerformance) async throws
1113
func createHistoricalPerformance(_ historicalPerformance: HistoricalPortfolioPerformance) async throws
@@ -54,6 +56,20 @@ class PostgresPortfolioRepository: PortfolioRepository {
5456
return portfolioWithTransactions
5557
}
5658

59+
func update(_ portfolio: Portfolio) async throws -> Portfolio {
60+
try await portfolio.save(on: database)
61+
62+
guard let updatedPortfolio = try await Portfolio.query(on: database)
63+
.filter(\Portfolio.$id == portfolio.id!)
64+
.with(\.$transactions)
65+
.with(\.$historicalPerformance)
66+
.first() else {
67+
throw FluentError.noResults
68+
}
69+
70+
return updatedPortfolio
71+
}
72+
5773
func delete(for userID: User.IDValue, with id: Portfolio.IDValue) async throws {
5874
guard let portfolio = try await self.portfolio(for: userID, with: id) else {
5975
throw FluentError.noResults

0 commit comments

Comments
 (0)