Problem Summary

In Gallery Creator, Springs and Springs Pro are listed as separate camps. The observed behavior:

Bug Selecting Springs Pro → zero photos shown.
Selecting Springs → all photos shown, including those belonging to Springs Pro campers.

Jesse's diagnosis: "Springs has a Final Destination folder, and Springs Pro does not have one at all."

Root Cause 1: Location Name Collision

Springs and Springs Pro share the same physical location, "Pine Cove Springs." When bridge-api resolves a folder path for any YouthCamp-type session it calls resolveAppDisplayLocation, which strips the "Pine Cove " prefix from the location name:

// bridge-api/server/src/service/camp-session.service.ts:90
static resolveAppDisplayLocation(campSessionDTO, showCitySession = false): string {
  // YouthCamp: resolves to location.name, then strips "Pine Cove "
  locationName = CampSessionService.resolveLocationName(campSessionDTO);
  locationName = locationName.replace('Pine Cove ', '');
  // Both "Springs" and "Springs Pro" resolve to → "Springs"
}

Without an override, both camps produce a locationName of "Springs". All S3 paths and gallery album folder paths for both camps collapse into the same Springs folder.

Root Cause 2: The Override Was Never Triggered

gallery-folder-generator.ts has a Springs Pro override in two places:

// bridge-api/.../gallery-folder-generator.ts:167–171  (standard session folder creation)
let locationName = CampSessionService.resolveAppDisplayLocation(campSession, true);
if (campSession.camp.name === 'Springs Pro') {
    locationName = 'Springs Pro';
}
locationName = locationName.replace('Pine Cove ', '');

The same override is at lines 776–778 for default album row creation.

Why this hasn't helped The override is correct code — but it only runs when the folder-creation function is invoked for a Springs Pro session. Jesse reports no Final Destination folder exists for Springs Pro, meaning the setup endpoint was never called for Springs Pro camp sessions. The code is ready; the provisioning step was skipped.

Root Cause 3: The LIKE Query Bug

Gallery Creator searches photos by filtering image.source (the S3 path) with a LIKE pattern:

// bridge-api/server/src/service/image.service.ts:170
query.andWhere('image.source LIKE :campPattern', { campPattern: `%/${camp}%` });

When camp = "Springs" the pattern is %/Springs%, which matches both:

S3 PathMatches %/Springs%?
2025/Springs/Week 1/Photos/1Sun/…Yes (intended)
2025/Springs Pro/Week 1/Photos/1Sun/…Yes (unintended — "Springs Pro" contains "Springs")

When camp = "Springs Pro" the pattern %/Springs Pro% is correct in theory — but since no photos exist at a /Springs Pro/ path, the query returns nothing.

Album-Level Filtering Is Fine

Gallery album queries use an exact campName match, not a LIKE:

query.andWhere('ga.campName = :camp', { camp });

Springs Pro albums exist as distinct rows in the database. The problem is upstream — no photos have ever been routed to Springs Pro S3 paths, so album photo lookups return empty even though the album rows are correct.

Solutions

Alternative

Option A — Shared Photo Pool

Change Springs Pro's photo query to also search Springs-pathed photos. Both camps draw from the same S3 folder.

Pros

  • No S3 provisioning required
  • Fastest to implement

Cons

  • Springs and Springs Pro galleries permanently cross-contaminate
  • Ties two distinct camps together in the data layer
  • Requires extra filtering to exclude wrong-camp campers

Secondary Fix: Tighten the LIKE Pattern

Even after Option B is applied, the LIKE query in image.service.ts:170 should be hardened with a trailing slash so Springs no longer matches Springs Pro paths:

// Current — matches both /Springs/ and /Springs Pro/
campPattern: `%/${camp}%`

// Fixed — exact path segment boundary
campPattern: `%/${camp}/%`

Key Files

FileLinesWhat It Does
bridge-api/…/gallery-folder-generator.ts 167–173, 775–779 Springs Pro locationName override for folder creation
bridge-api/…/camp-session.service.ts 90–121 resolveAppDisplayLocation — where both camps collapse to "Springs"
bridge-api/…/image.service.ts 165–172, 355–365 LIKE query that accidentally matches Springs Pro when filtering Springs
bridge-api/…/gallery-album.service.ts 1009–1075 Album filtering by exact campName (correct, not the problem)
sidekick-portal/…/GalleryCreator/GalleryCreator.tsx Frontend; no Springs-specific logic; delegates entirely to the API