Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Notification endpoints #19

Merged
merged 20 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@ SENTRY_DSN=
PORT=
DATABASE_URL=http://127.0.0.1:5984
DATABASE_USER=admin
DATABASE_PASSWORD=admin
DATABASE_PASSWORD=docker
QUERY_URL=http://127.0.0.1:4984
SCHEMA_CONFIG_ID=_design/sqlite:config

CHANGES_POLL_INTERVAL=60000
CHANGES_POLL_INTERVAL=60000

REPORT_DATABASE_URL=http://127.0.0.1:5984
REPORT_DATABASE_NAME=report-calculation

COUCH_SQS_CLIENT_CONFIG_BASIC_AUTH_USER=admin
COUCH_SQS_CLIENT_CONFIG_BASIC_AUTH_PASSWORD=docker

NOTIFICATION_COUCH_DB_CLIENT_CONFIG_BASIC_AUTH_USER=admin
NOTIFICATION_COUCH_DB_CLIENT_CONFIG_BASIC_AUTH_PASSWORD=docker

CRYPTO_ENCRYPTION_SECRET=super-duper-secret
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Query Backend
# Query Back'end

sleidig marked this conversation as resolved.
Show resolved Hide resolved
This service allows to run SQL queries on the database.
In particular, this service allows users with limited permissions to see reports of aggregated statistics across all data (e.g. a supervisor could analyse reports without having access to possibly confidential details of participants or notes).
Expand Down
75 changes: 53 additions & 22 deletions docs/api-specs/reporting-api-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ servers:
default: dev
description: Customer ID assigned by the service provider
tags:
- name: report
- name: reporting
description: Access reports and their results and trigger one-time report calculations.
- name: notification
- name: notifications
description: Subscribe to continuous notification events whenever a report's result data changes due to users changing records in the Aam Digital application.

paths:
/report:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- report
- reporting
summary: Return list of available Reports
responses:
200:
Expand All @@ -47,9 +47,9 @@ paths:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- report
- reporting
summary: Return report metadata by ID
parameters:
- in: path
Expand Down Expand Up @@ -81,9 +81,9 @@ paths:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- report
- reporting
summary: Return all report calculations for a report
parameters:
- in: path
Expand Down Expand Up @@ -114,9 +114,9 @@ paths:
post:
security:
- development:
- reporting_write
- reporting_write
tags:
- report
- reporting
summary: Trigger a new report calculation run.
description: Trigger a new report calculation run. Check status of the asynchronous calculation via the /report-calculation endpoint
As an alternative to triggering a single report calculation, you can subscribe to receive
Expand Down Expand Up @@ -162,9 +162,9 @@ paths:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- report
- reporting
summary: Return metadata for a report calculation
parameters:
- in: path
Expand Down Expand Up @@ -198,9 +198,9 @@ paths:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- report
- reporting
summary: Fetch actual report data for a specific calculation
parameters:
- in: path
Expand Down Expand Up @@ -237,9 +237,9 @@ paths:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- notification
- notifications
summary: Return list of existing Webhooks for your authorized client
responses:
200:
Expand All @@ -262,14 +262,45 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
security:
- development:
- reporting_write
tags:
- notifications
summary: Subscribe to events for a specific Report
description: Register a webhook to be called for one or more notification subscriptions. To receive events, make calls to your webhookId's /subscribe endpoint.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookConfiguration'
responses:
200:
description: Webhook registered successfully, you can now register subscriptions
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
401:
description: If no valid access token
content:
application/json:
schema:
$ref: '#/components/schemas/Error'

/webhook/{webhookId}:
get:
security:
- development:
- reporting_read
- reporting_read
tags:
- notification
- notifications
summary: Return a specific Webhook
parameters:
- in: path
Expand Down Expand Up @@ -307,9 +338,9 @@ paths:
post:
security:
- development:
- reporting_write
- reporting_write
tags:
- notification
- notifications
summary: Subscribe to events for a specific Report
description: If you subscribe to a reportId, Aam Digital will continuously monitor the changes users
make in the application and check if they affect the results calculated by that report.
Expand Down Expand Up @@ -356,9 +387,9 @@ paths:
delete:
security:
- development:
- reporting_write
- reporting_write
tags:
- notification
- notifications
summary: Remove event subscription for a specific Report
parameters:
- in: path
Expand Down
12 changes: 0 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/config/app.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
COUCH_SQS_CLIENT_CONFIG:
BASE_URL: http://localhost:4984

