# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - Added production deployment job triggered by semantic version tags (v1.0.0) with manual approval gate (#63) - Added production Helm values file with persistence enabled (20Gi PostgreSQL, 100Gi MinIO) (#63) - Added integration tests for production deployment (#63) - Added GitLab CI pipeline for feature branch deployments to dev namespace (#51) - Added `deploy_feature` job with dynamic hostnames and unique release names (#51) - Added `cleanup_feature` job with `on_stop` for automatic cleanup on merge (#51) - Added `values-dev.yaml` Helm values for lightweight ephemeral environments (#51) - Added main branch deployment to stage environment (#51) - Added post-deployment integration tests (#51) - Added internal proxy configuration for npm, pip, helm, and apt (#51) ### Changed - Deploy jobs now require all security scans to pass before deployment (added test_image, app_deps_scan, cve_scan, cve_sbom_analysis, app_sbom_analysis to dependencies) (#63) - Increased deploy job timeout from 5m to 10m (#63) - Added `--atomic` flag to Helm deployments for automatic rollback on failure - Adjusted dark mode color palette to use lighter background tones for better readability and reduced eye strain (#52) - Replaced project card grid with sortable data table on Home page for better handling of large project lists - Replaced package card grid with sortable data table on Project page for consistency - Replaced SortDropdown with table header sorting on Package page for consistency - Enabled sorting on supported table columns (name, created, updated) via clickable headers - Updated browser tab title to "Orchard" with custom favicon - Improved pod naming: Orchard pods now named `orchard-{env}-server-*` for clarity (#51) ### Fixed - Fixed deploy jobs running even when tests or security scans fail (changed rules from `when: always` to `when: on_success`) (#63) - Fixed python_tests job not using internal PyPI proxy (#63) - Fixed `cleanup_feature` job failing when branch is deleted (`GIT_STRATEGY: none`) (#51) - Fixed gitleaks false positives with fingerprints for historical commits (#51) - Fixed integration tests running when deploy fails (`when: on_success`) (#51) - Fixed static file serving for favicon and other files in frontend dist root - Fixed deploy jobs running when secrets scan fails (added `secrets` to deploy dependencies) - Fixed dev environment memory requests to equal limits per cluster Kyverno policy - Fixed init containers missing resource limits (Kyverno policy compliance) ### Removed - Removed unused `store_streaming()` method from storage.py (#51) ## [0.4.0] - 2026-01-12 ### Added - Added user authentication system with session-based login (#50) - `users` table with password hashing (bcrypt), admin flag, active status - `sessions` table for web login sessions (24-hour expiry) - `auth_settings` table for future OIDC configuration - Default admin user created on first boot (username: admin, password: admin) - Added auth API endpoints (#50) - `POST /api/v1/auth/login` - Login with username/password - `POST /api/v1/auth/logout` - Logout and clear session - `GET /api/v1/auth/me` - Get current user info - `POST /api/v1/auth/change-password` - Change own password - Added API key management with user ownership (#50) - `POST /api/v1/auth/keys` - Create API key (format: `orch_`) - `GET /api/v1/auth/keys` - List user's API keys - `DELETE /api/v1/auth/keys/{id}` - Revoke API key - Added `owner_id`, `scopes`, `description` columns to `api_keys` table - Added admin user management endpoints (#50) - `GET /api/v1/admin/users` - List all users - `POST /api/v1/admin/users` - Create user - `GET /api/v1/admin/users/{username}` - Get user details - `PUT /api/v1/admin/users/{username}` - Update user (admin/active status) - `POST /api/v1/admin/users/{username}/reset-password` - Reset password - Added `auth.py` module with AuthService class and FastAPI dependencies (#50) - Added auth schemas: LoginRequest, LoginResponse, UserResponse, APIKeyResponse (#50) - Added migration `006_auth_tables.sql` for auth database tables (#50) - Added frontend Login page with session management (#50) - Added frontend API Keys management page (#50) - Added frontend Admin Users page (admin-only) (#50) - Added AuthContext for frontend session state (#50) - Added user menu to Layout header with login/logout (#50) - Added 15 integration tests for auth system (#50) - Added reusable `DragDropUpload` component for artifact uploads (#8) - Drag-and-drop file selection with visual feedback - Click-to-browse fallback - Multiple file upload support with queue management - Real-time progress indicators with speed and ETA - File type and size validation (configurable) - Concurrent upload handling (configurable max concurrent) - Automatic retry with exponential backoff for network errors - Individual file status (pending, uploading, complete, failed) - Retry and remove actions per file - Auto-dismiss success messages after 5 seconds - Integrated DragDropUpload into PackagePage replacing basic file input (#8) - Added frontend testing infrastructure with Vitest and React Testing Library (#14) - Configured Vitest for React/TypeScript with jsdom - Added 24 unit tests for DragDropUpload component - Tests cover: rendering, drag-drop events, file validation, upload queue, progress, errors - Added chunked upload support for large files (#9) - Files >100MB automatically use chunked upload API (10MB chunks) - Client-side SHA256 hash computation via Web Crypto API - localStorage persistence for resume after browser close - Deduplication check at upload init phase - Added offline detection and network resilience (#12) - Automatic pause when browser goes offline - Auto-resume when connection restored - Offline banner UI with status message - XHR abort on network loss to prevent hung requests - Added download by artifact ID feature (#10) - Direct artifact ID input field on package page - Hex-only input validation with character count - File size and filename displayed in tag list - Added backend security tests (#15) - Path traversal prevention tests for upload/download - Malformed request handling tests - Checksum validation tests - 10 new security-focused integration tests - Added download verification with `verify` and `verify_mode` query parameters (#26) - `?verify=true&verify_mode=pre` - Pre-verification: verify before streaming (guaranteed no corrupt data) - `?verify=true&verify_mode=stream` - Streaming verification: verify while streaming (logs error if mismatch) - Added checksum response headers to all download endpoints (#27) - `X-Checksum-SHA256` - SHA256 hash of the artifact - `X-Content-Length` - File size in bytes - `X-Checksum-MD5` - MD5 hash (if available) - `ETag` - Artifact ID (SHA256) - `Digest` - RFC 3230 format sha-256 hash (base64) - `X-Verified` - Verification status (true/false/pending) - Added `checksum.py` module with SHA256 utilities (#26) - `compute_sha256()` and `compute_sha256_stream()` functions - `HashingStreamWrapper` for incremental hash computation - `VerifyingStreamWrapper` for stream verification - `verify_checksum()` and `verify_checksum_strict()` functions - `ChecksumMismatchError` exception with context - Added `get_verified()` and `get_stream_verified()` methods to storage layer (#26) - Added `logging_config.py` module with structured logging (#28) - JSON logging format for production - Request ID tracking via context variables - Verification failure logging with full context - Added `log_level` and `log_format` settings to configuration (#28) - Added 62 unit tests for checksum utilities and verification (#29) - Added 17 integration tests for download verification API (#29) - Added global artifacts endpoint `GET /api/v1/artifacts` with project/package/tag/size/date filters (#18) - Added global tags endpoint `GET /api/v1/tags` with project/package/search/date filters (#18) - Added wildcard pattern matching (`*`) for tag filters across all endpoints (#18) - Added comma-separated multi-value support for tag filters (#18) - Added `search` parameter to `/api/v1/uploads` for filename search (#18) - Added `tag` filter to `/api/v1/uploads` endpoint (#18) - Added `sort` and `order` parameters to `/api/v1/uploads` endpoint (#18) - Added `min_size` and `max_size` filters to package artifacts endpoint (#18) - Added `sort` and `order` parameters to package artifacts endpoint (#18) - Added `from` and `to` date filters to package tags endpoint (#18) - Added `GlobalArtifactResponse` and `GlobalTagResponse` schemas (#18) - Added S3 object verification before database commit during upload (#19) - Added S3 object cleanup on database commit failure (#19) - Added upload duration tracking (`duration_ms` field) (#19) - Added `User-Agent` header capture during uploads (#19) - Added `X-Checksum-SHA256` header support for client-side checksum verification (#19) - Added `status`, `error_message`, `client_checksum` columns to uploads table (#19) - Added `upload_locks` table for future concurrent upload conflict detection (#19) - Added consistency check endpoint `GET /api/v1/admin/consistency-check` (#19) - Added `PUT /api/v1/projects/{project}` endpoint for project updates with audit logging (#20) - Added `PUT /api/v1/project/{project}/packages/{package}` endpoint for package updates with audit logging (#20) - Added `artifact.download` audit logging to download endpoint (#20) - Added `ProjectHistory` and `PackageHistory` models with database triggers (#20) - Added migration `004_history_tables.sql` for project/package history (#20) - Added migration `005_upload_enhancements.sql` for upload status tracking (#19) - Added 9 integration tests for global artifacts/tags endpoints (#18) - Added global uploads query endpoint `GET /api/v1/uploads` with project/package/user/date filters (#18) - Added project-level uploads endpoint `GET /api/v1/project/{project}/uploads` (#18) - Added `has_more` field to pagination metadata for easier pagination UI (#18) - Added `upload_id`, `content_type`, `original_name`, `created_at` fields to upload response (#19) - Added audit log API endpoints with filtering and pagination (#20) - `GET /api/v1/audit-logs` - list all audit logs with action/resource/user/date filters - `GET /api/v1/projects/{project}/audit-logs` - project-scoped audit logs - `GET /api/v1/project/{project}/{package}/audit-logs` - package-scoped audit logs - Added upload history API endpoints (#20) - `GET /api/v1/project/{project}/{package}/uploads` - list upload events for a package - `GET /api/v1/artifact/{id}/uploads` - list all uploads of a specific artifact - Added artifact provenance endpoint `GET /api/v1/artifact/{id}/history` (#20) - Returns full artifact history including packages, tags, and upload events - Added audit logging for project.create, package.create, tag.create, tag.update, artifact.upload actions (#20) - Added `AuditLogResponse`, `UploadHistoryResponse`, `ArtifactProvenanceResponse` schemas (#20) - Added `TagHistoryDetailResponse` schema with artifact metadata (#20) - Added 31 integration tests for audit log, history, and upload query endpoints (#22) ### Changed - Standardized audit action naming to `{entity}.{action}` pattern (project.delete, package.delete, tag.delete) (#20) - Added `StorageBackend` protocol/interface for backend-agnostic storage (#33) - Added `health_check()` method to storage backend with `/health` endpoint integration (#33) - Added `verify_integrity()` method for post-upload hash validation (#33) - Added S3 configuration options: `s3_verify_ssl`, `s3_connect_timeout`, `s3_read_timeout`, `s3_max_retries` (#33) - Added `S3StorageUnavailableError` and `HashCollisionError` exception types (#33) - Added hash collision detection by comparing file sizes during deduplication (#33) - Added garbage collection endpoint `POST /api/v1/admin/garbage-collect` for orphaned artifacts (#36) - Added orphaned artifacts listing endpoint `GET /api/v1/admin/orphaned-artifacts` (#36) - Added global storage statistics endpoint `GET /api/v1/stats` (#34) - Added storage breakdown endpoint `GET /api/v1/stats/storage` (#34) - Added deduplication metrics endpoint `GET /api/v1/stats/deduplication` (#34) - Added per-project statistics endpoint `GET /api/v1/projects/{project}/stats` (#34) - Added per-package statistics endpoint `GET /api/v1/project/{project}/packages/{package}/stats` (#34) - Added per-artifact statistics endpoint `GET /api/v1/artifact/{id}/stats` (#34) - Added cross-project deduplication endpoint `GET /api/v1/stats/cross-project` (#34) - Added timeline statistics endpoint `GET /api/v1/stats/timeline` with daily/weekly/monthly periods (#34) - Added stats export endpoint `GET /api/v1/stats/export` with JSON/CSV formats (#34) - Added summary report endpoint `GET /api/v1/stats/report` with markdown/JSON formats (#34) - Added Dashboard page at `/dashboard` with storage and deduplication visualizations (#34) - Added pytest infrastructure with mock S3 client for unit testing (#35) - Added unit tests for SHA256 hash calculation (#35) - Added unit tests for duplicate detection and deduplication behavior (#35) - Added integration tests for upload scenarios and ref_count management (#35) - Added integration tests for S3 verification and failure cleanup (#35) - Added integration tests for all stats endpoints (#35) - Added integration tests for cascade deletion ref_count behavior (package/project delete) (#35) - Added integration tests for tag update ref_count adjustments (#35) - Added integration tests for garbage collection endpoints (#35) - Added integration tests for file size validation (#35) - Added test dependencies to requirements.txt (pytest, pytest-asyncio, pytest-cov, httpx, moto) (#35) - Added `ORCHARD_MAX_FILE_SIZE` config option (default: 10GB) for upload size limits (#37) - Added `ORCHARD_MIN_FILE_SIZE` config option (default: 1 byte, rejects empty files) (#37) - Added file size validation to upload and resumable upload endpoints (#37) - Added comprehensive deduplication design document (`docs/design/deduplication-design.md`) (#37) ### Fixed - Fixed Helm chart `minio.ingress` conflicting with Bitnami MinIO subchart by renaming to `minioIngress` (#48) - Fixed JSON report serialization error for Decimal types in `GET /api/v1/stats/report` (#34) - Fixed resumable upload double-counting ref_count when tag provided (removed manual increment, SQL triggers handle it) (#35) ## [0.3.0] - 2025-12-15 ### Changed - Changed default download mode from `proxy` to `presigned` for better performance (#48) ### Added - Added presigned URL support for direct S3 downloads (#48) - Added `ORCHARD_DOWNLOAD_MODE` config option (`presigned`, `redirect`, `proxy`) (#48) - Added `ORCHARD_PRESIGNED_URL_EXPIRY` config option (default: 3600 seconds) (#48) - Added `?mode=` query parameter to override download mode per-request (#48) - Added `/api/v1/project/{project}/{package}/+/{ref}/url` endpoint for getting presigned URLs (#48) - Added `PresignedUrlResponse` schema with URL, expiry, checksums, and artifact metadata (#48) - Added MinIO ingress support in Helm chart for presigned URL access (#48) - Added `orchard.download.mode` and `orchard.download.presignedUrlExpiry` Helm values (#48) - Added integrity verification workflow design document (#24) - Added `sha256` field to API responses for clarity (alias of `id`) (#25) - Added `checksum_sha1` field to artifacts table for compatibility (#25) - Added `s3_etag` field to artifacts table for S3 verification (#25) - Compute and store MD5, SHA1, and S3 ETag alongside SHA256 during upload (#25) - Added `Dockerfile.local` and `docker-compose.local.yml` for local development (#25) - Added migration script `003_checksum_fields.sql` for existing databases (#25) ## [0.2.0] - 2025-12-15 ### Added - Added `format` and `platform` fields to packages table (#16) - Added `checksum_md5` and `metadata` JSONB fields to artifacts table (#16) - Added `updated_at` field to tags table (#16) - Added `tag_name`, `user_agent`, `duration_ms`, `deduplicated`, `checksum_verified` fields to uploads table (#16) - Added `change_type` field to tag_history table (#16) - Added composite indexes for common query patterns (#16) - Added GIN indexes on JSONB fields for efficient JSON queries (#16) - Added partial index for public projects (#16) - Added database triggers for `updated_at` timestamps (#16) - Added database triggers for maintaining artifact `ref_count` accuracy (#16) - Added CHECK constraints for data integrity (`size > 0`, `ref_count >= 0`) (#16) - Added migration script `002_schema_enhancements.sql` for existing databases (#16) ### Changed - Updated images to use internal container BSF proxy (#46) ## [0.1.0] - 2025-12-12 ### Added - Added Prosper docker template config (#45) ### Changed - Changed the Dockerfile npm build arg to use the deps.global.bsf.tools URL as the default registry (#45)