Skip to content

Conversation

@weskubo-cgi
Copy link
Collaborator

@weskubo-cgi weskubo-cgi commented Dec 24, 2025

Overview

For Ministry users, add a new Offerings screen (available through the sidebar) in order to easily see Pending Offerings and navigate to them for approval.

Pending

  • Determine if we should use separate Study Start/End Dates like the recent update to Offerings.

API

  • Added new endpoint and associated artifacts to retrieve pending offerings.

Web

  • Added new screen to view pending offerings.
  • Added sidebar navigation.
  • Added supporting dto/service/API code.

Screenshots

image

E2E Tests

  • EducationProgramOfferingAESTController(e2e)-getPendingOfferings - Added e2e tests to cover sort, search, inactive/expired programs.
image

@weskubo-cgi weskubo-cgi marked this pull request as draft December 24, 2025 00:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a new "Pending Offerings" queue feature for AEST (ministry) users, allowing them to view and manage education program offerings that require ministry review. The implementation includes a complete full-stack feature with frontend UI, backend API, comprehensive e2e testing, and proper pagination/sorting/search capabilities.

Key Changes:

  • Added a new AEST view for pending offerings with search, sort, and pagination capabilities
  • Implemented backend API endpoint to retrieve offerings with "Creation Pending" status for active programs
  • Added comprehensive e2e tests covering default/custom sorting, search functionality, and inactive program filtering

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
ViewPendingOfferings.vue New Vue component providing the UI for viewing pending offerings with search, sort, and pagination
DataTableContract.ts Added PendingOfferingsHeaders configuration for the data table columns
AppRoutes.ts Added PendingOfferings route definition
EducationProgramOffering.dto.ts (web) Added EducationProgramOfferingPendingAPIOutDTO interface for frontend
EducationProgramOfferingApi.ts Added getPendingOfferings API client method
EducationProgramOfferingService.ts Added getPendingOfferings service method wrapping the API call
AESTRoutes.ts Configured route for ViewPendingOfferings component
RouteConstants.ts Added PENDING_OFFERINGS route constant
AESTHomeSideBar.vue Added "Offerings" menu item linking to pending offerings view
education-program-offering.ts (test-utils) Enhanced factory to support name and submittedDate in initial values
datatable-database-mapping-utils.ts Added sort column mappings for submittedDate, offeringIntensity, and offeringType
education-program-offering.service.ts (backend) Implemented getPendingOfferings business logic with query building, filtering, sorting, and pagination
pagination.dto.ts Extended OfferingsPaginationOptionsAPIInDTO to support additional sort fields
education-program-offering.dto.ts (backend) Added EducationProgramOfferingPendingAPIOutDTO interface
education-program-offering.controller.service.ts Added getPendingOfferings method and removed duplicate service injection
education-program-offering.aest.controller.ts Added GET /pending endpoint with proper decorators and documentation
education-program-offering.aest.controller.getPendingOfferings.e2e-spec.ts Comprehensive e2e tests covering sorting, search, and filtering scenarios

@weskubo-cgi weskubo-cgi changed the title Feature/#4584 pending offerings queue #4584 - Pending Offerings queue Dec 29, 2025
@weskubo-cgi weskubo-cgi self-assigned this Dec 29, 2025
@weskubo-cgi weskubo-cgi marked this pull request as ready for review December 30, 2025 00:55
.auth(token, BEARER_AUTH_TYPE)
.expect(HttpStatus.OK);

expect(response.body.count).toBeGreaterThanOrEqual(2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let @dheepak-aot confirm this but we follow a standard for the expect block, you can find some examples in my PR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these goes for all other tests

Copy link
Collaborator Author

@weskubo-cgi weskubo-cgi Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with this approach to avoid blocks of duplicated code in the toEqual assertion. I have simplified the tests that don't return results. I'll look the team's guidance on whether to refactor the other tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes same for me, i just got asked to change it to their standard a few times now!

// Ministry token.
const token = await getAESTToken(AESTGroups.BusinessAdministrators);
// Include a search criteria that matches both offerings to avoid test data collisions.
const endpoint = `/aest/education-program-offering/pending?page=0&pageLimit=10&searchCriteria=Psychology`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can set a base endpoint to avoid duplicating the url many times

// Ministry token.
const token = await getAESTToken(AESTGroups.BusinessAdministrators);

const endpoint = `/aest/education-program-offering/pending?page=0&pageLimit=10&sortField=submittedDate&sortOrder=DESC`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit -> Id move the values to a variable and add them to the url using string interpolation, it makes it a bit easier to see what the request is sending

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I've done this for sortField/sortOrder/searchCriteria.

export class OfferingsPaginationOptionsAPIInDTO extends PaginationOptionsAPIInDTO {
@IsOptional()
@IsIn(["name"])
@IsIn(["name", "submittedDate", "offeringIntensity", "offeringType"])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incoming conflict here since i'm also making changes to this in my PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to create a separate DTO. I shouldn't have re-used this.

relations?.institutionLocation?.institution ?? relations.institution;
const offering = new EducationProgramOffering();
offering.name = faker.lorem.word();
offering.name = options?.initialValues?.name ?? faker.lorem.word();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coud have used this in my tests!!

loading.value = false;
};
onMounted(async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think you need a wrapper: onMounted(getofferings); should work

Copy link
Collaborator Author

@weskubo-cgi weskubo-cgi Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's required to wait for the async call to load and seems to be used more often than not in the code.

Copy link
Collaborator

@tiago-graf tiago-graf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just a few small comments, it would be nice to have the "study dates" column split into the start/end for consistency, i've done the changes in the offerings view (it also looks really cramped in the table)

@weskubo-cgi weskubo-cgi marked this pull request as draft December 31, 2025 00:43
@weskubo-cgi weskubo-cgi marked this pull request as ready for review December 31, 2025 18:49
@sonarqubecloud
Copy link

@github-actions
Copy link

Backend Unit Tests Coverage Report

Totals Coverage
Statements: 20.33% ( 4323 / 21268 )
Methods: 9.66% ( 252 / 2608 )
Lines: 24.47% ( 3705 / 15139 )
Branches: 10.39% ( 366 / 3521 )

@github-actions
Copy link

E2E Workflow Workers Coverage Report

Totals Coverage
Statements: 75.41% ( 1055 / 1399 )
Methods: 79.31% ( 115 / 145 )
Lines: 78.79% ( 769 / 976 )
Branches: 61.51% ( 171 / 278 )

@github-actions
Copy link

E2E Queue Consumers Coverage Report

Totals Coverage
Statements: 85.68% ( 1616 / 1886 )
Methods: 85% ( 187 / 220 )
Lines: 88.64% ( 1287 / 1452 )
Branches: 66.36% ( 142 / 214 )

@github-actions
Copy link

E2E SIMS API Coverage Report

Totals Coverage
Statements: 75.29% ( 8545 / 11349 )
Methods: 75.24% ( 1024 / 1361 )
Lines: 79.41% ( 6214 / 7825 )
Branches: 60.43% ( 1307 / 2163 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants