From a4ff326625d062ae5eb6e3cc419a34003b7db0a9 Mon Sep 17 00:00:00 2001 From: jamesread Date: Sun, 11 Jan 2026 01:48:17 +0000 Subject: [PATCH] chore: calendar logging fixes --- proto/olivetin/api/v1/olivetin.proto | 1 + service/gen/olivetin/api/v1/olivetin.pb.go | 14 +++++++++++-- service/internal/api/api.go | 6 +++++- service/internal/executor/executor.go | 24 +++++++++++++++++++--- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/proto/olivetin/api/v1/olivetin.proto b/proto/olivetin/api/v1/olivetin.proto index 07032c5..dc35ebc 100644 --- a/proto/olivetin/api/v1/olivetin.proto +++ b/proto/olivetin/api/v1/olivetin.proto @@ -118,6 +118,7 @@ message StartActionByGetAndWaitResponse { message GetLogsRequest{ int64 start_offset = 1; + string date_filter = 2; // Optional date filter in YYYY-MM-DD format }; message LogEntry { diff --git a/service/gen/olivetin/api/v1/olivetin.pb.go b/service/gen/olivetin/api/v1/olivetin.pb.go index e49869b..776b4a0 100644 --- a/service/gen/olivetin/api/v1/olivetin.pb.go +++ b/service/gen/olivetin/api/v1/olivetin.pb.go @@ -1088,6 +1088,7 @@ func (x *StartActionByGetAndWaitResponse) GetLogEntry() *LogEntry { type GetLogsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` StartOffset int64 `protobuf:"varint,1,opt,name=start_offset,json=startOffset,proto3" json:"start_offset,omitempty"` + DateFilter string `protobuf:"bytes,2,opt,name=date_filter,json=dateFilter,proto3" json:"date_filter,omitempty"` // Optional date filter in YYYY-MM-DD format unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1129,6 +1130,13 @@ func (x *GetLogsRequest) GetStartOffset() int64 { return 0 } +func (x *GetLogsRequest) GetDateFilter() string { + if x != nil { + return x.DateFilter + } + return "" +} + type LogEntry struct { state protoimpl.MessageState `protogen:"open.v1"` DatetimeStarted string `protobuf:"bytes,1,opt,name=datetime_started,json=datetimeStarted,proto3" json:"datetime_started,omitempty"` @@ -3922,9 +3930,11 @@ const file_olivetin_api_v1_olivetin_proto_rawDesc = "" + "\x1eStartActionByGetAndWaitRequest\x12\x1b\n" + "\taction_id\x18\x01 \x01(\tR\bactionId\"Y\n" + "\x1fStartActionByGetAndWaitResponse\x126\n" + - "\tlog_entry\x18\x01 \x01(\v2\x19.olivetin.api.v1.LogEntryR\blogEntry\"3\n" + + "\tlog_entry\x18\x01 \x01(\v2\x19.olivetin.api.v1.LogEntryR\blogEntry\"T\n" + "\x0eGetLogsRequest\x12!\n" + - "\fstart_offset\x18\x01 \x01(\x03R\vstartOffset\"\xc8\x04\n" + + "\fstart_offset\x18\x01 \x01(\x03R\vstartOffset\x12\x1f\n" + + "\vdate_filter\x18\x02 \x01(\tR\n" + + "dateFilter\"\xc8\x04\n" + "\bLogEntry\x12)\n" + "\x10datetime_started\x18\x01 \x01(\tR\x0fdatetimeStarted\x12!\n" + "\faction_title\x18\x02 \x01(\tR\vactionTitle\x12\x16\n" + diff --git a/service/internal/api/api.go b/service/internal/api/api.go index 1d44fd8..a49a556 100644 --- a/service/internal/api/api.go +++ b/service/internal/api/api.go @@ -474,7 +474,11 @@ func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *connect.Request[apiv1.GetL } ret := &apiv1.GetLogsResponse{} - logEntries, paging := api.executor.GetLogTrackingIdsACL(api.cfg, user, req.Msg.StartOffset, api.cfg.LogHistoryPageSize) + dateFilter := "" + if req.Msg.DateFilter != "" { + dateFilter = req.Msg.DateFilter + } + logEntries, paging := api.executor.GetLogTrackingIdsACL(api.cfg, user, req.Msg.StartOffset, api.cfg.LogHistoryPageSize, dateFilter) for _, le := range logEntries { ret.Logs = append(ret.Logs, api.internalLogEntryToPb(le, user)) } diff --git a/service/internal/executor/executor.go b/service/internal/executor/executor.go index a42e8c7..70fcdc4 100644 --- a/service/internal/executor/executor.go +++ b/service/internal/executor/executor.go @@ -236,12 +236,22 @@ func isLogEntryAllowedByACL(cfg *config.Config, user *authpublic.AuthenticatedUs return acl.IsAllowedLogs(cfg, user, entry.Binding.Action) } -func (e *Executor) filterLogsByACL(cfg *config.Config, user *authpublic.AuthenticatedUser) []*InternalLogEntry { +func (e *Executor) filterLogsByACL(cfg *config.Config, user *authpublic.AuthenticatedUser, dateFilter string) []*InternalLogEntry { e.logmutex.RLock() defer e.logmutex.RUnlock() filtered := make([]*InternalLogEntry, 0, len(e.logsTrackingIdsByDate)) + var filterDate time.Time + var hasDateFilter bool + if dateFilter != "" { + parsedDate, err := time.Parse("2006-01-02", dateFilter) + if err == nil { + filterDate = parsedDate + hasDateFilter = true + } + } + for _, trackingId := range e.logsTrackingIdsByDate { entry := e.logs[trackingId] @@ -249,6 +259,13 @@ func (e *Executor) filterLogsByACL(cfg *config.Config, user *authpublic.Authenti continue } if isLogEntryAllowedByACL(cfg, user, entry) { + if hasDateFilter { + entryDate := entry.DatetimeStarted.UTC().Truncate(24 * time.Hour) + filterDateUTC := filterDate.UTC().Truncate(24 * time.Hour) + if !entryDate.Equal(filterDateUTC) { + continue + } + } filtered = append(filtered, entry) } } @@ -282,8 +299,9 @@ func paginateFilteredLogs(filtered []*InternalLogEntry, startOffset int64, pageC // GetLogTrackingIdsACL returns logs filtered by ACL visibility for the user and // paginated correctly based on the filtered set. -func (e *Executor) GetLogTrackingIdsACL(cfg *config.Config, user *authpublic.AuthenticatedUser, startOffset int64, pageCount int64) ([]*InternalLogEntry, *PagingResult) { - filtered := e.filterLogsByACL(cfg, user) +// dateFilter is optional and should be in YYYY-MM-DD format. If empty, no date filtering is applied. +func (e *Executor) GetLogTrackingIdsACL(cfg *config.Config, user *authpublic.AuthenticatedUser, startOffset int64, pageCount int64, dateFilter string) ([]*InternalLogEntry, *PagingResult) { + filtered := e.filterLogsByACL(cfg, user, dateFilter) return paginateFilteredLogs(filtered, startOffset, pageCount) }