Skip to content

Commit 8496133

Browse files
committed
feat: added origin filtering on /api/logs
1 parent 9ae9884 commit 8496133

12 files changed

Lines changed: 256 additions & 7 deletions

File tree

.validaterc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"parameters": {
1919
"no_parameter_description": "error",
2020
"param_name_case_convention": [
21-
"error",
21+
"warning",
2222
"lower_snake_case"
2323
],
2424
"invalid_type_format_pair": "error",

lib/database/adapters/LogAdapter.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class LogAdapter {
3030
title: databaseObject.title,
3131
creationTime: new Date(databaseObject.createdAt).getTime(),
3232
tags: [`Tag${databaseObject.id}`, `Tag${++databaseObject.id}`],
33+
origin: databaseObject.origin,
3334
content: [
3435
{ content: 'Batman wrote this...', sender: 'Batman' },
3536
{ content: 'Nightwing wrote this...', sender: 'Nightwing' },

lib/database/repositories/LogRepository.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ class LogRepository {
3030
/**
3131
* Returns all entities.
3232
*
33+
* @param {Object} queryBuilder The QueryBuilder to use.
3334
* @returns {Promise} Promise object representing the full mock data
3435
*/
35-
async findAll() {
36-
return Log.findAll().map(LogAdapter.toEntity);
36+
async findAll(queryBuilder) {
37+
return Log.findAll(queryBuilder.toImplementation()).map(LogAdapter.toEntity);
3738
}
3839

3940
/**
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
/**
15+
* Sequelize implementation of the QueryBuilder.
16+
*/
17+
class QueryBuilder {
18+
/**
19+
* Creates a new `QueryBuilder` instance.
20+
*/
21+
constructor() {
22+
this.options = {};
23+
}
24+
25+
/**
26+
* Returns the implementation specific query.
27+
*
28+
* @returns {Object} Implementation specific query.
29+
*/
30+
toImplementation() {
31+
return this.options;
32+
}
33+
34+
/**
35+
* Adds a filter on the given column value pair.
36+
*
37+
* @param {*} column The target column.
38+
* @param {*} value The required value.
39+
* @returns {Object} The current QueryBuilder instance.
40+
*/
41+
where(column, value) {
42+
if (!this.options.where) {
43+
this.options.where = {};
44+
}
45+
46+
this.options.where[column] = value;
47+
return this;
48+
}
49+
}
50+
51+
module.exports = QueryBuilder;

lib/database/utilities/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
* or submit itself to any jurisdiction.
1212
*/
1313

14+
const QueryBuilder = require('./QueryBuilder');
1415
const TransactionHelper = require('./TransactionHelper');
1516

1617
module.exports = (sequelize) => ({
18+
QueryBuilder,
1719
TransactionHelper: TransactionHelper(sequelize),
1820
});

lib/domain/dtos/GetAllLogsDto.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright CERN and copyright holders of ALICE O2. This software is
4+
* distributed under the terms of the GNU General Public License v3 (GPL
5+
* Version 3), copied verbatim in the file "COPYING".
6+
*
7+
* See http://alice-o2.web.cern.ch/license for full licensing information.
8+
*
9+
* In applying this license CERN does not waive the privileges and immunities
10+
* granted to it by virtue of its status as an Intergovernmental Organization
11+
* or submit itself to any jurisdiction.
12+
*/
13+
14+
const { attributes } = require('structure');
15+
16+
const FilterDto = attributes({
17+
origin: {
18+
type: String,
19+
equal: ['human', 'process'],
20+
},
21+
})(class FilterDto {});
22+
23+
const QueryDto = attributes({
24+
filter: FilterDto,
25+
})(class QueryDto {});
26+
27+
const GetAllLogsDto = attributes({
28+
query: QueryDto,
29+
})(class GetAllLogsDto {});
30+
31+
module.exports = GetAllLogsDto;

lib/domain/dtos/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
*/
1313

1414
const CreateLogDto = require('./CreateLogDto');
15+
const GetAllLogsDto = require('./GetAllLogsDto');
1516
const GetLogDto = require('./GetLogDto');
1617

1718
module.exports = {
1819
CreateLogDto,
20+
GetAllLogsDto,
1921
GetLogDto,
2022
};

lib/server/controllers/logs.controller.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313

1414
const { log: { CreateLogUseCase, GetAllLogsUseCase, GetLogUseCase } } = require('../../usecases');
15-
const { dtos: { CreateLogDto, GetLogDto } } = require('../../domain');
15+
const { dtos: { CreateLogDto, GetAllLogsDto, GetLogDto } } = require('../../domain');
1616

1717
/**
1818
* Create a new log
@@ -105,8 +105,23 @@ const getAttachment = (request, response, next) => {
105105
* @returns {undefined}
106106
*/
107107
const index = async (request, response, next) => {
108+
const getAllLogsDto = new GetAllLogsDto(request);
109+
const { valid, errors } = getAllLogsDto.validate();
110+
111+
if (!valid) {
112+
response.status(400).json({
113+
errors: errors.map((error) => ({
114+
status: '422',
115+
source: { pointer: `/data/attributes/${error.path.join('/')}` },
116+
title: 'Invalid Attribute',
117+
detail: error.message,
118+
})),
119+
});
120+
return;
121+
}
122+
108123
const logs = await new GetAllLogsUseCase()
109-
.execute();
124+
.execute(getAllLogsDto);
110125
response.status(200).json({
111126
data: logs,
112127
});

lib/usecases/log/GetAllLogsUseCase.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
LogRepository,
1717
},
1818
utilities: {
19+
QueryBuilder,
1920
TransactionHelper,
2021
},
2122
} = require('../../database');
@@ -27,10 +28,22 @@ class GetAllLogsUseCase {
2728
/**
2829
* Executes this use case.
2930
*
31+
* @param {Object} dto The GetAllLogs DTO which contains all request data.
3032
* @returns {Promise} Promise object represents the result of this use case.
3133
*/
32-
async execute() {
33-
return TransactionHelper.provide(() => LogRepository.findAll());
34+
async execute(dto = {}) {
35+
const queryBuilder = new QueryBuilder();
36+
const { query = {} } = dto;
37+
const { filter } = query;
38+
39+
if (filter) {
40+
const { origin } = filter;
41+
if (origin) {
42+
queryBuilder.where('origin', origin);
43+
}
44+
}
45+
46+
return TransactionHelper.provide(() => LogRepository.findAll(queryBuilder));
3447
}
3548
}
3649

spec/openapi.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,18 @@ paths:
2525
get:
2626
operationId: listLogs
2727
summary: List all logs
28+
parameters:
29+
- name: filter[origin]
30+
description: Filter logs by their origin
31+
in: query
32+
schema:
33+
type: string
34+
enum: [human, process]
2835
responses:
2936
'200':
3037
$ref: '#/components/responses/ArrayOfLogs'
38+
'400':
39+
$ref: '#/components/responses/BadRequest'
3140
tags:
3241
- log
3342
post:
@@ -134,6 +143,11 @@ components:
134143
$ref: '#/components/schemas/ArrayOfLogs'
135144
required:
136145
- data
146+
ArrayOfTags:
147+
description: A list of Tag objects.
148+
type: array
149+
items:
150+
$ref: '#/components/schemas/Tag'
137151
DeployInformation:
138152
description: Deploy information
139153
type: object
@@ -179,11 +193,24 @@ components:
179193
description: Describes an intervention or an event that happened.
180194
type: object
181195
properties:
196+
entryID:
197+
description: Id of the log.
198+
type: integer
199+
format: int64
182200
title:
183201
description: Title of the log.
184202
type: string
203+
origin:
204+
description: Type of creator.
205+
type: string
206+
enum: [human, process]
207+
tags:
208+
$ref: '#/components/schemas/ArrayOfTags'
185209
required:
210+
- entryID
186211
- title
212+
- origin
213+
- tags
187214
LogResponse:
188215
description: Response containing a single log.
189216
type: object
@@ -192,3 +219,6 @@ components:
192219
$ref: '#/components/schemas/Log'
193220
required:
194221
- data
222+
Tag:
223+
description: A label attached to something for the purpose of identification.
224+
type: string

0 commit comments

Comments
 (0)