tomwwinter marked this conversation as resolved.
Show resolved Hide resolved
NOTIFICATION:
COUCH_DB_CLIENT_CONFIG:
BASE_URL: http://localhost:5984
TARGET_DATABASE: notification-webhook
110 changes: 55 additions & 55 deletions src/couchdb/couch-db-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,57 @@ import { HttpService } from '@nestjs/axios';
import { AxiosHeaders } from 'axios';
import { CouchDbChangesResponse } from './dtos';

export class CouchDbClientConfig {
BASE_URL = '';
TARGET_DATABASE = '';
BASIC_AUTH_USER = '';
BASIC_AUTH_PASSWORD = '';
}

@Injectable()
export class CouchDbClient {
private readonly logger = new Logger(CouchDbClient.name);

constructor(private httpService: HttpService) {}

headDatabaseDocument(
changes(
databaseUrl: string,
databaseName: string,
sleidig marked this conversation as resolved.
Show resolved Hide resolved
documentId: string,
config?: any,
) {
): Observable<CouchDbChangesResponse> {
return this.httpService
.head(`${databaseUrl}/${databaseName}/${documentId}`, config)
.get<CouchDbChangesResponse>(
`${databaseUrl}/${databaseName}/_changes`,
config,
)
.pipe(
map((response) => {
return response.data;
}),
catchError((err) => {
this.handleError(err);
throw err;
}),
);
}

getDatabaseDocument<T>(
databaseUrl: string,
databaseName: string,
documentId: string,
config?: any,
): Observable<T> {
headDatabaseDocument(request: { documentId: string; config?: any }) {
return this.httpService.head(`${request.documentId}`, request.config).pipe(
catchError((err) => {
if (err.response.status !== 404) {
this.handleError(err);
}
throw err;
}),
);
}

getDatabaseDocument<T>(request: {
documentId: string;
config?: any;
}): Observable<T> {
return this.httpService
.get<T>(`${databaseUrl}/${databaseName}/${documentId}`, config)
.get<T>(`${request.documentId}`, request.config)
.pipe(
map((response) => {
return response.data;
Expand Down Expand Up @@ -64,21 +85,25 @@ export class CouchDbClient {
);
}

putDatabaseDocument<T>(
databaseUrl: string,
databaseName: string,
documentId: string,
body: any,
config?: any,
): Observable<T> {
return this.latestRef(databaseUrl, databaseName, documentId, config).pipe(
putDatabaseDocument<T>(request: {
documentId: string;
body: any;
config: any;
}): Observable<T> {
return this.latestRef({
documentId: request.documentId,
config: request.config,
}).pipe(
switchMap((rev) => {
if (rev) {
config.headers['If-Match'] = rev;
if (!request.config.headers) {
request.config.headers = {};
}
request.config.headers['If-Match'] = rev;
}

return this.httpService
.put<T>(`${databaseUrl}/${databaseName}/${documentId}`, body, config)
.put<T>(request.documentId, request.body, request.config)
.pipe(
map((response) => {
return response.data;
Expand All @@ -92,18 +117,14 @@ export class CouchDbClient {
);
}

private latestRef(
databaseUrl: string,
databaseName: string,
documentId: string,
config?: any,
): Observable<string | undefined> {
return this.headDatabaseDocument(
databaseUrl,
databaseName,
documentId,
config,
).pipe(
private latestRef(request: {
documentId: string;
config?: any;
}): Observable<string | undefined> {
return this.headDatabaseDocument({
documentId: request.documentId,
config: request.config,
}).pipe(
map((response): string | undefined => {
const headers = response.headers;
if (headers instanceof AxiosHeaders && headers.has('etag')) {
Expand All @@ -117,27 +138,6 @@ export class CouchDbClient {
}

private handleError(err: any) {
this.logger.debug(err);
}

changes(
databaseUrl: string,
databaseName: string,
config?: any,
): Observable<CouchDbChangesResponse> {
return this.httpService
.get<CouchDbChangesResponse>(
`${databaseUrl}/${databaseName}/_changes`,
config,
)
.pipe(
map((response) => {
return response.data;
}),
catchError((err) => {
this.handleError(err);
throw err;
}),
);
this.logger.error(err);
}
}
Loading
Loading