Skip to content

Commit ef5e581

Browse files
committed
Merge branch 'feat/fam-auth-1-2-signin' into feat/fam-auth-1-3-rolegate
2 parents 61c49ae + 01ad13c commit ef5e581

53 files changed

Lines changed: 7199 additions & 60 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/analysis.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ jobs:
4040
java-cache: maven
4141
java-distribution: temurin
4242
java-version: "21"
43-
# cpd.exclusions: RoadGroupLookup is a verbatim port of the legacy RMG tables
44-
# (RoadGroupUtil.setRmgByTfaTsbNumberCode/setRmgByTflNumberCode), where ~18 of the
45-
# TSA cases are token-identical apart from their literals. CPD reads that as 174
46-
# duplicated lines; the table is the business rule and must not be de-duplicated.
43+
# cpd.exclusions: both RoadGroup lookups are verbatim ports of the legacy RMG tables,
44+
# where ~18 of the TSA cases are token-identical apart from their literals. CPD reads
45+
# that as ~174 duplicated lines each; the tables ARE the business rule and must not be
46+
# de-duplicated. schedule6 ports setRmgByTfaTsbNumberCode/setRmgByTflNumberCode;
47+
# schedule10 ports setRG10ByTsaTsbNumberCode/setRG10ByTflNumberCode.
48+
# They are NOT interchangeable: the same inputs map to DIFFERENT road groups (TSA 01 ->
49+
# 15 vs 11, TSA 08 -> 10 vs 7, TFL 08 -> 7 vs 10), so "resolving" the duplication by
50+
# merging them would silently corrupt one schedule's derived, user-visible Road Group.
4751
# xmlReportPaths: with the ITs running, the pom's jacoco `merge`/`report-merged` executions
4852
# produce the union of surefire and failsafe coverage. Sonar would otherwise keep reading
4953
# the unit-only report and still count IT-covered lines as uncovered.
@@ -52,7 +56,7 @@ jobs:
5256
-Dsonar.projectKey=bcgov-sonarcloud_nr-ilcr_backend
5357
-Dsonar.host.url=https://sonarcloud.io
5458
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco-merged/jacoco.xml
55-
-Dsonar.cpd.exclusions=**/schedule6/RoadGroupLookup.java
59+
-Dsonar.cpd.exclusions=**/schedule6/RoadGroupLookup.java,**/schedule10/RoadGroup10Lookup.java
5660
sonar_token: ${{ secrets.sonar_token_backend }}
5761
triggers: ('backend/')
5862

.github/workflows/reusable-tests.yml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ jobs:
6868
# raw-Playwright frontend/e2e). Only the DATA-INDEPENDENT `@smoke` project runs here: it aborts /api,
6969
# so it needs neither the seeded delivery Oracle nor the pinned fixtures the deployed env lacks. The
7070
# full data-backed suite (setup + chromium — SCH1/SEC) is a LOCAL/manual gate; see frontend/e2e/README.md.
71+
#
72+
# The smoke runs against a LOCAL Vite server on localhost, NOT the deployed PR URL. Since Story 1.2
73+
# turned auth on, mock auth is (by design) disabled off-localhost — `isMockAuth()` double-gates on
74+
# `isLocalHost()` (src/env.ts) — so an anonymous visit to a deployed host correctly bounces to the
75+
# FAM/Cognito Hosted UI and never renders the shell. On localhost with the repo-default
76+
# `{ mockUser: true }` config the shell renders client-side, keeping this smoke auth- AND
77+
# backend-independent (the scenarios still abort every /api call).
7178
defaults:
7279
run:
7380
working-directory: frontend/e2e
@@ -82,17 +89,28 @@ jobs:
8289
node-version: 24
8390
cache: "npm"
8491
cache-dependency-path: frontend/e2e/package-lock.json
85-
- name: Install dependencies
92+
- name: Install e2e dependencies
8693
run: |
8794
npm ci
8895
npx playwright install --with-deps chromium
8996
90-
- name: Run smoke (data-independent)
97+
- name: Install frontend
98+
working-directory: frontend
99+
run: npm ci
100+
101+
- name: Run smoke (data-independent, localhost mock auth)
102+
working-directory: frontend
91103
env:
92-
E2E_BASE_URL: https://${{ env.PREFIX }}.${{ env.DOMAIN }}/
93104
CI: "true"
94105
run: |
95-
npm test -- --project=smoke --reporter=html
106+
# Serve the app on localhost so mock auth engages (isMockAuth() requires localhost); the
107+
# @smoke scenarios abort /api, so no backend is needed. No E2E_BASE_URL → the Playwright
108+
# config defaults baseURL to http://localhost:3000.
109+
npm run dev -- --port 3000 &
110+
DEV_PID=$!
111+
npx --yes wait-on -t 120000 http://localhost:3000
112+
( cd e2e && npm test -- --project=smoke --reporter=html )
113+
kill "$DEV_PID" 2>/dev/null || true
96114
97115
- uses: actions/upload-artifact@v7
98116
if: (! cancelled())

