Add filtering, sorting and date-range parameters to the audit log query endpoint
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 42/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- nodejs, typescript
Research direction
Start with query() and fetchForExport in src/infrastructure/audit/audit-log.service.ts, and read QueryAuditLogDto to see its current validators. Check closed issue #70 and database-index.service.ts before designing, since the issue asks for that. Done means the filters and deterministic sort work through the query builder, a migration in src/migrations/ adds the indexes, export gets the same filters, and tests in test/audit/provenance.e2e-spec.ts cover filtering, stable pagination and 400 validation errors.
Written by the indexing model from the issue text.
Description
Problem
src/infrastructure/audit/audit-log.service.ts:65-99 implements query(dto: QueryAuditLogDto) with only page, limit and a skip/take pair:
const limit = dto.limit ?? 100;
...
.skip((page - 1) * limit)
.take(limit);
There is no filtering by event type, actor, target entity, date range, or outcome — and no sorting, so results come back in whatever order the database returns. The export path (fetchForExport, line 107) has the same limitation with a dto.limit ?? 10000 default.
There are audit-related tests to build on: test/audit/provenance.e2e-spec.ts, and services at src/infrastructure/audit/audit-log.service.ts and provenance.service.ts.
Why it matters
An audit log is only useful if you can ask questions of it. Today the only query is "give me page N", so answering "what did user X do last Tuesday" means exporting pages and filtering client-side. That is both slow and impractical at the volumes an audit table accumulates — which is also why the export defaults to 10,000 rows with no ceiling.
There is also a closed issue #70, "Comprehensive Audit Log Search & Export", so this area has been worked on; check what it delivered before designing.
Suggested Direction
- Extend
QueryAuditLogDtowith typed, validated filters:eventType,actorId,entityType,entityId,from/to(ISO 8601), andsortBy/sortDirection. Use@IsEnum/@IsDateStringso the globalValidationPiperejects bad input with its existing structured 400 shape. - Build the query with TypeORM's query builder, composing
.where()clauses only for provided filters. Do not interpolate filter values into raw SQL — this table is the audit trail, and an injection here would be a serious finding. - Require a deterministic sort (
ORDER BYon the timestamp plus the primary key as a tiebreaker), otherwise pagination is unstable and rows can be skipped or repeated across pages. - Add composite indexes for the common filter combinations, via a proper migration under
src/migrations/. There is an existingdatabase-index.service.tsandnpm run migration:generateto use. - Apply the same filters to the export path, and clamp its default limit.
Constraints
- Filters must be parameterised, never string-interpolated.
- Adding indexes changes the schema — write a migration, do not rely on
synchronize. - Keep the existing
{ page, limit, total, totalPages }response shape so current clients keep working; add fields rather than changing it. - This is an append-only audit table — no update or delete operations should be added.
- Consider whether actors/actors' identifiers should be filterable by display value or only by id.
Acceptance Criteria
-
GET /audit(or the equivalent route) accepts typed filters and a deterministic sort. - A combined filter (date range + event type + actor) returns correct results.
- Invalid filter values return
400using the existing structured validation error shape. - No raw SQL interpolation is used for filter values.
- A migration adds the supporting indexes.
- The export path accepts the same filters and has a clamped default limit.
- Tests cover filtering, sorting stability across pages, and the validation failures.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 55
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SourceXXL/alian_structure-api
-
good first issue help wanted security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#266 ·
-
Parallelize the cache-warming loop in `cache-warming.service.ts` — warmers run strictly sequentiallyPossibly taken @syntaxsuuvam-spec claimed this 4 days ago. Opengood first issue performance
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#240 ·
-
documentation help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
SourceXXL/alian_structure-api#215 ·
-
good first issue refactor tooling
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
SourceXXL/alian_structure-api#199 ·
-
help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
SourceXXL/alian_structure-api#196 ·
All issues in SourceXXL/alian_structure-api
Similar issues
-
area:ui effort:S enhancement priority:P2
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
QuantumNous/new-api#7839 ·
Maintainers usually reply within 1 day
-
good first issue maintenance
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
dark-princezz/stellar-hooks#1010 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
interledger/rhyza#352 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day