diff --git a/docker-compose.yml b/docker-compose.yml index 1aa5238d0ad..ac389b8f82a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -97,7 +97,7 @@ services: volumes: - "pgdata:/var/lib/postgresql/data" ports: - - "54322:5432" + - "5432:5432" environment: POSTGRES_USER: ${DB_USERNAME:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} @@ -119,7 +119,7 @@ services: volumes: - "pgdata-test:/var/lib/postgresql/data" ports: - - "5432:5432" + - "5433:5432" environment: POSTGRES_DB: openproject POSTGRES_USER: openproject diff --git a/docker/dev/backend/Dockerfile b/docker/dev/backend/Dockerfile index bf24d5171a4..88060437fc1 100644 --- a/docker/dev/backend/Dockerfile +++ b/docker/dev/backend/Dockerfile @@ -23,7 +23,12 @@ WORKDIR /home/$USER RUN apt-get update -qq && \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ - postgresql-client libffi7 libffi-dev + postgresql-client libffi7 libffi-dev curl + +# Setup node source and install nodejs. Needed for running certain scripts in backend container, +# as the `./scripts/api/validate_spec`. +RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - +RUN apt-get install -y nodejs COPY ./docker/dev/backend/scripts/setup /usr/sbin/setup COPY ./docker/dev/backend/scripts/run-app /usr/sbin/run-app diff --git a/docs/api/apiv3/components/schemas/attachments_by_post.yml b/docs/api/apiv3/components/schemas/attachments_by_post.yml deleted file mode 100644 index 8cb9eed5c37..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_post.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_post ---- {} diff --git a/docs/api/apiv3/components/schemas/attachments_by_post_model.yml b/docs/api/apiv3/components/schemas/attachments_by_post_model.yml deleted file mode 100644 index ac77d405900..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_post_model.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_postModel ---- {} diff --git a/docs/api/apiv3/components/schemas/attachments_by_wiki_page.yml b/docs/api/apiv3/components/schemas/attachments_by_wiki_page.yml deleted file mode 100644 index 398c2f7c1cc..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_wiki_page.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_wiki_page ---- {} diff --git a/docs/api/apiv3/components/schemas/attachments_by_wiki_page_model.yml b/docs/api/apiv3/components/schemas/attachments_by_wiki_page_model.yml deleted file mode 100644 index a26b035a101..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_wiki_page_model.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_wiki_pageModel ---- {} diff --git a/docs/api/apiv3/components/schemas/attachments_by_work_package.yml b/docs/api/apiv3/components/schemas/attachments_by_work_package.yml deleted file mode 100644 index 6ccfbed78b7..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_work_package.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_work_package ---- {} diff --git a/docs/api/apiv3/components/schemas/attachments_by_work_package_model.yml b/docs/api/apiv3/components/schemas/attachments_by_work_package_model.yml deleted file mode 100644 index 1200c89a231..00000000000 --- a/docs/api/apiv3/components/schemas/attachments_by_work_package_model.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Schema: Attachments_by_work_packageModel ---- {} diff --git a/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml b/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml index e9b0cb55a30..6d59d113724 100644 --- a/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml +++ b/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml @@ -16,9 +16,9 @@ allOf: allOf: - $ref: "./link.yml" - description: |- - This file links list + This file links collection - **Resource**: File_LinksModel + **Resource**: FileLinkCollectionReadModel _embedded: type: object required: diff --git a/docs/api/apiv3/components/schemas/list_notifications_model.yml b/docs/api/apiv3/components/schemas/list_notifications_model.yml deleted file mode 100644 index b5880c53932..00000000000 --- a/docs/api/apiv3/components/schemas/list_notifications_model.yml +++ /dev/null @@ -1,43 +0,0 @@ -# Schema: List_notificationsModel ---- -type: object -example: - _type: Collection - _embedded: - elements: - - _links: - readIAN: - href: "/api/v3/notifications/1/read_ian" - method: "post" - actor: - href: "/api/v3/users/2" - title: Peggie Feeney - activity: - href: "/api/v3/activities/1234" - project: - href: "/api/v3/projects/1" - title: Seeded Project - self: - href: "/api/v3/notifications/1" - _type: Notification - createdAt: "2021-07-20T08:32:18Z" - updatedAt: "2021-07-20T08:33:19Z" - id: 1 - reason: mentioned - subject: "You have been mentioned in Task #1234 An important task" - _links: - changeSize: - href: "/api/v3/notifications?offset=1&pageSize=%7Bsize%7D" - templated: true - jumpTo: - href: "/api/v3/notifications?offset=%7Boffset%7D&pageSize=2" - templated: true - nextByOffset: - href: "/api/v3/notifications?offset=2&pageSize=2" - self: - href: "/api/v3/notifications?offset=1&pageSize=2" - _type: Collection - count: 1 - offset: 1 - pageSize: 50 - total: 1 diff --git a/docs/api/apiv3/components/schemas/notification_collection_model.yml b/docs/api/apiv3/components/schemas/notification_collection_model.yml new file mode 100644 index 00000000000..1f3e3054dd2 --- /dev/null +++ b/docs/api/apiv3/components/schemas/notification_collection_model.yml @@ -0,0 +1,70 @@ +# Schema: NotificationCollectionModel +--- +allOf: + - $ref: './collection_model.yml' + - type: object + required: + - _links + - _embedded + properties: + _links: + type: object + required: + - self + properties: + self: + allOf: + - $ref: "./link.yml" + - description: |- + This notification collection + + **Resource**: NotificationCollectionModel + jumpTo: + allOf: + - $ref: "./link.yml" + - description: |- + The notification collection at another offset + + **Resource**: NotificationCollectionModel + changeSize: + allOf: + - $ref: "./link.yml" + - description: |- + The notification collection with another size + + **Resource**: NotificationCollectionModel + _embedded: + type: object + required: + - elements + properties: + elements: + type: array + items: + $ref: './notification_model.yml' + +example: + _type: Collection + count: 2 + total: 2 + offset: 1 + pageSize: 20 + _embedded: + elements: + - _hint: Notification resource shortened for brevity + id: 1 + readIAN: false + reason: mentioned + - _hint: Notification resource shortened for brevity + id: 2 + readIAN: false + reason: mentioned + _links: + self: + href: '/api/v3/notifications?offset=1&pageSize=20' + jumpTo: + href: '/api/v3/notifications?filters=%5B%5D&offset=%7Boffset%7D&pageSize=20' + templated: true + changeSize: + href: '/api/v3/notifications?filters=%5B%5D&offset=1&pageSize=%7Bsize%7D' + templated: true \ No newline at end of file diff --git a/docs/api/apiv3/components/schemas/notification_model.yml b/docs/api/apiv3/components/schemas/notification_model.yml index 2e9a537fe2e..22a1a1c6f64 100644 --- a/docs/api/apiv3/components/schemas/notification_model.yml +++ b/docs/api/apiv3/components/schemas/notification_model.yml @@ -2,65 +2,81 @@ --- type: object properties: + _type: + type: string + enum: + - Notification id: type: integer description: Notification id - readOnly: true - minimum: 0 - exclusiveMinimum: true - subject: - type: string - description: The subject of the notification - readOnly: true + minimum: 1 reason: type: string description: The reason for the notification (such as mentioned, involved, watched) - readOnly: true readIAN: type: boolean description: Whether the notification is marked as read - readOnly: true createdAt: type: string format: date-time description: The time the notification was created at - readOnly: true updatedAt: type: string format: date-time description: The time the notification was last updated - readOnly: true + _embedded: + type: object + required: + - actor + - project + - activity + - resource + properties: + actor: + $ref: './user_model.yml' + project: + $ref: './project_model.yml' + activity: + $ref: './activity_model.yml' + resource: + oneOf: + - $ref: './work_package_model.yml' _links: type: object required: - - self - - project - - actor + - self + - readIAN + - project + - actor + - activity + - resource properties: self: allOf: - - "$ref": "./link.yml" - - description: |- - This notification - - **Resource**: Notification - readOnly: true + - "$ref": "./link.yml" + - description: |- + This notification + + **Resource**: Notification + readIAN: + allOf: + - "$ref": "./link.yml" + - description: |- + Request to mark the notification as read. project: allOf: - - "$ref": "./link.yml" - - description: |- - The project the notification originated in - - **Resource**: Project - readOnly: true + - "$ref": "./link.yml" + - description: |- + The project the notification originated in + + **Resource**: Project actor: allOf: - - "$ref": "./link.yml" - - description: |- - The user that caused the notification - - **Resource**: User - readOnly: true + - "$ref": "./link.yml" + - description: |- + The user that caused the notification + + **Resource**: User resource: allOf: - "$ref": "./link.yml" @@ -68,7 +84,6 @@ properties: The linked resource of the notification, if any. **Resource**: Polymorphic - readOnly: true activity: allOf: - "$ref": "./link.yml" @@ -76,38 +91,48 @@ properties: The journal activity, if the notification originated from a journal entry **Resource**: Activity - readOnly: true example: - _type: News + _type: Notification id: 1 - title: asperiores possimus nam doloribus ab - summary: Celebrer spiculum colo viscus claustrum atque. Id nulla culpa sumptus. - Comparo crapula depopulo demonstro. - description: - format: markdown - raw: Videlicet deserunt aequitas cognatus. Concedo quia est quia pariatur vorago - vallum. Calco autem atavus accusamus conscendo cornu ulterius. Tam patria ago - consectetur ventito sustineo nihil caecus. Supra officiis eos velociter somniculosus - tonsor qui. Suffragium aduro arguo angustus cogito quia tolero vulnus. Supplanto - sortitus cresco apud vestrum qui. - html: "

