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

docs(api-spec): add report-api spec #11

Merged
merged 12 commits into from
Feb 7, 2024
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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).

## Usage
## Deployment
See the [ndb-setup repo](https://github.com/Aam-Digital/ndb-setup) for full deployment instructions.

To use this you need a running [CouchDB](https://docs.couchdb.org/en/stable/) and [structured query server (SQS)](https://neighbourhood.ie/products-and-services/structured-query-server).
Expand All @@ -14,3 +14,44 @@ The following variables might need to be configured in the `.env` file:
- `SCHEMA_CONFIG_ID` database ID of the document which holds the SQS schema (default `_design/sqlite:config`)
- `PORT` where the app should listen (default 3000)
- `SENTRY_DSN` for remote logging

-----
# API access to reports
Reports and their results are available for external services through the given API endpoints ([see OpenAPI specs](./docs/api-specs/reporting-api-v1.yaml)). Endpoints require a valid JWT access token, which can be fetched via OAuth2 client credential flow.

## Initial setup of an API integration
1. Request client_id and client_secret from server administrator (--> admin has to [create new client grant in Keycloak](https://www.keycloak.org/docs/latest/server_admin/#_oidc_clients))

![Keycloak Client Setup](docs/assets/keycloak-client-setup.png)

2. Get the realm of your instance (e.g. https://[your_realm].aam-digital.com). This is both the subdomain of systems hosted on aam-digital.com and the Keycloak Realm for authentication (case sensitive!).

## Access a report via API (after setup)

1. Get valid access token using your client secret:

```bash
curl -X "POST" "https://keycloak.aam-digital.net/realms/<your_realm>/protocol/openid-connect/token" \
-H 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \
--data-urlencode "client_id=<your_client_id>" \
--data-urlencode "client_secret=<your_client_secret>" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scopes=openid reports_read reports_write"
```
Check API docs for the required "scopes".
This returns a JWT access token required to provided as Bearer Token for any request to the API endpoints. Sample token:
```json
{
"access_token": "eyJhbGciOiJSUzI...",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "openid reports_read reports_write"
}
```

2. Request the all available reports: `GET /reports` (see OpenAPI specs for details)
3. Trigger the calculation of a reports data: `POST /report-calculation/<report-id>`
4. Get status of the report calculation: `GET /report-calculation/<calculation-id>`
5. Once the status shows the calculation is completed, get the actual result data: `GET /report-calculation/<calculation-id>/data`
252 changes: 252 additions & 0 deletions docs/api-specs/reporting-api-v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
openapi: 3.0.3
info:
title: Aam Digital - Reporting API
description: |-
API to manage reports that provide data calculated based on any entities of the Aam Digital system.
version: 1.0.0-alpha.1
servers:
- url: https://{customerId}.aam-digital.net/api/v1/reporting
description: Developer Instance for testing
variables:
customerId:
default: dev
description: Customer ID assigned by the service provider
tags:
- name: report

paths:
/report:
get:
security:
- development:
- reports_read
tags:
- report
summary: Return list of available Reports
responses:
200:
description: List of all available Reports the requester has access permissions to, empty array if no reports are available
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Report'
401:
description: If no valid access token

/report/{reportId}:
get:
security:
- development:
- reports_read
tags:
- report
summary: Return report metadata by ID
parameters:
- in: path
name: reportId
schema:
type: string
required: true
responses:
200:
description: Get details of a report, including details of the data structure (schema) this specific report's data has
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
404:
description: If the Report does not exist
401:
description: If the access token does not grant permission to this Report

/report-calculation/report/{reportId}:
get:
security:
- development:
- reports_read
tags:
- report
summary: Return all report calculations for a report
parameters:
- in: path
name: reportId
schema:
type: string
required: true
responses:
200:
description: List of metadata of all calculations triggered by any user (pending and completed)
sleidig marked this conversation as resolved.
Show resolved Hide resolved
content:
application/json:
schema:
$ref: '#/components/schemas/ReportCalculation'
401:
description: If the access token does not grant permission to this Report
404:
description: If report does not exist

post:
security:
- development:
- reports_write
tags:
- report
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
(CURRENTLY UNDER DEVELOPMENT) optionally receive status updates via a webhook if that has been set up for the authorized client
parameters:
- in: path
name: reportId
schema:
type: string
required: true
- in: query
name: from
description: start date for report period
schema:
type: string
format: date
- in: query
name: to
description: end date for report period
schema:
type: string
format: date
responses:
200:
description: Return calculation identifier, to be used to check status and result data
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
401:
description: If the access token does not grant permission to this Report

/report-calculation/{calculationId}:
get:
security:
- development:
- reports_read
tags:
- report
summary: Return metadata for a report calculation
parameters:
- in: path
name: calculationId
schema:
type: string
required: true
responses:
200:
description: Status and details of the given report calculation run
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ReportCalculation'
401:
description: If the access token does not grant permission to this Report
404:
description: If the calculation identifier does not exist

/report-calculation/{calculationId}/data:
get:
security:
- development:
- reports_read
tags:
- report
summary: Fetch actual report data for a specific calculation
parameters:
- in: path
name: calculationId
schema:
type: string
required: true
responses:
200:
description: The actual data that has been calculated by the calculation run. This matches the schema defined in the /report/id
content:
application/json:
schema:
$ref: '#/components/schemas/ReportData'
application/xml:
schema:
$ref: '#/components/schemas/ReportData'
404:
description: report data is not available yet (when either the calculation id is not valid or the calculation is still running)
401:
description: If the access token does not grant permission to this Report

components:
schemas:
Report:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
example: report_all_course_members
calculationPending:
type: boolean
schema:
$ref: '#/components/schemas/ReportSchema'

ReportSchema:
type: object
properties:
fields:
type: array
items:
type: object

ReportCalculation:
type: object
properties:
id:
type: string
format: uuid
start_date:
type: string
example: date
end_date:
type: string
example: date
nullable: true
status:
type: string
description: Current status of the run
enum:
- PENDING
- RUNNING
- FINISHED_SUCCESS
- FINISHED_ERROR

ReportData:
type: object
properties:
reportId:
type: string
format: uuid
data:
type: object

securitySchemes:
development:
type: oauth2
description: This API uses OAuth2 with the Client Credentials Flow
flows:
clientCredentials:
tokenUrl: https://keycloak.aam-digital.net/realms/TolaData/protocol/openid-connect/token
scopes:
reports_read: Read Report and ReportCalculation
reports_write: Trigger new ReportCalculation
Binary file added docs/assets/keycloak-client-setup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading