diff --git a/.github/workflows/java_tests.yml b/.github/workflows/java_tests.yml index 896fdc71..702a9cc0 100644 --- a/.github/workflows/java_tests.yml +++ b/.github/workflows/java_tests.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: # Add any future services relative paths from . here - service: [user] + service: [user, matching] steps: @@ -41,7 +41,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: junit-test-results + name: ${{ matrix.service }}-junit-test-results path: | server/${{ matrix.service }}/build/test-results server/${{ matrix.service }}/build/reports/tests diff --git a/.github/workflows/update_api_spec.yml b/.github/workflows/update_api_spec.yml index e6071e7e..9fec32f5 100644 --- a/.github/workflows/update_api_spec.yml +++ b/.github/workflows/update_api_spec.yml @@ -6,7 +6,8 @@ on: workflow_dispatch: push: paths: - - 'api/*' + - 'api/openapi.yaml' + - 'api/scripts/*' jobs: @@ -21,6 +22,7 @@ jobs: - name: Make Scripts Executable run: | + chmod +x api/scripts/gen_client.sh chmod +x api/scripts/gen_docs.sh chmod +x api/scripts/gen_spring.sh chmod +x api/scripts/gen_typescript.sh @@ -43,6 +45,10 @@ jobs: run: ./api/scripts/gen_spring.sh shell: bash + - name: Generate Client Code + run: ./api/scripts/gen_client.sh + shell: bash + - name: Generate api.ts run: ./api/scripts/gen_typescript.sh shell: bash @@ -57,6 +63,9 @@ jobs: git add server/matching/generated git add server/user/generated git add server/gateway/generated + git add server/matching/generated-client + git add server/user/generated-client + git add server/gateway/generated-client git add client/src/api.ts git add docs/api.html diff --git a/api/changelogs/changelog_v2_1_2.md b/api/changelogs/changelog_v2_1_2.md new file mode 100644 index 00000000..1cc217d1 --- /dev/null +++ b/api/changelogs/changelog_v2_1_2.md @@ -0,0 +1,19 @@ +## Info +### Version +v2.1.2 +### Date +2025-06-30 +### Autor +James Stark +## Changelog: + +### Models +- Set required flag for most fields + +``` diff + +@@ All @@ ++ Set required flag for all fields where it is sensible +# This forces the generation of constructors where aplicable + +``` diff --git a/api/changelogs/changelog_v2_1_3.md b/api/changelogs/changelog_v2_1_3.md new file mode 100644 index 00000000..62a89c24 --- /dev/null +++ b/api/changelogs/changelog_v2_1_3.md @@ -0,0 +1,25 @@ +## Info +### Version +v2.1.3 +### Date +2025-06-30 +### Autor +James Stark +## Changelog: + +### Models +- Bug: fix incorrect values for collection models + +``` diff + +@@ UserCollection @@ +- remove attribute Users: User ++ insert attribute Users: [User] +# fix incorrect attribute + +@@ MatchCollection @@ +- remove attribute Matches: Matches ++ insert attribute Matches: [Matches] +# fix incorrect attribute + +``` diff --git a/api/changelogs/changelog_v2_1_4.md b/api/changelogs/changelog_v2_1_4.md new file mode 100644 index 00000000..e1123338 --- /dev/null +++ b/api/changelogs/changelog_v2_1_4.md @@ -0,0 +1,20 @@ +## Info +### Version +v2.1.4 +### Date +2025-07-01 +### Autor +James Stark +## Changelog: + +### Models +- Bug: remove userID value from MatchRequestUpdate + +``` diff + +@@ MatchRequestUpdate @@ +- remove attribute userID: UUID +# User should not be changeable! + + +``` diff --git a/api/changelogs/changelog_v2_1_5.md b/api/changelogs/changelog_v2_1_5.md new file mode 100644 index 00000000..96059dfd --- /dev/null +++ b/api/changelogs/changelog_v2_1_5.md @@ -0,0 +1,24 @@ +## Info +### Version +v2.1.4 +### Date +2025-07-01 +### Autor +James Stark +## Changelog: + +### Operations +- Bug: fix incorrect operation name + +``` diff + +@@ post-api-v2-matching-request @@ +- remove operation ID: post-api-v2-matching-request ++ insert operation ID: post-api-v2-matching-request-submit + +@@ delete-api-v2-matching-matches-request-id @@ +- remove operation ID: delete-api-v2-matching-matches-request-id ++ insert operation ID: delete-api-v2-matching-request-request-id + + +``` diff --git a/api/changelogs/changelog_v2_1_6.md b/api/changelogs/changelog_v2_1_6.md new file mode 100644 index 00000000..ba7a1344 --- /dev/null +++ b/api/changelogs/changelog_v2_1_6.md @@ -0,0 +1,20 @@ +## Info +### Version +v2.1.4 +### Date +2025-07-01 +### Autor +James Stark +## Changelog: + +### Paths +- Add 409 response and 200 body to api/v2/matching/request/submit + +``` diff + +@@ api/v2/matching/request/submit @@ ++ add return object to 200: MatchingRequset ++ add 409 CONFLICT response when a user already has a match on a given day + + +``` diff --git a/api/openapi.yaml b/api/openapi.yaml index 5fa4588d..4f58ada5 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -3,7 +3,7 @@ x-stoplight: id: ceylawji1yc2t info: title: MeetAtMensa - version: 2.1.1 + version: 2.1.6 description: |- This OpenAPI specification defines the endpoints, schemas, and security mechanisms for the Meet@Mensa User micro-service. @@ -65,6 +65,8 @@ components: id: 5grlrzedrmo9k type: object description: Object representing a conversation starter in the meet@mensa system + required: + - prompt properties: prompt: type: string @@ -76,6 +78,8 @@ components: id: p1vhmcpea8fmp type: object description: Object representing a collection of conversation starters in the Meet@Mensa system. + required: + - conversationsStarters properties: conversationsStarters: type: array @@ -91,6 +95,13 @@ components: id: 67i45cu41e80g type: object description: Object representing a group that has been matched in the Meet@Mensa system. + required: + - groupID + - date + - time + - location + - userStatus + - conversationStarters properties: groupID: $ref: '#/components/schemas/groupID' @@ -204,11 +215,17 @@ components: id: 4bem9fq0uukzk type: object description: Object representing a collection of matches in the Meet@Mensa system. + required: + - matches properties: matches: - $ref: '#/components/schemas/Match' x-stoplight: id: xxfpxm2j35k81 + type: array + items: + $ref: '#/components/schemas/Match' + x-stoplight: + id: 3k8gw0nlqax44 matchID: title: matchID x-stoplight: @@ -222,6 +239,10 @@ components: id: azr6ciwnsz5nr type: object description: Object Representing a set of user preferences + required: + - degreePref + - agePref + - genderPref properties: degreePref: type: boolean @@ -293,6 +314,8 @@ components: id: ccqjyx1unnz6s type: object description: Object representing a collection of match requests in the Meet@Mensa system. + required: + - requests properties: requests: type: array @@ -348,10 +371,6 @@ components: description: Object representing a request for matching a given user on a given date in the Meet@Mensa system. title: MatchRequestUpdate properties: - userID: - $ref: '#/components/schemas/userID' - x-stoplight: - id: rpwxqsd1z3mwd date: type: string x-stoplight: @@ -379,6 +398,9 @@ components: x-stoplight: id: pdsvthtexm88j type: object + required: + - userID + - status properties: userID: $ref: '#/components/schemas/userID' @@ -528,11 +550,17 @@ components: id: 8qy8pit8jdvq3 type: object description: Object representing a collection of student user in the Meet@Mensa system. + required: + - users properties: users: - $ref: '#/components/schemas/User' x-stoplight: id: l8a1hngdfmgzr + type: array + items: + $ref: '#/components/schemas/User' + x-stoplight: + id: l5erbwkguwpoa UserNew: title: UserNew x-stoplight: @@ -796,13 +824,20 @@ paths: responses: '200': description: Request submitted sucessfully + headers: {} + content: + application/json: + schema: + $ref: '#/components/schemas/MatchRequest' '400': $ref: '#/components/responses/BadRequestError' '401': $ref: '#/components/responses/UnauthorizedError' + '409': + description: Conflict '500': description: Internal Server Error - operationId: post-api-v2-matching-request + operationId: post-api-v2-matching-request-submit x-stoplight: id: 1x5ta8qguutzq requestBody: @@ -881,7 +916,7 @@ paths: $ref: '#/components/responses/NotFoundError' '500': description: Internal Server Error - operationId: delete-api-v2-matching-matches-request-id + operationId: delete-api-v2-matching-request-request-id x-stoplight: id: shgx14ydoaa2f description: 'Delete MatchRequest with ID {request-id} from the system' diff --git a/api/scripts/gen_client.sh b/api/scripts/gen_client.sh new file mode 100644 index 00000000..b8c7b885 --- /dev/null +++ b/api/scripts/gen_client.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# generate client code and build files based on openapi spec for springboot backend services + +# dependencies: +# - npm: +# - @openapitools/openapi-generator-cli +# - other: +# - gradle + +# fail command if any part fails +set -euo pipefail + +for path in matching user gateway; do + + # echo generating code + echo "Generating client code for $path..." + + # generate client code based on OpenAPI specification + openapi-generator-cli generate \ + -g java \ + -i api/openapi.yaml \ + -o server/$path/generated-client \ + --additional-properties=scmConnection=false,groupId=org.openapitools.client,artifactId=openapi-client-$path + + # echo generating gradle + echo "Generating gradle project files for $path..." + + # generate gradle build files. + gradle init \ + --type pom \ + --dsl groovy \ + --no-incubating \ + --project-dir server/$path/generated-client + +done \ No newline at end of file diff --git a/client/src/api.ts b/client/src/api.ts index 8ac5989a..99caafdc 100644 --- a/client/src/api.ts +++ b/client/src/api.ts @@ -68,7 +68,7 @@ export interface paths { * Submit matching Request * @description Submit a new matching request to the Matching-Service */ - post: operations["post-api-v2-matching-request"]; + post: operations["post-api-v2-matching-request-submit"]; delete?: never; options?: never; head?: never; @@ -142,7 +142,7 @@ export interface paths { * Delete MatchRequest with {request-id} * @description Delete MatchRequest with ID {request-id} from the system */ - delete: operations["delete-api-v2-matching-matches-request-id"]; + delete: operations["delete-api-v2-matching-request-request-id"]; options?: never; head?: never; patch?: never; @@ -223,31 +223,31 @@ export interface components { * @description Object representing a conversation starter in the meet@mensa system */ ConversationStarter: { - prompt?: string; + prompt: string; }; /** * ConversationStarterCollection * @description Object representing a collection of conversation starters in the Meet@Mensa system. */ ConversationStarterCollection: { - conversationsStarters?: components["schemas"]["ConversationStarter"][]; + conversationsStarters: components["schemas"]["ConversationStarter"][]; }; /** * Group * @description Object representing a group that has been matched in the Meet@Mensa system. */ Group: { - groupID?: components["schemas"]["groupID"]; + groupID: components["schemas"]["groupID"]; /** * Format: date * @description Date the group is scheduled to meet at */ - date?: string; + date: string; /** @description Timeslot the group is scheduled to meet at */ - time?: components["schemas"]["timeslot"]; - location?: components["schemas"]["location"]; - userStatus?: components["schemas"]["MatchStatus"][]; - conversationStarters?: components["schemas"]["ConversationStarterCollection"]; + time: components["schemas"]["timeslot"]; + location: components["schemas"]["location"]; + userStatus: components["schemas"]["MatchStatus"][]; + conversationStarters: components["schemas"]["ConversationStarterCollection"]; }; /** * groupID @@ -300,7 +300,7 @@ export interface components { * @description Object representing a collection of matches in the Meet@Mensa system. */ MatchCollection: { - matches?: components["schemas"]["Match"]; + matches: components["schemas"]["Match"][]; }; /** * matchID @@ -317,17 +317,17 @@ export interface components { * ---------|--------- * true | degree = same (priority) * false | degree = any (no priority) */ - degreePref?: boolean; + degreePref: boolean; /** @description Value | Meaning * ---------|--------- * true | age = same (priority) * false | age = any (no priority) */ - agePref?: boolean; + agePref: boolean; /** @description Value | Meaning * ---------|--------- * true | gender = same (priority) * false | gender = any (no priority) */ - genderPref?: boolean; + genderPref: boolean; }; /** * MatchRequest @@ -351,7 +351,7 @@ export interface components { * @description Object representing a collection of match requests in the Meet@Mensa system. */ MatchRequestCollection: { - requests?: components["schemas"]["MatchRequest"][]; + requests: components["schemas"]["MatchRequest"][]; }; /** * MatchRequestNew @@ -373,7 +373,6 @@ export interface components { * @description Object representing a request for matching a given user on a given date in the Meet@Mensa system. */ MatchRequestUpdate: { - userID?: components["schemas"]["userID"]; /** * Format: date * @description The date a user would like meet@mensa to find them a match @@ -385,8 +384,8 @@ export interface components { }; /** MatchStatus */ MatchStatus: { - userID?: components["schemas"]["userID"]; - status?: components["schemas"]["inviteStatus"]; + userID: components["schemas"]["userID"]; + status: components["schemas"]["inviteStatus"]; }; /** * requestID @@ -483,7 +482,7 @@ export interface components { * @description Object representing a collection of student user in the Meet@Mensa system. */ UserCollection: { - users?: components["schemas"]["User"]; + users: components["schemas"]["User"][]; }; /** * UserNew @@ -763,7 +762,7 @@ export interface operations { }; }; }; - "post-api-v2-matching-request": { + "post-api-v2-matching-request-submit": { parameters: { query?: never; header?: never; @@ -781,10 +780,19 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; + content: { + "application/json": components["schemas"]["MatchRequest"]; + }; }; 400: components["responses"]["BadRequestError"]; 401: components["responses"]["UnauthorizedError"]; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; /** @description Internal Server Error */ 500: { headers: { @@ -904,7 +912,7 @@ export interface operations { }; }; }; - "delete-api-v2-matching-matches-request-id": { + "delete-api-v2-matching-request-request-id": { parameters: { query?: never; header?: never; diff --git a/deployment/debug/compose.yml b/deployment/debug/compose.yml new file mode 100644 index 00000000..ee3926b6 --- /dev/null +++ b/deployment/debug/compose.yml @@ -0,0 +1,89 @@ +# This file is used to deploy the microservices using Docker Compose. +# It defines the services, their images, build context, and ports. + +services: + gateway-service: + build: ../../server/gateway + container_name: meetatmensa-gateway + ports: + - "8080:80" + depends_on: + - matching-service + - user-service + - genai-service + networks: + - backend + + matching-service: + build: ../../server/matching + container_name: meetatmensa-matching + expose: + - "80" + ports: + - "8081:80" + depends_on: + - match-database + networks: + - backend + + user-service: + build: ../../server/user + container_name: meetatmensa-user + expose: + - "80" + ports: + - "8082:80" + depends_on: + - user-database + networks: + - backend + + genai-service: + build: ../../server/genai + container_name: meetatmensa-genai + expose: + - "80" + ports: + - "8083:80" + networks: + - backend + + client-service: + build: ../../client + container_name: meetatmensa-client + ports: + - "80:80" + + match-database: + build: ../../server/database/matchdb + container_name: meetatmensa-matchdb + # TODO: Implement password passed via secret + environment: + - MYSQL_ROOT_PASSWORD=root + volumes: + - matchdb_data:/var/lib/mysql + expose: + - "3306" + networks: + - backend + + user-database: + build: ../../server/database/userdb + container_name: meetatmensa-userdb + # TODO: Implement password passed via secret + environment: + - MYSQL_ROOT_PASSWORD=root + volumes: + - userdb_data:/var/lib/mysql + expose: + - "3306" + networks: + - backend + +networks: + backend: + driver: bridge + +volumes: + matchdb_data: + userdb_data: \ No newline at end of file diff --git a/docs/api.html b/docs/api.html index b3cda8f2..77d05bc4 100644 --- a/docs/api.html +++ b/docs/api.html @@ -406,7 +406,7 @@
-