Skip to content

Run 1: common-module Library

Implements the shared S3 asset management library in common-module and refactors CsvS3BucketDirectAccess to use it. Corresponds to specification.md Phase 0 + Phase 2a (tasks T-1 through T-5).

Author: Claude Code for jmpicnic | Date: 2026-03-31 | Status: Planning

Implement three new classes (AssetKeyGenerator, CdnUrlResolver, S3AssetService) in common-module’s cards.arda.common.lib.infra.storage package, refactor CsvS3BucketDirectAccess to delegate S3 primitives to S3AssetService (TD-18, TD-24), and verify no regressions in existing CSV functionality.

#CriterionVerification CommandExpected Output
1common-module worktree existsgit -C /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module branch --show-currentjmpicnic/item-image-upload-backend
2operations worktree exists (for baseline)git -C /Users/jmp/code/arda/projects/image-upload-backend-worktrees/operations branch --show-currentjmpicnic/item-image-upload-backend
3No uncommitted changes in common-modulegit -C /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module status --porcelainEmpty
4Worktree based on jmpicnic/claude-prepgit -C /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module log --oneline -1 origin/jmpicnic/claude-prepMatches HEAD ancestor
#TaskPersonaDepends OnStatusAcceptance Criteria
1.1Baseline verification: make clean build both reposback-end-engineerPendingAll existing tests pass in both common-module and operations; test counts and coverage recorded
1.2Implement AssetKeyGenerator + AssetKeyGeneratorTestback-end-engineer1.1Pending7 test cases pass: namespace validation, key format, tenant prefix, UUID uniqueness, content type mapping, unsupported type failure (spec T-2)
1.3Implement CdnUrlResolver + CdnUrlResolverTestback-end-engineer1.1Pending7 test cases pass: URL resolution, valid CDN URL, wrong host, cross-tenant, unexpected path, malformed URL, empty string (spec T-3)
1.4Implement S3AssetService + S3AssetServiceTestback-end-engineer1.2, 1.3Pending7 test cases pass with MockAWS: presigned PUT, presigned POST, POST policy conditions, HEAD success, HEAD missing, HEAD metadata match, HEAD metadata mismatch. Pre-implementation: verify AWS SDK presigned POST support (spec T-4)
1.5Refactor CsvS3BucketDirectAccess to delegate to S3AssetServiceback-end-engineer1.4PendingExisting CsvS3DirectAccessTest and S3BucketAccessTest pass. Factory methods accept S3AssetService parameter (TD-24). make clean build succeeds (spec T-5)
1.6Quality review of T-2 through T-5 implementationquality-reviewer1.5PendingCode review report: no anti-patterns, follows kotlin-coding conventions, appropriate use of Result<T> and AppError hierarchy
1.7Address quality review findings (if any)back-end-engineer1.6PendingAll actionable findings resolved. make clean build still passes

Single directory — no intra-repo worktrees needed. One back-end-engineer works sequentially through T-2 → T-3 → T-4 → T-5 in the same worktree.

Working directory: /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module Branch: jmpicnic/item-image-upload-backend Base branch: jmpicnic/claude-prep

T-2 and T-3 are independent new files, but parallelism is not worthwhile — each is a single source + test file, and worktree overhead exceeds time savings.

  • Sequential chain: 1.1 → 1.2 → 1.4 → 1.5 → 1.6 → 1.7
  • Sequential chain: 1.1 → 1.3 → 1.4 (1.3 can start after 1.1, independent of 1.2)
  • In practice: Single agent executes 1.1 → 1.2 → 1.3 → 1.4 → 1.5 sequentially. Quality reviewer (1.6) runs after 1.5 completes, then back-end-engineer addresses findings (1.7).
1.1 (baseline) → 1.2 (AssetKeyGenerator) ─┐
└→ 1.3 (CdnUrlResolver) ──┤→ 1.4 (S3AssetService) → 1.5 (CSV refactor) → 1.6 (QR) → 1.7 (fixes)

Accept idle time — the quality-reviewer is idle during implementation (1.1–1.5) and the back-end-engineer is idle during review (1.6). Phases are short enough that buffer tasks add no value.

PersonaAgent NameTasks AssignedWorking DirectorySpawn Order
back-end-engineerbe-common-module1.1, 1.2, 1.3, 1.4, 1.5, 1.7/Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-moduleFirst
quality-reviewerqr-common-module1.6/Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-moduleAfter 1.5
ArtifactPath (relative to worktree)FormatDescription
AssetKeyGeneratorlib/src/main/kotlin/cards/arda/common/lib/infra/storage/AssetKeyGenerator.ktKotlinKey generation with configurable namespace (TD-19)
CdnUrlResolverlib/src/main/kotlin/cards/arda/common/lib/infra/storage/CdnUrlResolver.ktKotlinCDN URL construction and validation (TD-14, TD-20)
S3AssetServicelib/src/main/kotlin/cards/arda/common/lib/infra/storage/S3AssetService.ktKotlinPresigned PUT/POST, HEAD, metadata validation (TD-17)
Refactored CSV servicelib/src/main/kotlin/cards/arda/common/lib/infra/storage/CsvS3ObjectDirectService.ktKotlinDelegates S3 primitives to S3AssetService (TD-18, TD-24)
AssetKeyGeneratorTestlib/src/test/kotlin/cards/arda/common/lib/infra/storage/AssetKeyGeneratorTest.ktKotlin/Kotest7 test cases
CdnUrlResolverTestlib/src/test/kotlin/cards/arda/common/lib/infra/storage/CdnUrlResolverTest.ktKotlin/Kotest7 test cases
S3AssetServiceTestlib/src/test/kotlin/cards/arda/common/lib/infra/storage/S3AssetServiceTest.ktKotlin/Kotest7 test cases with MockAWS
1.1 (baseline)
├──→ 1.2 (AssetKeyGenerator) ──→ 1.4 (S3AssetService) ──→ 1.5 (CSV refactor)
└──→ 1.3 (CdnUrlResolver) ────┘ │
1.6 (quality review) ──→ 1.7 (fixes)
#CriterionVerification CommandExpected Output
1AssetKeyGeneratorTest passesmake -C <cm-worktree> clean build 2>&1 | grep -c "AssetKeyGeneratorTest"≥ 1
2CdnUrlResolverTest passesmake -C <cm-worktree> clean build 2>&1 | grep -c "CdnUrlResolverTest"≥ 1
3S3AssetServiceTest passesmake -C <cm-worktree> clean build 2>&1 | grep -c "S3AssetServiceTest"≥ 1
4Existing CSV tests passmake -C <cm-worktree> clean build 2>&1 | grep -c "CsvS3DirectAccessTest"≥ 1
5Full build succeedsmake -C <cm-worktree> clean buildExit code 0
6Quality review completedQuality review report exists and findings addressed
7No uncommitted changes outside scopegit -C <cm-worktree> diff --statOnly expected files

