diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 000000000..5c23c8340 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,49 @@ +you are an expert Angular programmer using TypeScript, Angular 18 and Jest that focuses on producing clear, readable code. + +this project uses SDKMAN for Java/Kotlin/Maven version management. ensure you run `sdk env install` or `sdk env` to load the versions specified in .sdkmanrc before building or running the project. + +RUN TESTS before telling the user that you're done. + +run format:check before committing (ui/: npm run format:check). run prettier --write to fix any issues. + +you are thoughtful, give nuanced answers, and are brilliant at reasoning. + +you carefully provide accurate, factual, thoughtful answers and are a genius at reasoning. + +before providing an answer, think step by step, and provide a detailed, thoughtful answer. + +if you need more information, ask for it. + +write tests for your code. + +break down complex problems into smaller, more manageable pieces. + +place most abstract / general functions first in files. + +prefer a one-concept-per-file approach with a matching .spec.ts file. + +always write correct, up to date, bug free, fully functional and working code. + +focus on performance, readability, and maintainability. + +before providing an answer, double check your work + +include all required imports, and ensure proper naming of key components + +do not nest code more than 2 levels deep + +code should obey the rules defined in the .eslintrc.json, .prettierrc, .htmlhintrc, and .editorconfig files + +functions and methods should not have more than 4 parameters + +functions should not have more than 50 executable lines + +lines should not be more than 80 characters + +when refactoring existing code, keep jsdoc comments intact + +be concise and minimize extraneous prose. + +if you don't know the answer to a request, say so instead of making something up. + +linting: configure ktlint in .editorconfig, not in mvn.xml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..232becddb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +Dockerfile +/ui/node_modules +/ui/reports +/ui/.angular + +# Exclude previously built artifacts +/ui/dist +/api/target diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..99c3d7fe0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{ts,js,json,html,scss,css}] +indent_size = 2 + +[*.{kt,kts}] +indent_size = 4 +max_line_length = 100 +ktlint_standard_no-wildcard-imports = disabled +ktlint_standard_property-naming = disabled + +[**/test/**/*.{kt,kts}] +ktlint_standard_max-line-length = off + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +[*/target/**] +ktlint_standard = disabled diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml deleted file mode 100644 index 3746eed93..000000000 --- a/.github/workflows/api-tests.yml +++ /dev/null @@ -1,36 +0,0 @@ -# This workflow will Run API tests using Newman - -name: API Tests with Maven - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - api-test: - runs-on: ubuntu-latest - - steps: - - name: Checkout out branch - uses: actions/checkout@v2 - - name: Set up JDK 17 - uses: actions/setup-java@v2 - with: - java-version: '17' - distribution: 'adopt' - - name: Maven version - run: mvn -version - - name: Run API tests - run: mvn clean install -DskipTests && mvn verify -pl test -Prun-api-tests - env: - OAUTH_CLIENTID: "${{secrets.OAUTH_CLIENTID}}" - OAUTH_CLIENTSECRET: "${{secrets.OAUTH_CLIENTSECRET}}" - OAUTH_AUDIENCE: "${{secrets.OAUTH_AUDIENCE}}" - OAUTH_ISSUER: "${{secrets.OAUTH_ISSUER}}" - OKTA_USERNAME: "${{secrets.OKTA_USERNAME}}" - OKTA_PASSWORD: "${{secrets.OKTA_PASSWORD}}" - OKTA_URL: "${{secrets.OKTA_URL}}" - BASE_URL: "http://localhost:8080" - APP_START_CHECK_RETRY_LIMIT: 100 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..b4178f2e8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,176 @@ +name: CI Validation + +on: + pull_request: + branches: + - "main" + - "feature/*" + - "renovate/*" + +jobs: + version-check: + name: Version Consistency Check + runs-on: ubuntu-latest + if: | + github.event.pull_request.draft == false && ( + contains(github.event.pull_request.head.ref, 'skip-ci') == false + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Validate version consistency + run: | + chmod +x bin/validate-versions.sh + bin/validate-versions.sh + + ui-build-test: + name: UI Build & Tests + runs-on: ubuntu-latest + if: | + github.event.pull_request.draft == false && ( + contains(github.event.pull_request.head.ref, 'skip-ci') == false + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "npm" + cache-dependency-path: ui/package-lock.json + + - name: Install dependencies + working-directory: ui + run: npm ci + + - name: Build UI + id: ui-build + working-directory: ui + run: | + echo "::group::Building UI" + npm run build-prod + echo "::endgroup::" + + - name: Validation (format check) + id: ui-validation + working-directory: ui + run: | + echo "::group::Validating code format" + npm run format:check + echo "::endgroup::" + + - name: Lint UI + id: ui-lint + working-directory: ui + run: | + echo "::group::Linting UI code" + npm run lint + echo "::endgroup::" + + - name: Test UI + id: ui-test + working-directory: ui + run: | + echo "::group::Running UI tests" + npm run ci-test + echo "::endgroup::" + + api-build-test: + name: API Build & Tests + runs-on: ubuntu-latest + if: | + github.event.pull_request.draft == false && ( + contains(github.event.pull_request.head.ref, 'skip-ci') == false + ) + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: "21" + distribution: "temurin" + cache: "maven" + + - name: Setup SDKMAN + uses: sdkman/sdkman-action@master + with: + candidate: maven + version: "3.9.6" + + - name: Maven version + run: mvn -version + + - name: Build API module + id: api-build + run: | + echo "::group::Building API module" + mvn clean install -pl api -am --batch-mode + echo "::endgroup::" + + - name: Run API unit tests + id: api-tests + run: | + echo "::group::Running API unit tests" + mvn test -pl api --batch-mode + echo "::endgroup::" + +# integration-tests: +# name: Integration Tests +# runs-on: ubuntu-latest +# needs: [ ui-build-test, api-build-test ] +# if: | +# github.event.pull_request.draft == false && ( +# contains(github.event.pull_request.head.ref, 'skip-ci') == false +# ) +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up JDK 21 +# uses: actions/setup-java@v4 +# with: +# java-version: "21" +# distribution: "temurin" +# cache: "maven" +# +# - name: Setup SDKMAN +# uses: sdkman/sdkman-action@master +# with: +# candidate: maven +# version: "3.9.6" +# +# - name: Maven version +# run: mvn -version +# +# - name: Build API and test modules +# id: build-all +# run: | +# echo "::group::Building API and test modules" +# mvn clean install -pl api,test -am -DskipTests --batch-mode +# echo "::endgroup::" +# +# - name: Run API integration tests +# id: integration-tests +# run: | +# echo "::group::Running API integration tests" +# mvn verify -pl test -Prun-api-tests --batch-mode +# echo "::endgroup::" +# env: +# OAUTH_CLIENTID: "${{secrets.OAUTH_CLIENTID}}" +# OAUTH_CLIENTSECRET: "${{secrets.OAUTH_CLIENTSECRET}}" +# OAUTH_AUDIENCE: "${{secrets.OAUTH_AUDIENCE}}" +# OAUTH_ISSUER: "${{secrets.OAUTH_ISSUER}}" +# OKTA_USERNAME: "${{secrets.OKTA_USERNAME}}" +# OKTA_PASSWORD: "${{secrets.OKTA_PASSWORD}}" +# OKTA_URL: "${{secrets.OKTA_URL}}" +# BASE_URL: "http://localhost:8080" +# APP_START_CHECK_RETRY_LIMIT: 100 diff --git a/.github/workflows/main-push.yml b/.github/workflows/main-push.yml new file mode 100644 index 000000000..475e0eff6 --- /dev/null +++ b/.github/workflows/main-push.yml @@ -0,0 +1,29 @@ +name: Main push - Version tag + +on: + push: + branches: + - main + +concurrency: + group: main-push-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: write + +jobs: + tag-next-version: + name: Tag next patch version + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate and push tag + env: + BRANCH: main + CI: "true" + run: bin/tag-next-version.sh diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 45605844f..000000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,26 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Java CI with Maven - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 17 - uses: actions/setup-java@v2 - with: - java-version: '17' - distribution: 'adopt' - - name: Maven version - run: mvn -version - - name: Build with Maven - run: mvn -B package diff --git a/.github/workflows/trigger-monorepo-version-bump.yml b/.github/workflows/trigger-monorepo-version-bump.yml new file mode 100644 index 000000000..b3f6288c2 --- /dev/null +++ b/.github/workflows/trigger-monorepo-version-bump.yml @@ -0,0 +1,31 @@ +name: Trigger Monorepo Version Bump + +on: + push: + branches: + - main + +permissions: + contents: read + +jobs: + trigger: + runs-on: ubuntu-latest + steps: + - name: Generate GitHub App token + id: generate-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.MONOREPO_APP_ID }} + private-key: ${{ secrets.MONOREPO_APP_PRIVATE_KEY }} + owner: skybridgeskills + repositories: skybridgeskills-monorepo + + - name: Trigger monorepo version bump workflow + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + gh workflow run osmt-bump-version.yml \ + --repo skybridgeskills/skybridgeskills-monorepo \ + --ref main + echo "✅ Triggered monorepo version bump workflow" diff --git a/.gitignore b/.gitignore index fe71f1d3c..730508365 100644 --- a/.gitignore +++ b/.gitignore @@ -15,12 +15,6 @@ buildNumber.properties # OSX metadata **/.DS_Store -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - ### NetBeans ### /nbproject/private/ /nbbuild/ @@ -31,8 +25,10 @@ build/ !**/src/main/**/build/ !**/src/test/**/build/ -### VS Code ### -.vscode/ +### Cursor ### +# Cursor plans directory - contains development plans and notes +.plans +.cursor/plans ### Local nodejs downloaded for frontend-maven-plugin ui/node @@ -46,3 +42,7 @@ osmt*.env /test/postman/token.env /test/node_modules **/target/ + +.m2-cache +.m2 +task-logs-* diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..ab1f4164e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/IntelliLang.xml b/.idea/IntelliLang.xml new file mode 100644 index 000000000..8cfd40917 --- /dev/null +++ b/.idea/IntelliLang.xml @@ -0,0 +1,286 @@ + + + + + Apache HttpClient 4 HTTP Header (org.apache.http) + + + + + + Apache HttpClient 5 HTTP Header (org.apache.hc.core5) + + + + + + + + + AsyncQueryRunner (org.apache.commons.dbutils) + + + + + + + + + + + + + + + + + + Jodd (jodd.db) + + + + + + + + MockServer Header (org.mockserver) + + + + + + + MyBatis @Select/@Delete/@Insert/@Update + + + + + + + + QueryRunner (org.apache.commons.dbutils) + + + + + + + + + + + + + + + + + + R2DBC (io.r2dbc) + + + + + + Reactiverse Postgres Client (io.reactiverse) + + + + + + + + + + + + + RestAssured HTTP Header (io.restassured) + + + + + + + + SmallRye Axle SqlClient (io.vertx.axle.sqlclient) + + + + + + SmallRye Mutiny SqlClient (io.vertx.mutiny.sqlclient) + + + + + + SmallRye Mutiny SqlConnection (io.vertx.mutiny.sqlclient) + + + + + + + + Spring @Cacheable and @CacheEvict + + + + + + + + + + + + Spring HttpHeaders (org.springframework.http) + + + + + + + Spring Integration/Messaging + + + + + + + Spring JDBC (org.springframework.jdbc.core.JdbcOperations) + + + + + + + + + + + + + + + + Spring JDBC (org.springframework.jdbc.core.PreparedStatementCreatorFactory) + + + + + + + Spring JDBC (org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator) + + + + + + + + Spring Security @PostAuthorize/@PostFilter/@PreAuthorize/@PreFilter/@AuthenticationPrincipal + + + + + + + + + + Spring State Machine + + + + + + + + Vert.x SQL Extensions (io.vertx.ext.sql) + + + + + + + Vert.x SQL Reactive Extensions (io.vertx.reactivex.ext.sql) + + + + + + + + + + Vert.x SqlClient (io.vertx.sqlclient) + + + + + + + + + + + Vert.x SqlClient RxJava2 (io.vertx.reactivex.sqlclient) + + + + + + + + + + + + WireMock (com.github.tomakehurst.wiremock.client) + + + + + + + + WireMock (com.github.tomakehurst.wiremock.client) + + + + + + + WireMock (com.github.tomakehurst.wiremock.client) + + + + + + + + jOOQ (org.jooq.DSLContext) + + + + + + + + rxjava2-jdbc (org.davidmoten.rx.jdbc) + + + + + + + SpEL for Spring Cache + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..a55e7a179 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 000000000..0a3531bfb --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 000000000..4ea72a911 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 000000000..7ef04e2ea --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 000000000..1f2ea11e7 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 000000000..8648f9401 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..4e87d3386 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..03d9549ea --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 000000000..7f3184822 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 000000000..8ad8c8610 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/ktlint-plugin.xml b/.idea/ktlint-plugin.xml new file mode 100644 index 000000000..e8bd90cf2 --- /dev/null +++ b/.idea/ktlint-plugin.xml @@ -0,0 +1,7 @@ + + + + DISTRACT_FREE + DEFAULT + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..0c961a65e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..61e45b5ea --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.idea/osmt.iml b/.idea/osmt.iml new file mode 100644 index 000000000..c956989b2 --- /dev/null +++ b/.idea/osmt.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/OSMT_API_Dev.xml b/.idea/runConfigurations/OSMT_API_Dev.xml new file mode 100644 index 000000000..a93acc3c3 --- /dev/null +++ b/.idea/runConfigurations/OSMT_API_Dev.xml @@ -0,0 +1,22 @@ + + + + diff --git a/.idea/runConfigurations/OSMT_API_Dev__google_oauth____TEMPLATE.xml b/.idea/runConfigurations/OSMT_API_Dev__google_oauth____TEMPLATE.xml new file mode 100644 index 000000000..bb43fbd34 --- /dev/null +++ b/.idea/runConfigurations/OSMT_API_Dev__google_oauth____TEMPLATE.xml @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/OSMT_UI.xml b/.idea/runConfigurations/OSMT_UI.xml new file mode 100644 index 000000000..0f78acce2 --- /dev/null +++ b/.idea/runConfigurations/OSMT_UI.xml @@ -0,0 +1,17 @@ + + + + + +