Commit Graph

9 Commits

Author SHA1 Message Date
JSLMPR bd620fc773 The storage port now has a real staging operation:
- materializeSourceObject(String sourceObjectKey, Path targetPath) in src/main/java/org/example/videoclips/storage/ObjectStoragePort.java

  Both storage adapters implement it:

  - src/main/java/org/example/videoclips/storage/InMemoryObjectStorageAdapter.java creates a placeholder local file for the default stub flow
  - src/main/java/org/example/videoclips/storage/S3ObjectStorageAdapter.java downloads the object from S3-compatible storage to the worker filesystem

  The processor now uses that seam before clip generation starts. In src/main/java/org/example/videoclips/processing/ClipProcessor.java it resolves the local input path under the configured FFmpeg
  input directory, materializes the source object there, and records a SOURCE_MATERIALIZED job event before invoking the clipper.

  That means the FFmpeg path is no longer relying on a file appearing magically in the input directory. The next concrete step is to finish the output side the same way: persist generated clip
  object keys and push FFmpeg outputs back through the storage port instead of only creating clip metadata in memory.
2026-07-09 00:02:05 +02:00
JSLMPR 9df97362ba The core change is that VideoAsset now carries sourceObjectKey, and that value is persisted through the JPA entity and migrations:
- src/main/java/org/example/videoclips/domain/VideoAsset.java
  - src/main/java/org/example/videoclips/persistence/entity/VideoAssetEntity.java
  - src/main/java/org/example/videoclips/persistence/JpaVideoClippingMapper.java
  - src/main/resources/db/migration/V4__video_asset_source_object_key.sql

  createAsset(...) now assigns a stable source object key of the form uploads/{uploadId}/source, and that value is exposed back through the asset read response in src/main/java/org/example/
  videoclips/application/VideoAssetService.java. I also threaded that source-object reference through the clipper contract in src/main/java/org/example/videoclips/processing/VideoClipperPort.java,
  so src/main/java/org/example/videoclips/processing/ClipProcessor.java passes a real persisted object reference into the processing adapter. The FFmpeg adapter now resolves its input path from
  that source object key instead of assuming {assetId}.mp4.

  I also completed the multipart upload seam:

  - UploadSession now stores providerUploadId
  - the storage port gained completeMultipartUpload(...)
  - the service now calls storage completion during uploads:complete
  - the new metadata is migrated in src/main/resources/db/migration/V3__upload_session_provider_metadata.sql

  Finally, I extended the MockMvc test to assert that the asset read response now includes the expected sourceObjectKey in src/test/java/org/example/videoclips/api/VideoAssetControllerTest.java.
2026-07-08 23:57:09 +02:00
JSLMPR 7e8a214c3e uploads:complete now goes through the storage port instead of being a pure metadata flip. I added provider upload metadata to UploadSession, wired it through src/main/java/org/example/videoclips/
application/VideoAssetService.java, src/main/java/org/example/videoclips/storage/ObjectStoragePort.java, and the JPA upload-session mapping, and added a migration at src/main/resources/db/
  migration/V3__upload_session_provider_metadata.sql. The storage adapters now expose completeMultipartUpload(...), with the in-memory adapter as a no-op and the S3 adapter implementing the AWS
  multipart completion call.

  I also added an FFmpeg-backed clipper adapter in src/main/java/org/example/videoclips/processing/FfmpegVideoClipperAdapter.java, controlled by video-clipping.processing=ffmpeg. The stub clipper
  remains the default via video-clipping.processing=stub, so the app still has a safe fallback. The new FFmpeg configuration lives under src/main/java/org/example/videoclips/config/
  VideoClippingProperties.java and src/main/resources/application.properties.

  I also extended the test expectations so the upload-session response now verifies providerUploadId in src/test/java/org/example/videoclips/api/VideoAssetControllerTest.java.