backend/src/main/java/ca/bc/gov/nrs/ilcr/configuration/SpringDataJdbcConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import ca.bc.gov.nrs.ilcr.assignment.MillUserProfileXrefRepository;
44
import ca.bc.gov.nrs.ilcr.millcontext.MillContextRepository;
55
import ca.bc.gov.nrs.ilcr.schedule1.Schedule1Repository;
6+
import ca.bc.gov.nrs.ilcr.schedule10.Schedule10Repository;
67
import ca.bc.gov.nrs.ilcr.schedule11.Schedule11Repository;
78
import ca.bc.gov.nrs.ilcr.schedule2.Schedule2Repository;
89
import ca.bc.gov.nrs.ilcr.schedule3.Schedule3Repository;
@@ -47,6 +48,7 @@
4748
Schedule7bRepository.class,
4849
Schedule8Repository.class,
4950
Schedule9Repository.class,
51+
Schedule10Repository.class,
5052
Schedule11Repository.class,
5153
MillContextRepository.class,
5254
MillUserProfileXrefRepository.class
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package ca.bc.gov.nrs.ilcr.schedule10;
2+
3+
import java.math.BigDecimal;
4+
import org.springframework.data.annotation.Id;
5+
import org.springframework.data.relational.core.mapping.Column;
6+
import org.springframework.data.relational.core.mapping.Table;
7+
8+
/**
9+
* One Schedule 10 road-detail row — a {@code THE.ROAD_CONSTRUCTION_REPRT_DTL} row.
10+
*
11+
* <p>Shape is delivery-verified (Story 11.1 Task 1 gate (i)). Costs are NOT columns here: they are
12+
* keyed rows in {@code THE.ILCR_COST_REPORT_DETAIL} joined by
13+
* {@code ROAD_CONSTRUCTION_REPRT_DTL_ID} (BR-08), reassembled by {@link Schedule10Repository}.
14+
*
15+
* <p><strong>Three delivery columns are deliberately absent</strong> — business-directed departures
16+
* LD-1/LD-2/LD-3 remove ASM Code ({@code RELATIVE_SOIL_MOISTUR_RGM_CODE}), Soil Moisture Code
17+
* ({@code ILCR_SOIL_MOISTURE_CODE}) and Boulder Area % ({@code BOULDER_AREA_PCT}). They still exist
18+
* in the table and the first two are {@code NOT NULL} there, which is a hard problem for the Story
19+
* 11.2 write path but none at all for this read: we simply never select them.
20+
*
21+
* <p><strong>{@code REL_SOIL_MOIST_RGM_CLS_CODE} (RSMR Class) is nullable</strong> despite the
22+
* legacy view marking it required — it is populated in only 18 of 66 real delivery rows.
23+
*
24+
* <p>All numerics are boxed. Oracle {@code NUMBER} arrives as {@code BigDecimal} and null is a
25+
* first-class value throughout Schedule 10 (see {@link Schedule10Amounts}).
26+
*/
27+
@Table(name = "ROAD_CONSTRUCTION_REPRT_DTL", schema = "THE")
28+
public record RoadConstructionReportDetailEntity(
29+
@Id @Column("ROAD_CONSTRUCTION_REPRT_DTL_ID") Integer roadConstructionReprtDtlId,
30+
@Column("ROAD_CONSTRUCTION_REPRT_ID") Integer roadConstructionReprtId,
31+
@Column("ROAD_NAME") String roadName,
32+
@Column("SIDE_SLOPE_PCT") Integer sideSlopePct,
33+
@Column("ILCR_ROAD_LIFETIME_CODE") String ilcrRoadLifetimeCode,
34+
@Column("RIPPABLE_ROCK_PCT") Integer rippableRockPct,
35+
@Column("SOLID_ROCK_PCT") Integer solidRockPct,
36+
@Column("COARSE_MATERIAL_PCT") Integer coarseMaterialPct,
37+
@Column("BECBIOGEO_CATALOGUE_ID") Integer becbiogeoCatalogueId,
38+
@Column("FINE_MATERIAL_PCT") Integer fineMaterialPct,
39+
@Column("ORGANIC_MATERIAL_PCT") Integer organicMaterialPct,
40+
@Column("SUB_GRADE_LENGTH") BigDecimal subGradeLength,
41+
@Column("DETAIL_ENGINEERING_COST_IND") String detailEngineeringCostInd,
42+
@Column("END_HAUL_DISTANCE") BigDecimal endHaulDistance,
43+
@Column("END_HAUL_VOLUME") BigDecimal endHaulVolume,
44+
@Column("OVERLAND_DISTANCE") BigDecimal overlandDistance,
45+
@Column("OVERLAND_VOLUME") BigDecimal overlandVolume,
46+
@Column("ILCR_ROAD_BALLAST_METHOD_CODE") String ilcrRoadBallastMethodCode,
47+
@Column("SUB_GRADE_SURFACE_WIDTH") BigDecimal subGradeSurfaceWidth,
48+
@Column("ILCR_ROAD_BALLAST_MATERL_CODE") String ilcrRoadBallastMaterlCode,
49+
@Column("STABILIZING_LENGTH") BigDecimal stabilizingLength,
50+
@Column("STABILIZING_SURFACE_WIDTH") BigDecimal stabilizingSurfaceWidth,
51+
@Column("STABILIZING_DEPTH") BigDecimal stabilizingDepth,
52+
@Column("STABILIZING_DISTANCE_TO_SOURCE") BigDecimal stabilizingDistanceToSource,
53+
@Column("REL_SOIL_MOIST_RGM_CLS_CODE") String relSoilMoistRgmClsCode,
54+
@Column("COMMENTS") String comments,
55+
@Column("REVISION_COUNT") Integer revisionCount) {
56+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package ca.bc.gov.nrs.ilcr.schedule10;
2+
3+
import org.springframework.data.annotation.Id;
4+
import org.springframework.data.relational.core.mapping.Column;
5+
import org.springframework.data.relational.core.mapping.Table;
6+
7+
/**
8+
* A Schedule 10 construction page — one {@code THE.ROAD_CONSTRUCTION_REPRT} row.
9+
*
10+
* <p>Shape is delivery-verified (Story 11.1 Task 1 gate (i)). Two things to note:
11+
*
12+
* <p><strong>There is no Road Group column.</strong> {@code RMG} is derived on every read from the
13+
* TSA/TSB or TFL tables via {@link RoadGroup10Lookup}, never stored.
14+
*
15+
* <p><strong>{@code CONSTRUCTION_DIVISION_NAME} is {@code VARCHAR2(20)}</strong> even though
16+
* {@code schedule10.xhtml:140} sets {@code maxlength="30"} — a real defect recorded for Story 11.2.
17+
* This read story is unaffected.
18+
*
19+
* <p>Numeric columns are boxed: ojdbc maps Oracle {@code NUMBER} to {@code BigDecimal} and a
20+
* primitive would NPE on a null. {@code REPORT_YEAR} and {@code ILCR_MILL_ID} are {@code NOT NULL}
21+
* in delivery but stay boxed for consistency with the shipped schedules.
22+
*/
23+
@Table(name = "ROAD_CONSTRUCTION_REPRT", schema = "THE")
24+
public record RoadConstructionReportEntity(
25+
@Id @Column("ROAD_CONSTRUCTION_REPRT_ID") Integer roadConstructionReprtId,
26+
@Column("REPORT_YEAR") Integer reportYear,
27+
@Column("ILCR_MILL_ID") Long ilcrMillId,
28+
@Column("ILCR_CATEGORY_ID") String ilcrCategoryId,
29+
@Column("CONSTRUCTION_PERIOD") String constructionPeriod,
30+
@Column("CONSTRUCTION_DIVISION_NAME") String constructionDivisionName,
31+
@Column("ILCR_FOREST_REGION_CODE") String ilcrForestRegionCode,
32+
@Column("TSB_NUMBER_CODE") String tsbNumberCode,
33+
@Column("TSA_NUMBER") String tsaNumber,
34+
@Column("TFL_NUMBER_CODE") String tflNumberCode,
35+
@Column("REVISION_COUNT") Integer revisionCount) {
36+
}

0 commit comments

Comments
 (0)