Where <cm-worktree> = /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module.

Working directory: /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module Use absolute paths for all tool calls. Prefix Bash commands with cd /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module &&.

Implement the shared S3 asset management library in common-module. Follow specification.md Phase 0 + Phase 2a (tasks T-1 through T-5).

Load skills: kotlin-coding, unit-tests-backend, unit-tests-infra, build-core-modules.

Package: cards.arda.common.lib.infra.storage Source root: lib/src/main/kotlin/cards/arda/common/lib/infra/storage/ Test root: lib/src/test/kotlin/cards/arda/common/lib/infra/storage/

Tasks: 1.1 through 1.5 per this plan. Each task produces its tests before the next task starts. Record any design decisions in the project decision log continuing from TD-25.

Key decisions: TD-17 (PUT+POST), TD-18 (CSV delegation), TD-19 (configurable namespace), TD-20 (ApplicationContext for tenant), TD-24 (S3AssetService injected into CSV factory).

T-4 pre-implementation check: Verify AWS SDK presigned POST support in version pinned by gradle/libs.versions.toml before coding.

After completing all tasks, run make clean build and report the full test count and any coverage changes.

Working directory: /Users/jmp/code/arda/projects/image-upload-backend-worktrees/common-module Use absolute paths for all tool calls.

Review the new and modified files in lib/src/main/kotlin/cards/arda/common/lib/infra/storage/:

  • AssetKeyGenerator.kt
  • CdnUrlResolver.kt
  • S3AssetService.kt
  • CsvS3ObjectDirectService.kt (refactored)

And their test files in lib/src/test/kotlin/cards/arda/common/lib/infra/storage/.

Load skills: kotlin-coding, unit-tests-backend.

Evaluate against: Kotlin coding conventions, Result<T> + AppError usage, suspend function patterns, Exposed ORM conventions (if any), DRY principle, type safety. Produce a code review report.

None — this is the first run.

ArtifactConsumer RunPath
AssetKeyGenerator classRun 2lib/src/main/kotlin/.../infra/storage/AssetKeyGenerator.kt
CdnUrlResolver classRun 2lib/src/main/kotlin/.../infra/storage/CdnUrlResolver.kt
S3AssetService classRun 2lib/src/main/kotlin/.../infra/storage/S3AssetService.kt
Passing build baselineRun 2make clean build exit code 0
Committed codeRun 2Branch jmpicnic/item-image-upload-backend
#QuestionOptionsRecommendationDecision
No open questions

All design questions for Run 1 were resolved during specification: TD-17 (PUT+POST), TD-18 (CSV delegation), TD-19 (configurable namespace), TD-20 (ApplicationContext), TD-24 (S3AssetService injected into CSV).

  • All 3 new test suites pass (AssetKeyGenerator, CdnUrlResolver, S3AssetService)
  • Existing CSV tests pass without modification
  • make clean build succeeds with exit code 0
  • Quality review completed, findings addressed
  • Code committed on jmpicnic/item-image-upload-backend branch
Risk / BlockerImpactMitigation
AWS SDK v2.34.3 lacks presigned POST APIHigh — T-4 design changesT-4 pre-implementation check; construct policy manually if needed
CSV refactoring breaks existing testsHigh — regressionT-5 constraint: existing tests must pass without modification
S3AssetService factory signature change breaks CSV callersMedium — test updates neededTD-24 decided: factory accepts S3AssetService; tests updated to supply MockAWS instance
MockAWS/LocalStack doesn’t support presigned POSTMedium — test coverage gapTest form field presence only; defer full policy validation to Phase 2c
FileDescription
changelog.mdSummary of changes made in Run 1
learnings.mdNew knowledge about AWS SDK, MockAWS capabilities
suggestions.mdImprovement suggestions, tech debt, documentation gaps
ArtifactProduced ByLocation
Observation logCI Observersession/ci-observations.md
Improvement proposalImprovement Analyzercontinuous-improvement-proposal.md

The team’s TaskList is the single source of truth for task status. Follow the protocol at every phase boundary per the team-lead agent definition.

DateEventNotes
2026-03-31Plan created

Copyright: (c) Arda Systems 2025-2026, All rights reserved