Skip to content

OSMT Update 2026#479

Open
ottonomy wants to merge 205 commits into
wgu-opensource:developfrom
skybridgeskills:main
Open

OSMT Update 2026#479
ottonomy wants to merge 205 commits into
wgu-opensource:developfrom
skybridgeskills:main

Conversation

@ottonomy
Copy link
Copy Markdown
Contributor

Major updates and code completed over the course of a large scope of work. Individual pieces reviewed for UX by product team, UX representatives. Architecture for deployment reviewed by security, auth, cloud engineering teams.

QA: Observe the public frontend for testing at https://osmt.staging.prettygoodskills.com and the read/write staff backend at https://osmt-staff.staging.prettygoodskills.com

Many open issues on this github organization, especially the dependabot updates are resolved by this PR.

We also recommend switching the default branch to "main" to prepare for a simpler trunk-based development pattern when this repository is transferred to credentialengine.


Bugs

  • Bug1: Avoid a viewer role blank screen. This is caused because there is no public home/search page, and the user gets redirected to authenticate without the ability to browse public collections.
  • Bug2: Display categories in a collection in a container with limited height.
  • Bug3: Clicking "Show All/Fewer" should expand or collapse relevant content as indicated.
  • Bug4: Type-ahead search in categories dropdown should show all relevant results.
  • Bug5: Results per page dropdown should display correctly in the UI and be visible with proper alignment.
  • Bug6: Download RSD in CSV format option should result in CSV download. Bug causes the JSON file to be downloaded.
  • Bug7: When converting a Workspace to a Collection, the collection description should be preserved.
  • Bug8: When downloading an RSD or a Collection as XLSX, download should work properly.
  • Bug9: System Timeout Implementation — login session validity period updated to 24 hrs. (Note: 12 hrs suggested as an alternative, aligning session expiration to overnight rather than mid-workday.)
  • Bug10: Tune up test framework. Some "test containers" references exist in code. Significant rework of testing to remove dependencies on actual Okta test credentials and running containers.
  • Bug13: Resolve "Error message when a user clicks on last page of library or collection" (OSMT-235).
  • Bug14: Add user message for a collection search result with 0 returned results (OSMT-306).
  • Bug15: Store and report collection publish date (OSMT-48).
  • Bug18: Skill counts over 10,000 were inaccurate.
  • Bug19: Results per page dropdown was misaligned.
  • Bug20: Category search only showed 20 results.
  • Bug21: Category list could clip without a way to expand.
  • Bug22: Category names weren't clickable. Category names should be visually styled as links.
  • Bug23: Archived RSDs should not show in a published collection. Bug is unfixed — see this public collection with an archived skill in it.
  • Bug26: Error when adding parentheses to RSD fields.
  • Bug27: Cannot add or remove RSDs from My Workspace.

