- Deleted the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer` endpoints as part of the architectural shift towards simplified resource management.
- Removed associated methods and configurations, including `ResourcesService.GetEncryptedResource`, `ResourcesService.GetInstaller`, and related properties in `ResourcesConfig`.
- Cleaned up environment variables and configuration files to reflect the removal of installer-related settings.
- Eliminated the `GetResourceRequest` DTO and its validator, along with the `WrongResourceName` error code.
- Updated documentation to clarify the changes in resource handling and the retirement of per-user file encryption.
Co-authored-by: Cursor <cursoragent@cursor.com>
4.5 KiB
Resource Management
Cycle 1 (2026-05-13) note — AZ-197 removed the
Hardwarefield fromGetResourceRequestand removedCheckResourceRequestandPOST /resources/checkentirely. AZ-183 introduced an OTA update path (POST /get-update,POST /resources/publish,IResourceUpdateService,Resourceentity,resourcestable,ResourcesConfig.EncryptionMasterKey) but it was reverted later the same day after the security audit (finding F-1) — the OTA delivery model itself was deemed obsolete.Cycle 2 (2026-05-14) note — the encrypted-download endpoint (
POST /resources/get/{dataFolder?}) and both installer endpoints (GET /resources/get-installer[/stage]) were removed as obsolete. With them wentResourcesService.GetEncryptedResource/GetInstaller,GetResourceRequest(andWrongResourceName = 50), and theResourcesConfig.SuiteInstallerFolder/SuiteStageInstallerFolderproperties + their env-var rows. The component is now upload + list + clear only and no longer depends on Authentication & Security for encryption primitives.
1. High-Level Overview
Purpose: filesystem-backed storage — upload, list, clear. Owned by IResourcesService.
Architectural Pattern: a single service over the local filesystem. No DB access, no cache.
Upstream dependencies: Data Layer (ResourcesConfig).
Downstream consumers: Admin API (resource endpoints).
2. Internal Interfaces
Interface: IResourcesService
| Method | Input | Output | Async | Error Types |
|---|---|---|---|---|
SaveResource |
string? dataFolder, IFormFile data, CancellationToken |
void | Yes | BusinessException(NoFileProvided) |
ListResources |
string? dataFolder, string? search, CancellationToken |
IEnumerable<string> |
Yes | DirectoryNotFoundException |
ClearFolder |
string? dataFolder |
void | No | None |
Removed:
GetEncryptedResource— removed in cycle 2 with the encrypted-download endpoint.GetInstaller— removed in cycle 2 with the installer endpoints.
Removed DTOs:
GetResourceRequest— removed in cycle 2 (file deleted).CheckResourceRequest— removed by AZ-197 (cycle 1).GetUpdateRequest,PublishResourceRequest— removed in the post-cycle-1 AZ-183 revert.
3. External API Specification
N/A — exposed through Admin API.
4. Data Access Patterns
ResourcesService is filesystem-only — no DB access, no cache.
| Source | Service | Pattern |
|---|---|---|
Filesystem (ResourcesConfig.ResourcesFolder) |
ResourcesService |
Direct read/write/delete |
Storage Estimates
- Filesystem: AI models, DLLs, etc. — potentially hundreds of MB per file.
5. Implementation Details
State Management: stateless — reads/writes directly to filesystem.
Key Dependencies: none beyond BCL (System.IO).
Error Handling Strategy:
SaveResourcethrowsBusinessException(NoFileProvided)for null uploads.- Missing files/directories throw standard .NET I/O exceptions.
ClearFoldersilently returns if directory doesn't exist.
6. Extensions and Helpers
None remaining after the cycle-2 removal of Security.EncryptTo and Security.GetApiEncryptionKey.
7. Caveats & Edge Cases
Known limitations (security-audit findings):
- F-2 (High) — no path traversal protection:
dataFolderparameter is concatenated directly withResourcesFolder. A maliciousdataFolderlike../../etccould access arbitrary filesystem paths. Filed as separate ticket. SaveResourcedeletes existing file before writing — no versioning or backup.ListResourceswraps a synchronousDirectoryInfo.GetFilesinTask.FromResult— not truly async.
Performance bottlenecks:
ClearFolderiterates and deletes files synchronously.
8. Dependency Graph
Must be implemented after: Data Layer (ResourcesConfig).
Can be implemented in parallel with: User Management, Authentication & Security.
Blocks: Admin API.
9. Logging Strategy
| Log Level | When | Example |
|---|---|---|
| INFO | Successful file save | Resource {data.FileName} Saved Successfully |
Log format: string interpolation via Serilog (security audit F-12 hygiene item: convert to structured form).
Log storage: console + rolling file (via Serilog configured in Program.cs).
Modules Covered
Services/ResourcesService(post-cycle-2 — onlySaveResource/ListResources/ClearFolderremain)Common/Configs/ResourcesConfig(post-cycle-2 — onlyResourcesFolderremains)