scaffolding hermes flow and audit logging
This commit is contained in:
@@ -25,4 +25,34 @@ final class HermesAnalyticsClient: ObservableObject, AnalyticsTracking {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func flush(using repository: HermesRepository) async {
|
||||
guard repository.currentSession != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
let pendingEvents = trackedEvents
|
||||
guard !pendingEvents.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
try await repository.submitAnalyticsBatch(
|
||||
HermesAnalyticsBatchRequest(
|
||||
events: pendingEvents.map { event in
|
||||
HermesAnalyticsEventInput(
|
||||
eventName: event.event,
|
||||
occurredAt: event.timestamp,
|
||||
attributes: event.attributes.map { HermesAnalyticsAttributeInput(key: $0.key, value: $0.value) }
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
let deliveredIds = Set(pendingEvents.map(\.id))
|
||||
trackedEvents.removeAll { deliveredIds.contains($0.id) }
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ final class LocalizationStore: ObservableObject {
|
||||
return value
|
||||
}
|
||||
|
||||
func localeName(for targetLocaleCode: String, displayLocaleCode: String? = nil) -> String {
|
||||
let key = Self.normalize(targetLocaleCode) == "sv" ? "locale_swedish" : "locale_english"
|
||||
return string(for: key, localeCode: displayLocaleCode ?? localeCode)
|
||||
}
|
||||
|
||||
private func fallbackString(for key: String, localeCode: String) -> String {
|
||||
guard localeCode != Self.fallbackLocaleCode else {
|
||||
return key
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import AVKit
|
||||
import SwiftUI
|
||||
|
||||
struct StudyVideoPlayerView: View {
|
||||
struct HermesVideoPlayerView: View {
|
||||
@ObservedObject var coordinator: PlayerCoordinator
|
||||
|
||||
var body: some View {
|
||||
@@ -9,13 +9,15 @@ final class PlayerCoordinator: ObservableObject {
|
||||
@Published var isPlaying = false
|
||||
@Published var playbackPositionMs: Int = 0
|
||||
|
||||
init(previewURL: URL = URL(string: "https://cdn.example.com/hermes/sample-event/master.m3u8")!) {
|
||||
self.player = AVPlayer(url: previewURL)
|
||||
init() {
|
||||
self.player = AVPlayer()
|
||||
self.player.actionAtItemEnd = .pause
|
||||
}
|
||||
|
||||
func prepareForPreview() {
|
||||
player.seek(to: .zero)
|
||||
func prepareForPreview(url: URL, startTimeMs: Int = 0) {
|
||||
player.replaceCurrentItem(with: AVPlayerItem(url: url))
|
||||
let startTime = CMTime(seconds: Double(startTimeMs) / 1_000.0, preferredTimescale: 1_000)
|
||||
player.seek(to: startTime)
|
||||
player.play()
|
||||
isPlaying = true
|
||||
}
|
||||
@@ -30,8 +32,7 @@ final class PlayerCoordinator: ObservableObject {
|
||||
isPlaying = false
|
||||
}
|
||||
|
||||
func restart() {
|
||||
player.seek(to: .zero)
|
||||
play()
|
||||
func restart(url: URL, startTimeMs: Int = 0) {
|
||||
prepareForPreview(url: url, startTimeMs: startTimeMs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ struct HermesAPIClient {
|
||||
try await send(path: "api/v1/session/start", method: "POST", body: payload)
|
||||
}
|
||||
|
||||
func health() async throws -> HermesHealthResponse {
|
||||
try await send(path: "health")
|
||||
}
|
||||
|
||||
func endSession() async throws -> HermesSessionResponse {
|
||||
try await send(path: "api/v1/session/end", method: "POST")
|
||||
}
|
||||
|
||||
@@ -23,6 +23,17 @@ struct HermesSessionResponse: Codable {
|
||||
var devicePlatform: String
|
||||
}
|
||||
|
||||
struct HermesHealthResponse: Codable {
|
||||
var status: String
|
||||
var serviceName: String
|
||||
var environment: String
|
||||
var version: String
|
||||
var uptimeMs: Int
|
||||
var serverTime: Date
|
||||
var databaseReady: Bool
|
||||
var redisReady: Bool
|
||||
}
|
||||
|
||||
struct HermesEvent: Codable {
|
||||
var id: UUID
|
||||
var sportType: String
|
||||
@@ -94,6 +105,22 @@ struct HermesEventManifest: Codable {
|
||||
var markets: [HermesMarket]
|
||||
}
|
||||
|
||||
struct HermesRound: Codable {
|
||||
var event: HermesEvent
|
||||
var media: HermesEventMedia
|
||||
var market: HermesMarket
|
||||
var oddsVersion: HermesOddsVersion
|
||||
var settlement: HermesSettlement
|
||||
}
|
||||
|
||||
struct HermesRound: Codable {
|
||||
var event: HermesEvent
|
||||
var media: HermesEventMedia
|
||||
var market: HermesMarket
|
||||
var oddsVersion: HermesOddsVersion
|
||||
var settlement: HermesSettlement
|
||||
}
|
||||
|
||||
struct HermesBetIntentRequest: Codable {
|
||||
var sessionId: UUID
|
||||
var eventId: UUID
|
||||
|
||||
Reference in New Issue
Block a user