Features

  • Feature0: Environment Separation — support separation of read-only UI container from read/write management container. Enable public URL creation across domains, ensure correct public URLs are used consistently. Provide documentation for necessary env vars and configuration (e.g. read-only database user, read-only search user), including example configuration snippets with detailed notes.
  • Feature11: Complete Job Code support drafted in PR #447.
  • Feature12: Evaluate PR #430 for additional admin fields (207 files modified) and close out remaining work (OSMT-39).
  • Feature16: Authentication based on OAuth2 (part of architecture surgery component).
  • Feature17: Credential Registry integration (contract period through March 31, 2026). Update link text from "...Credential Engine" to "View in Credential Registry".
  • Feature24 (theming): White label theming (part of architecture surgery component).
  • Feature24 (selection): Enable selected RSDs to be retained across search pages (OSMT-49). Accepted approach: add an "Add to Workspace" action.
  • Feature25: Create duplicate a collection feature (OSMT-340).
  • Feature28: Convert published collection back to draft (OSMT-51). Ensure consequences for Registry publication state are covered.
  • Feature29: RSD Preview View (GitHub issue #181) — user wants to preview a skill in a dialog showing full field data, standards, occupations, and alignments not currently visible in list view. Accepted solution: add an "Add to Workspace" action on the skill detail view (accepted by Christina, April 6).

frgray and others added 30 commits September 26, 2025 11:02
chore: Updates api build process to not auto-build ui
chore: Moved dev-stack.yaml compose file into a top-level docker-compose.yaml file
Replaced `jcenter` with `Maven Central`, adjusted repository configurations.
Introduce `validate-versions.sh` script to ensure version consistency across `.sdkmanrc`, `.nvmrc`, Dockerfiles, `pom.xml`, and GitHub Actions workflows. Add a corresponding GitHub Actions workflow for automated validation.
- Updated .sdkmanrc to Java 21.0.2-tem
- Updated pom.xml java.version to 21
- Updated api/pom.xml maven-compiler-plugin release to 21
- Updated .vscode/settings.json Kotlin JVM target to 21
- Updated api/Dockerfile to use java-21-openjdk
- Updated README.md Java requirement to 21
- Updated bin/lib/common.sh Java version validation to 21
- Updated GitHub workflows to use Java 21 and Temurin distribution

Note: Kotlin 1.7.21 does not support Java 21 JVM target.
Kotlin upgrade needed before build will succeed.
- Updated .sdkmanrc to Kotlin 2.2.21
- Updated api/pom.xml: kotlin.version to 2.2.21, coroutines to 1.9.5
- Replaced kotlin-stdlib-jdk8 with kotlin-stdlib (deprecated in Kotlin 2.x)
- Added jvmTarget 21 configuration to kotlin-maven-plugin
- Updated Dokka plugin in pom.xml from 1.7.20 to 2.1.0
- Fixed String.strip() -> String.trim() in KeywordRepository.kt (Kotlin compatibility)
- Fixed null safety issue in RichSkillEsRepo.kt
- Fixed KDoc comment parsing issue in SecurityConfigHelper.kt (avoided /* in comments)

All tests passing: 155 tests, 0 failures
Build verified with Java 21 and Kotlin 2.2.21
- Document Spring Boot 3.3.0 upgrade attempt and test failures
- Track reasons for skipping and next steps for investigation
- File will be updated as other upgrades progress
- Updated log4j.version property to 2.23.1
- All tests passing (155 tests, 0 failures)
- Build successful
- Removed mysql-connector-java from dependencyManagement in pom.xml
- Removed mysql-connector-java from dependencies in pom.xml and api/pom.xml
- Now using only com.mysql:mysql-connector-j (provided by Spring Boot parent)
- All tests passing (155 tests, 0 failures)
- Database connectivity verified
- Updated jackson.version property to 2.17.1
- All tests passing (155 tests, 0 failures)
- JSON serialization/deserialization verified
- Updated all @angular/* packages from ^16.0.2 to ^18.0.0
- Updated Angular CLI and build tools to ^18.0.0
- Updated RxJS from ~6.5.5 to ~7.8.1
- Updated TypeScript from ~4.9.5 to ~5.4.5
- Updated zone.js from ~0.13.0 to ~0.14.10
- Updated @types/node to ^20.11.0
- Fixed zone.js import paths (removed /dist/)
- Replaced deprecated async with waitForAsync in tests
- Fixed TypeScript 5 strictness issues in tests
- Added esModuleInterop and allowSyntheticDefaultImports to tsconfig
- Build successful, 689 tests passing
- Updated .nvmrc from 18.18.2 to 20.18.0
- Updated ui/Dockerfile from node:18.18-alpine3.15 to node:20.18-alpine
- Updated ui/pom.xml nodeVersion from v18.18 to v20.18
- Updated README.md with Node.js v20.18.0 requirement
- npm install and build verified successful
- All tests passing
Yona-Appletree and others added 29 commits April 2, 2026 17:49
Add SESSION_EXPIRE_HOURS environment variable to control both:
- server.servlet.session.timeout (HTTP session in Redis)
- app.sessionTokenExpirySeconds (JWT token expiry, via fallback)

Both now default to 24 hours from SESSION_EXPIRE_HOURS. Supports fractional
hours (e.g., 0.5 for 30 minutes).

Backwards compatibility: APP_SESSION_TOKEN_EXPIRY_SECONDS can still be used
to override just the JWT token expiry if needed (takes precedence).

Also adds sessionExpireHours property to AppConfig for programmatic access.

Made-with: Cursor
Add documentation for the new SESSION_EXPIRE_HOURS environment variable
to both dev and staging env example files. Clarify that
APP_SESSION_TOKEN_EXPIRY_SECONDS is still supported as an override
for JWT token expiry (backwards compatibility).

Made-with: Cursor
- Remove SESSION_EXPIRE_HOURS and app.sessionExpireHours; tie
  server.servlet.session.timeout to the same seconds as the session JWT.
- Update env examples and AppConfig/test fixtures accordingly.
- Add IntelliJ parent module descriptor and modules.xml entry.

Made-with: Cursor
fixes: Public collection search and JWT session alignment
…single

feat(richskill): add Add to Workspace on manage skill detail action bar
Add support for running OSMT in a split deployment configuration:
- Public read-only instance (no auth, no writes, read-only DB user)
- Staff writable instance (full auth, full DB access)

Changes:
- Add readonly Spring profile with ReadOnlySecurityConfig
- Add ReadOnlyAccessDeniedHandler for 403 JSON responses
- Add split deployment config properties (writableInstanceUrl, etc.)
- Update UI to hide login on read-only instances
- Add whitelabel configuration for instance differentiation
- Add tests for read-only security behavior
- Add feature documentation and implementation plans

Made-with: Cursor
Use readOnlyMode as the single flag; replace writable-instance fields with
publicInstanceUrl on the authoring side. Drop instanceType and read-only
login link to staff. Update whitelabel JSON, UI, tests, and feature doc.

Made-with: Cursor
readonly: feat: implement split deployment with read-only profile
- Provide @primary ElasticsearchTemplate that wraps IndexOperations to
  no-op create/delete on shared Elasticsearch sidecars
- Add unit tests for SkipCreateIndexOperations

Made-with: Cursor
readonly: fix: skip ES index creation in readonly profile
AdminTokenJwtConfig, AdminUserAuthenticationFilter, AdminTokenService,
AdminAuthController, and SingleAuthEntryPoint all had @Profile("single-auth")
which activates even in readonly mode because the entrypoint auto-adds
single-auth when no OAuth creds are present. Add !readonly to prevent
APP_SESSION_TOKEN_SECRET requirement on public instances.

Made-with: Cursor
readonly: readonly profile and task-log cleanup
- ElasticsearchClientManager: exclude elasticsearchTemplate bean from
  readonly profile with @Profile(!readonly)
- ReadOnlyElasticsearchConfig: rename bean method from
  readOnlyElasticsearchTemplate to elasticsearchTemplate so it's picked
  up by @EnableElasticsearchRepositories
- SpringTest.HasElasticsearchReset: handle NoSuchIndexException gracefully
  to support readonly profile tests

Made-with: Cursor
- ElasticsearchClientManager: exclude elasticsearchTemplate bean from
  readonly profile with @Profile(!readonly)
- ReadOnlyElasticsearchConfig: rename bean method from
  readOnlyElasticsearchTemplate to elasticsearchTemplate so it's picked
  up by @EnableElasticsearchRepositories
- SpringTest.HasElasticsearchReset: handle NoSuchIndexException gracefully
  to support readonly profile tests

Made-with: Cursor
The public collection view was requesting archived and draft skills along
with published ones. Filter the collection skills query to Published
status only, and add a unit test for the getCollectionSkills call.

Made-with: Cursor
Published collections can return to draft via a new action. If the
collection was synced to the Credential Registry, re-sync runs after
unpublish so the registry reflects draft status. Publish confirmation
copy no longer claims collections cannot be unpublished.

Made-with: Cursor
readonly: fix: proper ES readonly bean naming to prevent index creation
Add POST /api/v3/collections/{uuid}/duplicate that creates a draft copy
with the same skills, using ApiCollectionUpdate for name, description,
and author from the client.

Wire Angular route collections/:uuid/duplicate, duplicate flow on the
collection form (Copy of prefix and notACopy validation), manage
collection action, and tests for API and UI.

Made-with: Cursor
The new Duplicate Collection action at index 2 shifted all subsequent
actions, causing the test to call unpublishAction (native confirm dialog)
instead of archiveAction -- crashing headless Chrome.

Made-with: Cursor
fixes: collections duplicate, unpublish, and public publishing fixes
Replace the icon-unarchive fallback with a dedicated icon-unpublish
that visually mirrors the publish icon - arrow points down into
the box instead of up out of it, making the action's intent clearer.

Refs: OSMT-###
Made-with: Cursor
Replace "Copy of <name>" format with "<name> (Copy <YYYY-MM-DD> HH:MM)"
to provide better UX:
- Users no longer need to manually remove "Copy of" prefix
- Timestamp makes it obvious when the copy was made
- Multiple copies won't collide or require manual renaming
- Smart logic removes existing (Copy ...) suffix to avoid double parens

Updated:
- Collection form duplicate naming
- Skill form duplicate naming
- Form validator to check for (Copy ...) pattern
- Error messages to reference new format
- Tests for new behavior

Refs: OSMT-###
Made-with: Cursor
Fix formatting issues in files from the duplicate naming UX feature.

Made-with: Cursor
ux fixes: icon and duplicated collection name
Resolve OsMt canonical skill and collection URLs against AppConfig
publicInstanceUrl for copy actions and View Published opens from the
authoring UI. Add shared canonical-public-url helpers and tests.

Made-with: Cursor
Use public instance URL for authoring canonical links
@ottonomy ottonomy requested a review from stirhale-wgu April 29, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants