diff --git a/pkg/notification/client.go b/pkg/notification/client.go index a4b02a1..a5738d7 100644 --- a/pkg/notification/client.go +++ b/pkg/notification/client.go @@ -304,6 +304,65 @@ func (c *Client) buildQueryParams(req *GetNotificationsRequest) string { return result } +// MarkSeen marks a notification as seen +func (c *Client) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) { + if c.config.EnableLogging && c.logger != nil { + c.logger.Debug("Marking notification as seen", map[string]interface{}{ + "notification_id": notificationID, + "base_url": c.config.BaseURL, + }) + } + + // Create HTTP request + url := fmt.Sprintf("%s/api/v1/notifications/%s/seen", c.config.BaseURL, notificationID) + httpReq, err := http.NewRequestWithContext(ctx, "PUT", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP request: %w", err) + } + + // Set headers + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("User-Agent", c.config.UserAgent) + + // Send request + resp, err := c.httpClient.Do(httpReq) + if err != nil { + return nil, fmt.Errorf("HTTP request failed: %w", err) + } + defer resp.Body.Close() + + // Read response body + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %w", err) + } + + // Handle non-2xx status codes + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + // Try to parse error response + var errorResp NotificationErrorResponse + if json.Unmarshal(body, &errorResp) == nil && errorResp.Error != "" { + return nil, MapHTTPError(resp.StatusCode, errorResp.Error) + } + return nil, MapHTTPError(resp.StatusCode, string(body)) + } + + // Parse success response + var markSeenResp MarkSeenResponse + if err := json.Unmarshal(body, &markSeenResp); err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + + if c.config.EnableLogging && c.logger != nil { + c.logger.Info("Notification marked as seen successfully", map[string]interface{}{ + "notification_id": notificationID, + "status": markSeenResp.Status, + }) + } + + return &markSeenResp, nil +} + // shouldRetry determines if a request should be retried based on the error func (c *Client) shouldRetry(err error) bool { switch e := err.(type) { diff --git a/pkg/notification/entities.go b/pkg/notification/entities.go index c5ba13a..74049f3 100644 --- a/pkg/notification/entities.go +++ b/pkg/notification/entities.go @@ -135,6 +135,8 @@ type NotificationItem struct { Status string `json:"status"` ScheduledAt int64 `json:"scheduled_at"` IsScheduled bool `json:"is_scheduled"` + Seen bool `json:"seen"` + SeenAt int64 `json:"seen_at"` } // NotificationListResponse represents the response from getting notifications list @@ -162,3 +164,13 @@ type GetNotificationsRequest struct { Page int `json:"page,omitempty" valid:"optional"` PerPage int `json:"per_page,omitempty" valid:"optional"` } + +// MarkSeenRequest represents the request for marking a notification as seen +type MarkSeenRequest struct { + NotificationID string `json:"notification_id" valid:"required"` +} + +// MarkSeenResponse represents the response from marking a notification as seen +type MarkSeenResponse struct { + Status string `json:"status"` +} diff --git a/pkg/notification/interfaces.go b/pkg/notification/interfaces.go index 627f411..8cde4cd 100644 --- a/pkg/notification/interfaces.go +++ b/pkg/notification/interfaces.go @@ -24,6 +24,9 @@ type NotificationService interface { // GetNotifications retrieves a list of notifications GetNotifications(ctx context.Context, req *GetNotificationsRequest) (*NotificationListResponse, error) + // MarkSeen marks a notification as seen + MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) + // Health checks if the notification service is available Health(ctx context.Context) error diff --git a/pkg/notification/sdk.go b/pkg/notification/sdk.go index 0ff12fd..7c6eab2 100644 --- a/pkg/notification/sdk.go +++ b/pkg/notification/sdk.go @@ -79,6 +79,11 @@ func (s *SDK) GetNotifications(ctx context.Context, req *GetNotificationsRequest return s.service.GetNotifications(ctx, req) } +// MarkSeen marks a notification as seen +func (s *SDK) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) { + return s.service.MarkSeen(ctx, notificationID) +} + // NewBuilder creates a new notification builder for fluent API usage func (s *SDK) NewBuilder() Builder { return s.service.(*Service).NewBuilder() @@ -149,6 +154,12 @@ func (s *SDK) GetNotificationsByStatus(ctx context.Context, status string, page, return s.GetNotifications(ctx, req) } +// QuickMarkSeen marks a notification as seen (convenience method) +func (s *SDK) QuickMarkSeen(ctx context.Context, notificationID string) error { + _, err := s.MarkSeen(ctx, notificationID) + return err +} + // Batch operations for sending multiple notifications // BatchRequest represents a batch notification request diff --git a/pkg/notification/service.go b/pkg/notification/service.go index d506db0..c1bf65c 100644 --- a/pkg/notification/service.go +++ b/pkg/notification/service.go @@ -109,6 +109,11 @@ func (s *Service) GetNotifications(ctx context.Context, req *GetNotificationsReq return s.client.GetNotifications(ctx, req) } +// MarkSeen marks a notification as seen +func (s *Service) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) { + return s.client.MarkSeen(ctx, notificationID) +} + // Health checks if the notification service is available func (s *Service) Health(ctx context.Context) error { // Create a simple test request to check service availability