2026-07-08 23:54:16 +02:00
JSLMPR 67c7b65639 The storage port now has an opt-in S3-compatible implementation in src/main/java/org/example/videoclips/storage/S3ObjectStorageAdapter.java. It uses the AWS SDK presigner to generate multipart
upload part URLs and signed clip download URLs when video-clipping.storage=s3. The current in-memory adapter remains the default. I also added the supporting configuration fields in src/main/
  java/org/example/videoclips/config/VideoClippingProperties.java and default values in src/main/resources/application.properties.

  The queue port now has a durable database-backed implementation in src/main/java/org/example/videoclips/queue/DatabaseBackedClipJobQueueAdapter.java. It persists queue messages in a new
  queue_messages table from src/main/resources/db/migration/V2__queue_messages.sql, polls them on a schedule, and dispatches them through the existing processor. I updated src/main/java/org/
  example/videoclips/processing/ClipProcessor.java so processing failures propagate back to the queue adapter instead of being swallowed.

  I also enabled scheduling in src/main/java/org/example/videoclips/VideoClippingApplication.java, added the AWS SDK dependency in pom.xml, and updated src/main/resources/application-jpa.properties
  so the JPA profile uses the database queue by default.
2026-07-08 23:47:05 +02:00
JSLMPR 517a4e1146 The service now has an opt-in JPA/Flyway adapter instead of only the in-memory repository. I introduced VideoClippingRepository as the application-facing persistence contract and wired both src/
main/java/org/example/videoclips/infrastructure/InMemoryVideoAssetRepository.java and the new src/main/java/org/example/videoclips/persistence/JpaVideoClippingRepository.java behind it. The JPA
  path includes entity models, Spring Data repositories, a mapper, and a Flyway baseline migration at src/main/resources/db/migration/V1__init_video_clipping.sql. I also added the required
  dependencies in pom.xml.

  The default runtime still uses the in-memory repository via video-clipping.repository=memory, so existing behavior stays intact. There’s now a ready-to-use JPA profile in src/main/resources/
  application-jpa.properties that uses H2 in PostgreSQL mode for local bring-up. That gives the codebase a real persistence lane without forcing the switch yet.
2026-07-08 22:44:18 +02:00
JSLMPR 067fc782a3 DELETE /v1/video-assets/{assetId} now does more than flip a flag. In src/main/java/org/example/videoclips/application/VideoAssetService.java it now:
- cancels any active jobs for that asset
  - aborts an open upload session
  - records an asset deletion event
  - prevents clip download URLs from being created for clips that belong to deleted assets

  I also added a regression test for that behavior in src/test/java/org/example/videoclips/api/VideoAssetControllerTest.java, along with the earlier repository-port and operations work. The
  application and worker layers now depend on VideoClippingRepository instead of the concrete in-memory adapter, which is the right base for a future PostgreSQL adapter.
2026-07-08 22:39:54 +02:00
JSLMPR bcf2fa40bb This pass added explicit upload-session state and stricter media validation. GET /v1/video-assets/{assetId}/upload-session is now implemented in src/main/java/org/example/videoclips/api/
VideoAssetController.java, backed by richer UploadSession metadata in src/main/java/org/example/videoclips/domain/UploadSession.java. The service now stores part size, part count, expiry, and
  completion time, and returns them through src/main/java/org/example/videoclips/application/VideoAssetService.java. I also added a configurable media-type allowlist in src/main/java/org/example/
  videoclips/config/VideoClippingProperties.java and reject unsupported uploads with 415 via src/main/java/org/example/videoclips/application/UnsupportedMediaTypeException.java and src/main/java/
  org/example/videoclips/api/ApiExceptionHandler.java.

  I also added adapter-level health visibility for operations. src/main/java/org/example/videoclips/observability/ObjectStorageHealthIndicator.java and src/main/java/org/example/videoclips/
  observability/QueueHealthIndicator.java now expose basic readiness details through Actuator. Tests were extended in src/test/java/org/example/videoclips/api/VideoAssetControllerTest.java to cover
  the upload-session read path and the unsupported-media-type case.
2026-07-08 22:28:20 +02:00
JSLMPR 372d2d6fa6 wip 2026-07-08 22:25:12 +02:00
JSLMPR 01b83cec20 initial 2026-07-08 17:00:58 +02:00