Videlicet deserunt aequitas cognatus. Concedo quia est quia pariatur - vorago vallum. Calco autem atavus accusamus conscendo cornu ulterius. Tam patria - ago consectetur ventito sustineo nihil caecus. Supra officiis eos velociter - somniculosus tonsor qui. Suffragium aduro arguo angustus cogito quia tolero - vulnus. Supplanto sortitus cresco apud vestrum qui.

" - createdAt: '2015-03-20T12:57:01Z' + readIAN: false + reason: mentioned + createdAt: '2022-04-05T14:38:28Z' + updatedAt: '2022-04-06T09:03:24Z' + _embedded: + author: + _hint: User resource shortened for brevity + _type: User + id: 13 + name: Darth Nihilus + project: + _hint: Project resource shortened for brevity + _type: Project + id: 11 + name: Jedi Remnant Locator + activity: + _hint: Activity resource shortened for brevity + _type: Activity::Comment + id: 180 + version: 3 + resource: + _hint: WorkPackage resource shortened for brevity + _type: WorkPackage + id: 77 + subject: Educate Visas Marr _links: self: - href: "/api/v3/news/1" - title: asperiores possimus nam doloribus ab + href: '/api/v3/notifications/1' + readIAN: + href: '/api/v3/notifications/1/read_ian' + method: post + actor: + href: '/api/v3/users/13' + title: Darth Nihilus project: - href: "/api/v3/projects/1" - title: A project - author: - href: "/api/v3/users/2" - title: Peggie Feeney - _embedded: - project: - _type: Project... - author: - _type: User... + href: '/api/v3/projects/11' + title: Jedi Remnant Locator + activity: + href: '/api/v3/activities/180' + resource: + href: '/api/v3/work_packages/77' + title: Educate Visas Marr diff --git a/docs/api/apiv3/openapi-spec.yml b/docs/api/apiv3/openapi-spec.yml index de9faca7c69..bd9611685ab 100644 --- a/docs/api/apiv3/openapi-spec.yml +++ b/docs/api/apiv3/openapi-spec.yml @@ -555,8 +555,6 @@ components: "$ref": "./components/schemas/list_memberships_model.yml" List_of_NewsModel: "$ref": "./components/schemas/list_of_news_model.yml" - List_notificationsModel: - "$ref": "./components/schemas/list_notifications_model.yml" List_projectsModel: "$ref": "./components/schemas/list_projects_model.yml" List_projects_by_versionModel: @@ -577,6 +575,8 @@ components: "$ref": "./components/schemas/membership_update_form.yml" NewsModel: "$ref": "./components/schemas/news_model.yml" + NotificationCollectionModel: + "$ref": "./components/schemas/notification_collection_model.yml" NotificationModel: "$ref": "./components/schemas/notification_model.yml" NotificationSettingsModel: diff --git a/docs/api/apiv3/paths/file_link.yml b/docs/api/apiv3/paths/file_link.yml index 261fa14a082..c33cb4cfffc 100644 --- a/docs/api/apiv3/paths/file_link.yml +++ b/docs/api/apiv3/paths/file_link.yml @@ -2,7 +2,7 @@ --- get: summary: Gets a file link. - operationId: Work_Package_Get_File_Link + operationId: Get_File_Link tags: - Work Packages - File links diff --git a/docs/api/apiv3/paths/notification.yml b/docs/api/apiv3/paths/notification.yml index 1587aa9a1d1..337f98164a1 100644 --- a/docs/api/apiv3/paths/notification.yml +++ b/docs/api/apiv3/paths/notification.yml @@ -1,40 +1,36 @@ # /api/v3/notifications/{id} --- get: + summary: Get the notification + operationId: Get_Notification + tags: + - Notifications + description: Returns the notification identified by the notification id. parameters: - - description: notification id - example: '1' - in: path - name: id - required: true - schema: - type: integer + - name: id + in: path + description: notification id + example: '1' + required: true + schema: + type: integer responses: '200': content: application/hal+json: schema: - "$ref": "../components/schemas/notification_model.yml" + $ref: '../components/schemas/notification_model.yml' description: OK - headers: {} '404': content: application/hal+json: schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. description: |- Returned if the notification does not exist or if the user does not have permission to view it. **Required permission** being recipient of the notification - headers: {} - tags: - - Notifications - description: '' - operationId: View_notification - summary: View notification diff --git a/docs/api/apiv3/paths/notifications.yml b/docs/api/apiv3/paths/notifications.yml index 47a434e9280..e7639722fb4 100644 --- a/docs/api/apiv3/paths/notifications.yml +++ b/docs/api/apiv3/paths/notifications.yml @@ -1,23 +1,33 @@ # /api/v3/notifications --- get: + summary: Get notification collection + operationId: Get_Notification_Collection + tags: + - Notifications + description: |- + Returns the collection of available in-app notifications. The notifications returned depend on the provided + parameters and also on the requesting user's permissions. parameters: - - description: Page number inside the requested collection. - example: '25' + - name: offset + description: Page number inside the requested collection. in: query - name: offset + example: 25 required: false schema: default: 1 type: integer - - description: Number of elements to display per page. - example: '25' + - name: pageSize + description: Number of elements to display per page. in: query - name: pageSize + example: 25 required: false schema: + default: 20 type: integer - - description: |- + - name: sortBy + in: query + description: |- JSON specifying sort criteria. Accepts the same format as returned by the [queries](https://www.openproject.org/docs/api/endpoints/queries/) endpoint. Currently supported sorts are: @@ -27,24 +37,24 @@ get: + readIAN: Sort by read status example: '[["reason", "asc"]]' - in: query - name: sortBy required: false schema: type: string - - description: |- + - name: groupBy + in: query + description: |- string specifying group_by criteria. + reason: Group by notification reason + project: Sort by associated project example: 'reason' - in: query - name: groupBy required: false schema: type: string - - description: |- + - name: filters + in: query + description: |- JSON specifying filter conditions. Accepts the same format as returned by the [queries](https://www.openproject.org/docs/api/endpoints/queries/) endpoint. Currently supported filters are: @@ -60,8 +70,6 @@ get: + resourceType: Filter by the type of the resource the notification was created for. Ideally used together with the `resourceId` filter. example: '[{ "readIAN": { "operator": "=", "values": ["t"] } }]' - in: query - name: filters required: false schema: type: string @@ -70,39 +78,26 @@ get: content: application/hal+json: schema: - "$ref": "../components/schemas/list_notifications_model.yml" + $ref: '../components/schemas/notification_collection_model.yml' description: OK - headers: { } '400': content: application/hal+json: schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:InvalidQuery - message: - - Filters Invalid filter does not exist. + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:InvalidQuery + message: + - Filters Invalid filter does not exist. description: Returned if the client sends invalid request parameters e.g. filters - headers: { } '403': content: application/hal+json: schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to view this resource. + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission + message: You are not authorized to view this resource. description: Returned if the client is not logged in and login is required. - headers: { } - tags: - - Notifications - description: Lists available in-app notifications. The notifications returned depend on the provided parameters and - also on the requesting user's permissions. - operationId: List_Notifications - summary: List Notifications