- Use .NET 10 Web API with MongoDB integration
- Follow RESTful API design principles
- Implement proper error handling and logging
- Use dependency injection for services
- Main API project: backend/JwstDataAnalysis.API/
- Controllers:
- JwstDataController.cs - Main CRUD + lineage + viewer + thumbnail endpoints
- DataManagementController.cs - Faceted search, export, bulk operations
- MastController.cs - MAST search, import, metadata refresh
- CompositeController.cs - RGB composite generation
- MosaicController.cs - WCS mosaic generation
- AnalysisController.cs - Region statistics, source detection, FITS table data
- AuthController.cs - Authentication endpoints
- JobsController.cs - Unified job status, cancel, and result download
- DiscoveryController.cs - Featured targets and recipe suggestions
- SearchController.cs - Semantic search and re-index
- Models:
- JwstDataModel.cs - Core data models
- DataValidationModels.cs - DTOs and validation
- MastModels.cs - MAST request/response DTOs
- Services:
- MongoDBService.cs - Database operations
- MastService.cs - MAST HTTP client
- CompositeService.cs - RGB composite processing
- MosaicService.cs - WCS mosaic processing
- AnalysisService.cs - Region statistics, source detection, FITS table data
- ThumbnailService.cs - FITS thumbnail generation
- ThumbnailQueue.cs - Background queue for thumbnail batches
- ThumbnailBackgroundService.cs - BackgroundService processing queued batches
- CompositeQueue.cs - Bounded channel queue for async composite exports
- CompositeBackgroundService.cs - BackgroundService processing composite export jobs
- MosaicQueue.cs - Bounded channel queue for async mosaic jobs (export, save-to-library, observation mosaic)
- MosaicBackgroundService.cs - BackgroundService processing mosaic export, save, and observation mosaic jobs
- ImportJobTracker.cs - MAST import job tracking
- JobTracker.cs - Unified job tracker (MongoDB + in-memory cache, SignalR push)
- JobProgressNotifier.cs - SignalR progress notification
- JobReaperBackgroundService.cs - Expired job cleanup
- StartupReconciliationService.cs - Marks interrupted jobs as failed on restart
- IStorageProvider.cs - Storage abstraction interface
- LocalStorageProvider.cs - Local filesystem storage
- S3StorageProvider.cs - S3-compatible object storage (AWS SDK)
- StorageKeyHelper.cs - File path to storage key conversion
- DiscoveryService.cs - Featured targets and recipe engine proxy
- SemanticSearchService.cs - Semantic search engine proxy with MongoDB enrichment
- MastProxyHealthCheck.cs - IHealthCheck for MAST proxy service
- EmbeddingQueue.cs - Bounded channel queue for embedding jobs
- EmbeddingBackgroundService.cs - BackgroundService for embedding jobs
- AuthService.cs - User authentication
- JwtTokenService.cs - JWT token generation/validation
- Configuration: backend/JwstDataAnalysis.API/appsettings.json
MastProxy:BaseUrl— URL for the dedicated MAST proxy service (falls back toProcessingEngine:BaseUrl)
- Use async/await for all database operations
- Implement proper validation using DataAnnotations
- Use structured logging with ILogger
- Follow C# naming conventions (PascalCase for public members)
- Use MongoDB.Driver for database operations
- Implement proper CORS configuration for frontend integration
- GET /api/jwstdata - Get all data
- GET /api/jwstdata/{id} - Get by ID
- GET /api/jwstdata/type/{dataType} - Filter by type
- GET /api/jwstdata/status/{status} - Filter by status
- GET /api/jwstdata/search/{searchTerm} - Search data
- POST /api/jwstdata - Create new data
- PUT /api/jwstdata/{id} - Update data
- DELETE /api/jwstdata/{id} - Delete data
- GET /api/jwstdata/lineage - Get all lineage groups
- GET /api/jwstdata/lineage/{observationBaseId} - Get lineage for observation
- POST /api/jwstdata/migrate/processing-levels - Backfill processing levels
- POST /api/jwstdata/check-availability - Check if observations have existing data (AllowAnonymous)
- POST /api/jwstdata/generate-thumbnails - Queue thumbnail generation for all viewable records without thumbnails
- GET /api/jwstdata/{id}/thumbnail - Get thumbnail image for a record
Search:
- POST /api/mast/search/target - Search by target name
- POST /api/mast/search/coordinates - Search by RA/Dec
- POST /api/mast/search/observation - Search by observation ID
- POST /api/mast/search/program - Search by program ID
- POST /api/mast/products - Get data products for observation
Import:
- POST /api/mast/download - Download FITS files (no DB records)
- POST /api/mast/import - Download and import into MongoDB (supports
downloadSource: "auto", "s3", "http") - GET /api/mast/import-progress/{jobId} - Get import progress
- POST /api/mast/import/resume/{jobId} - Resume paused import
- POST /api/mast/import/cancel/{jobId} - Cancel active import
- GET /api/mast/import/resumable - List resumable jobs
- POST /api/mast/import/from-existing/{obsId} - Import from downloaded files
- GET /api/mast/import/check-files/{obsId} - Check if files exist
Metadata Management:
- POST /api/mast/refresh-metadata/{obsId} - Re-fetch metadata for observation
- POST /api/mast/refresh-metadata-all - Re-fetch metadata for all imports
- POST /api/datamanagement/search - Faceted search
- GET /api/datamanagement/statistics - Data distribution stats
- POST /api/datamanagement/export - Export data
- POST /api/datamanagement/bulk/tags - Bulk tag updates
- POST /api/datamanagement/bulk/status - Bulk status updates
- POST /api/composite/generate-nchannel - Generate N-channel composite with color mapping (1–N filters mapped to RGB via hue or explicit RGB weights)
- POST /api/composite/generate-nchannel-async - Same payload as
generate-nchannel, but routed through the job queue so authenticated wizard previews emit live SignalR progress (auth required, returns 202 with jobId, result via/api/jobs/{jobId}/result) - POST /api/composite/export-nchannel - Async N-channel composite export via job queue (requires auth, returns 202 with jobId, track via SignalR/polling, download via
/api/jobs/{jobId}/result) - WCS alignment: channels are reprojected to a common celestial grid before RGB stacking
- Per-channel controls: stretch, blackPoint, whitePoint, gamma, asinhA, curve, weight (0.0–2.0 intensity multiplier)
- N-channel adds: color (hue 0-360°, explicit RGB weights, or
luminance: truefor LRGB), label, wavelength_um - Luminance channel: at most one per composite; contributes detail (lightness) via HSL blending instead of color
- Optional global controls: overall.stretch, overall.blackPoint, overall.whitePoint, overall.gamma, overall.asinhA
- Access model: anonymous users can only use public data; authenticated users can use own/public/shared; admins can use all
- POST /api/mosaic/generate - Generate WCS-aligned mosaic from 2+ source data IDs (png/jpeg/fits)
- POST /api/mosaic/generate-and-save - Generate native FITS mosaic server-side and persist as a new data record
- POST /api/mosaic/export - Async mosaic image export via job queue (requires auth, returns 202 with jobId, track via SignalR/polling, download via
/api/jobs/{jobId}/result) - POST /api/mosaic/save - Async mosaic FITS save-to-library via job queue (requires auth, returns 202 with jobId, creates new data record)
- POST /api/mosaic/footprint - Compute WCS footprint polygons for selected source files
- Large-output pattern: use
exportorsavefor mosaics that would be too large for browser download/upload roundtrips - FITS mosaic metadata:
/mosaic/generateFITS responses include provenance in primary headers plus aSRCMETAextension containing source FITS header cards
- GET /api/jobs - List jobs for current user (query:
status,type) - GET /api/jobs/{jobId} - Get job status (ownership enforced). Returns a defensive snapshot —
JobStatus.Messagesis a server-side rolling buffer (cap 50, consecutive duplicates collapsed) the frontendLogPanelrehydrates from on SignalR reconnect (#1471). - POST /api/jobs/{jobId}/cancel - Cancel a job (ownership enforced)
- GET /api/jobs/{jobId}/result - Stream blob result or return data ID (extends TTL on access)
- GET /api/discovery/featured - Get curated featured targets list (12 targets with metadata, instruments, composite potential)
- POST /api/discovery/suggest-recipes - Generate ranked composite recipe suggestions for a set of observations (proxies to Python recipe engine)
- GET /api/search/semantic?q=...&topK=20&minScore=0.3 - Natural language search over FITS metadata (anonymous, results access-controlled)
- POST /api/search/reindex - Trigger full semantic re-index (admin only, returns 202 + jobId)
- GET /api/search/index-status - Semantic index health (total indexed, model loaded)
- POST /api/analysis/region-statistics - Compute statistics for rectangle/ellipse regions (mean, median, std, min, max, sum, pixel count)
- POST /api/analysis/detect-sources - Detect astronomical sources in a FITS image (returns list of sources with coordinates, flux, sharpness, roundness)
- Parameters:
thresholdSigma(1-50, default 5),fwhm(0.5-20, default 3),method(auto/daofind/iraf/segmentation),npixels,deblend
- Parameters:
- GET /api/analysis/table-info?dataId= - Get table HDU metadata for a FITS file
- GET /api/analysis/table-data?dataId=&hduIndex=&page=&pageSize=&sortColumn=&sortDirection=&search= - Get paginated table data from a FITS binary table HDU
- GET /api/analysis/spectral-data?dataId=&hduIndex=1 - Get spectral column arrays (wavelength, flux, error) for chart rendering
The following query parameters are available on both GET /api/jwstdata/{id}/preview and GET /api/jwstdata/{id}/histogram:
smoothMethod: Filter method —gaussian,median,box,astropy_gaussian,astropy_box, or""(disabled, default)smoothSigma: Gaussian sigma (0.1-10.0, default 1.0) — used for gaussian/astropy_gaussian methodssmoothSize: Kernel size (1-25, odd only, default 3) — used for median/box/astropy_box methods
-
JwstDataModel: Main data entity with flexible metadata
ProcessingLevel: JWST pipeline stage (L1, L2a, L2b, L3)ObservationBaseId: Groups related files by observationExposureId: Finer-grained lineage trackingMetadata: Dictionary storing all MAST fields withmast_prefixIsViewable: true for images, false for tables/catalogs
-
ImageMetadata: For image-specific data
- Core:
targetName,instrument,filter,exposureTime,observationDate - MAST fields:
wavelengthRange,calibrationLevel,proposalId,proposalPi,observationTitle - WCS:
coordinateSystem,wcs(CRVAL1, CRVAL2)
- Core:
-
SensorMetadata: For sensor/spectral data
-
SpectralMetadata: For spectral analysis data
-
CalibrationMetadata: For calibration files
-
ProcessingResult: For processing outcomes
-
LineageResponse/LineageFileInfo: DTOs for lineage queries
-
MetadataRefreshResponse: Response for metadata refresh operations
- Current MongoDB credentials are for development only
- JWT Bearer authentication is implemented (AuthService + JwtTokenService)
- Use environment variables for sensitive configuration
- ALWAYS create a Pull Request (PR) after pushing
- NEVER push directly to
main - Workflow:
- Create feature branch (
git checkout -b feature/name) - Commit changes (
git commit) - Push to origin (
git push) - IMMEDIATELY create PR (
gh pr create)
- Create feature branch (
- Use conventional commit messages
- Atomic, focused commits