fleet/server/activity/api/list_activities.go
Victor Lyuboslavsky 7deade8057
Activity bounded context: /api/latest/fleet/activities (2 of 2) (#38478)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #37806 

Removed `ds.ListActivities` from the legacy datastore and updated
code/tests to use the new activity bounded context instead.

The changes to `cron.go` and most changes to `mysql/activities_test.go`
will eventually be migrated to the activity bounded context. The current
changes are an intermediate step.

The issues tracked by https://github.com/fleetdm/fleet/issues/38234 will
be addressed in additional/parallel PRs shortly.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
  - Done in the previous PR

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Migrated activity retrieval from direct datastore calls to a
service-based architecture for improved maintainability and consistency.
* Enhanced system context handling for background automation tasks to
ensure proper authorization during scheduled operations.
* Streamlined activity recording for automated processes with dedicated
system identity tracking.

* **Tests**
* Updated test infrastructure with new helpers for activity service
integration across test suites.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ian Littman <iansltx@gmail.com>
2026-01-23 07:42:09 -06:00

72 lines
2.9 KiB
Go

// Package api provides the public API for the activity bounded context.
// External code should use this package to interact with activities.
package api
import (
"context"
"encoding/json"
"time"
)
// OrderDirection represents the sort direction for list queries.
type OrderDirection string
const (
OrderAscending OrderDirection = "asc"
OrderDescending OrderDirection = "desc"
)
type ListActivitiesService interface {
ListActivities(ctx context.Context, opt ListOptions) ([]*Activity, *PaginationMetadata, error)
}
// Activity represents a recorded activity in the audit log.
type Activity struct {
ID uint `json:"id,omitempty" db:"id"`
UUID string `json:"uuid,omitempty" db:"uuid"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
Type string `json:"type" db:"activity_type"`
ActorID *uint `json:"actor_id,omitempty" db:"user_id"`
ActorFullName *string `json:"actor_full_name,omitempty" db:"name"`
ActorEmail *string `json:"actor_email,omitempty" db:"user_email"`
ActorGravatar *string `json:"actor_gravatar,omitempty" db:"gravatar_url"`
ActorAPIOnly *bool `json:"actor_api_only,omitempty" db:"api_only"`
Streamed *bool `json:"-" db:"streamed"`
FleetInitiated bool `json:"fleet_initiated" db:"fleet_initiated"`
Details *json.RawMessage `json:"details" db:"details"`
}
// AuthzType implements the authorization type for activities.
func (a *Activity) AuthzType() string {
return "activity"
}
// ListOptions defines options for listing activities.
// Note: Query parameter decoding is handled by listOptionsFromRequest in the service layer,
// not via struct tags. This keeps the API package free of HTTP-specific concerns.
type ListOptions struct {
// Pagination
Page uint
PerPage uint
After string // Cursor-based pagination: start after this value (used with OrderKey)
// Sorting
OrderKey string // Field to order by (e.g., "created_at", "id")
OrderDirection OrderDirection // OrderAscending or OrderDescending
// Filters
ActivityType string // Filter by activity type
StartCreatedAt string // ISO date string, filter activities created after this time
EndCreatedAt string // ISO date string, filter activities created before this time
MatchQuery string // Search query for actor name and email
Streamed *bool // Filter by streamed status (nil = all, true = streamed only, false = not streamed only)
}
// PaginationMetadata contains pagination information for list responses.
type PaginationMetadata struct {
HasNextResults bool `json:"has_next_results"`
HasPreviousResults bool `json:"has_previous_results"`
// TotalResults is excluded from JSON responses to match legacy behavior.
// It can be used by server-side code but won't be sent to API clients.
TotalResults uint `json:"-"`
}