feat: record audit events for watch progress and completion
This commit is contained in:
@@ -21,10 +21,10 @@ var Module = fx.Options(
|
|||||||
fx.Provide(
|
fx.Provide(
|
||||||
repository.NewPlaybackRepository,
|
repository.NewPlaybackRepository,
|
||||||
fx.Annotate(
|
fx.Annotate(
|
||||||
func(repo domain.PlaybackRepository, providers []domain.Provider, jikan *jikan.Client, episodeSvc domain.EpisodeService, proxyTokenKey string) domain.PlaybackService {
|
func(repo domain.PlaybackRepository, providers []domain.Provider, jikan *jikan.Client, episodeSvc domain.EpisodeService, auditSvc domain.AuditService, proxyTokenKey string) domain.PlaybackService {
|
||||||
return service.NewPlaybackService(repo, providers, jikan, episodeSvc, proxyTokenKey)
|
return service.NewPlaybackService(repo, providers, jikan, episodeSvc, auditSvc, proxyTokenKey)
|
||||||
},
|
},
|
||||||
fx.ParamTags(``, ``, ``, ``, ``),
|
fx.ParamTags(``, ``, ``, ``, ``, ``),
|
||||||
),
|
),
|
||||||
func(svc domain.PlaybackService, animeSvc domain.AnimeService) *handler.PlaybackHandler {
|
func(svc domain.PlaybackService, animeSvc domain.AnimeService) *handler.PlaybackHandler {
|
||||||
return handler.NewPlaybackHandler(svc, animeSvc)
|
return handler.NewPlaybackHandler(svc, animeSvc)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type playbackService struct {
|
|||||||
episodes domain.EpisodeService
|
episodes domain.EpisodeService
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
proxyTokenKey string
|
proxyTokenKey string
|
||||||
|
auditSvc domain.AuditService
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyTokenPayload struct {
|
type proxyTokenPayload struct {
|
||||||
@@ -40,8 +41,16 @@ type proxyTokenPayload struct {
|
|||||||
ExpiresAt int64 `json:"exp"`
|
ExpiresAt int64 `json:"exp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlaybackService(repo domain.PlaybackRepository, providers []domain.Provider, jikan *jikan.Client, episodes domain.EpisodeService, proxyTokenKey string) domain.PlaybackService {
|
func NewPlaybackService(repo domain.PlaybackRepository, providers []domain.Provider, jikan *jikan.Client, episodes domain.EpisodeService, auditSvc domain.AuditService, proxyTokenKey string) domain.PlaybackService {
|
||||||
return &playbackService{repo: repo, providers: providers, jikan: jikan, episodes: episodes, httpClient: &http.Client{Timeout: 10 * time.Second}, proxyTokenKey: proxyTokenKey}
|
return &playbackService{
|
||||||
|
repo: repo,
|
||||||
|
providers: providers,
|
||||||
|
jikan: jikan,
|
||||||
|
episodes: episodes,
|
||||||
|
auditSvc: auditSvc,
|
||||||
|
httpClient: &http.Client{Timeout: 10 * time.Second},
|
||||||
|
proxyTokenKey: proxyTokenKey,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *playbackService) SignProxyToken(targetURL, referer, scope string) (string, error) {
|
func (s *playbackService) SignProxyToken(targetURL, referer, scope string) (string, error) {
|
||||||
@@ -311,12 +320,21 @@ func (s *playbackService) CompleteAnime(ctx context.Context, userID string, anim
|
|||||||
UserID: userID,
|
UserID: userID,
|
||||||
AnimeID: animeID,
|
AnimeID: animeID,
|
||||||
})
|
})
|
||||||
return s.repo.SaveWatchProgress(ctx, db.SaveWatchProgressParams{
|
if err := s.repo.SaveWatchProgress(ctx, db.SaveWatchProgressParams{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
AnimeID: animeID,
|
AnimeID: animeID,
|
||||||
CurrentEpisode: sql.NullInt64{Valid: false},
|
CurrentEpisode: sql.NullInt64{Valid: false},
|
||||||
CurrentTimeSeconds: 0,
|
CurrentTimeSeconds: 0,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = s.auditSvc.Record(ctx, domain.AuditEvent{
|
||||||
|
UserID: userID,
|
||||||
|
Action: "watch_completed",
|
||||||
|
ResourceType: "anime",
|
||||||
|
ResourceID: strconv.FormatInt(animeID, 10),
|
||||||
})
|
})
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *playbackService) SaveProgress(ctx context.Context, userID string, animeID int64, episode int, timeSeconds float64) error {
|
func (s *playbackService) SaveProgress(ctx context.Context, userID string, animeID int64, episode int, timeSeconds float64) error {
|
||||||
@@ -328,7 +346,31 @@ func (s *playbackService) SaveProgress(ctx context.Context, userID string, anime
|
|||||||
CurrentTimeSeconds: timeSeconds,
|
CurrentTimeSeconds: timeSeconds,
|
||||||
DurationSeconds: sql.NullFloat64{Valid: false},
|
DurationSeconds: sql.NullFloat64{Valid: false},
|
||||||
})
|
})
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
metadataBytes, marshalErr := json.Marshal(struct {
|
||||||
|
Episode int `json:"episode"`
|
||||||
|
TimeSeconds float64 `json:"time_seconds"`
|
||||||
|
}{Episode: episode, TimeSeconds: timeSeconds})
|
||||||
|
if marshalErr == nil {
|
||||||
|
_ = s.auditSvc.Record(ctx, domain.AuditEvent{
|
||||||
|
UserID: userID,
|
||||||
|
Action: "watch_progress_saved",
|
||||||
|
ResourceType: "anime",
|
||||||
|
ResourceID: strconv.FormatInt(animeID, 10),
|
||||||
|
MetadataJSON: metadataBytes,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
_ = s.auditSvc.Record(ctx, domain.AuditEvent{
|
||||||
|
UserID: userID,
|
||||||
|
Action: "watch_progress_saved",
|
||||||
|
ResourceType: "anime",
|
||||||
|
ResourceID: strconv.FormatInt(animeID, 10),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *playbackService) UpsertSkipSegmentOverride(ctx context.Context, userID string, animeID int64, episode int, skipType string, startTime, endTime float64) error {
|
func (s *playbackService) UpsertSkipSegmentOverride(ctx context.Context, userID string, animeID int64, episode int, skipType string, startTime, endTime float64) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user