NestReader opened .pep files with FileStream(path, FileMode.Open), which
defaults to FileAccess.ReadWrite. The forge deployment bind-mounts
/mnt/pep-nest read-only, so every read-only open was rejected with
"Read-only file system" (EROFS) even though the code never writes.
Pass FileAccess.Read/FileShare.Read explicitly, matching DrawingReader
and ZipHelper elsewhere in PepLib.Core.
Once that was fixed, a second pre-existing bug surfaced: GetNestDetailsAsync
matched DB rows by NestName AND a literal Path comparison built from the
container's local mount path. NestHeader.Path stores the original Windows
UNC share path (e.g. \REMCOSRV0\pep nest\) from when PepApi ran directly
against the network share, so the comparison can never match post-Docker.
Match by NestName alone (ordered by most recent), consistent with the
fallback lookup already used elsewhere in NestsController.
- DrawingsController: rename 'name/{name}' to 'by-name/{name}' to
eliminate ambiguous match with '{name}/dxf' on path /drawings/name/dxf
- NestsController: add regex constraint to '{nestName}/download' and
'{nestName}/plates' to prevent collision with year-parameterized routes
when nestName is a 4-digit integer
- PepMcp/PepTools.cs: update GetDrawingByName URL to match renamed route
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The customer parameter on the parts search endpoint was doing exact
equality matching against CustomerName/CustID, so partial values like
"sull" would never match "Sullys". Changed to case-insensitive
Contains matching, consistent with how the search term is handled.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add POST parts/search/batch endpoint for searching multiple parts at once
- Extract SearchPartsInternalAsync helper method to support batch operations
- Include material description in part search results by looking up MaterialHeaders
- Add BatchPartSearchRequest and BatchPartSearchResponse models
- Add ResultsReturned field to single-part search response for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Support /nests/{year}/{nestName} routes to disambiguate older programs
that don't have year digits in the name. Refactor GetNestPathAsync to
handle 2025+ .pep files in flat directory vs older .zip files in year
subdirectories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add GET /api/nests/parts/search endpoint to search for parts across nests
by part name. Supports filtering by year and customer, with configurable
result limit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add GetPartsFromDbAsync(NestHeader) to aggregate quantities and plate indices
- Use NestName + CopyID filter to select correct program set
- Preserve original drawing name case; normalize grouping to avoid duplicates
- Replace PepHelper.GetParts(nest) usage with DB-driven result