2026-04-28-exam-sprint-download-url-prefix.md 9.5 KB

Exam Sprint Download URL Prefix Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Rename the Azure report download URL configuration from url-prefix to download-url-prefix and make test downloads return direct Azure Blob URLs.

Architecture: Keep the existing storage boundary unchanged: DefaultExamSprintReportApplicationService asks ExamSprintReportStorage.generateDownloadUrl(...), and AzureBlobExamSprintReportStorage builds a public URL from a configured download prefix, container name, and storage object key. This change only clarifies the configuration name and default test URL; upload/download/delete continue to use the Azure SDK client and connection string.

Tech Stack: Java 17, Spring Boot @Value configuration binding, Maven, JUnit 5, AssertJ, Mockito, Spring MockMvc tests.


File Structure

  • Modify abilities/exam-sprint/application/src/main/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportProperties.java
    • Replace the Storage.urlPrefix property with Storage.downloadUrlPrefix.
  • Modify abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorage.java
    • Inject ability.exam-sprint.report.storage.download-url-prefix instead of url-prefix.
    • Rename internal field and validation method naming from urlPrefix to downloadUrlPrefix.
  • Modify ability-center-runtime/src/main/resources/application-test.yml
    • Replace url-prefix with download-url-prefix and default to https://dcjxbtest.blob.core.chinacloudapi.cn.
  • Modify ability-center-runtime/src/main/resources/application-prod.yml
    • Replace url-prefix with download-url-prefix and keep the existing production Blob account host default.
  • Modify abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorageTest.java
    • Update test names, expected URLs, and validation messages.
  • Modify ability-center-runtime/src/test/java/cn/yunzhixue/ability/center/examsprint/adapter/http/ExamSprintReportControllerWebMvcTest.java
    • Update expected downloadUrl values from CDN host to Blob host where tests assert exact values.

Task 1: Rename the Azure storage configuration property

Files:

  • Modify: abilities/exam-sprint/application/src/main/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportProperties.java
  • Modify: abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorage.java
  • Modify: ability-center-runtime/src/main/resources/application-test.yml
  • Modify: ability-center-runtime/src/main/resources/application-prod.yml
  • Test: abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorageTest.java

  • [ ] Step 1: Write the failing infrastructure expectations

In AzureBlobExamSprintReportStorageTest, update the constructor reflection test so it still expects seven parameters but treats the sixth String as download-url-prefix by name in the surrounding test naming. Rename generateDownloadUrlReturnsConfiguredOssFileLink to generateDownloadUrlReturnsConfiguredBlobFileLink and change the expected URL to:

assertThat(downloadUrl).isEqualTo(URI.create(
        "https://dcjxbtest.blob.core.chinacloudapi.cn/exam-assault-report/exam-sprint-outlook-report-report-123.pdf"));

Rename constructorRejectsAllSlashUrlPrefix to constructorRejectsAllSlashDownloadUrlPrefix and constructorRejectsBlankAfterTrimUrlPrefix to constructorRejectsBlankAfterTrimDownloadUrlPrefix. Change both expected messages to:

.hasMessage("Azure storage download-url-prefix is incomplete");
  • Step 2: Run the focused infrastructure test and verify it fails

Run:

mvn -pl abilities/exam-sprint/infrastructure -Dtest=AzureBlobExamSprintReportStorageTest test

Expected: FAIL because production code still emits the old CDN URL and old url-prefix error message.

  • Step 3: Implement the Java property rename

In ExamSprintReportProperties.Storage, replace:

private String urlPrefix;

public String getUrlPrefix() {
    return urlPrefix;
}

public void setUrlPrefix(String urlPrefix) {
    this.urlPrefix = urlPrefix;
}

with:

private String downloadUrlPrefix;

public String getDownloadUrlPrefix() {
    return downloadUrlPrefix;
}

public void setDownloadUrlPrefix(String downloadUrlPrefix) {
    this.downloadUrlPrefix = downloadUrlPrefix;
}

In AzureBlobExamSprintReportStorage, replace the urlPrefix field and constructor parameter with downloadUrlPrefix, inject:

@Value("${ability.exam-sprint.report.storage.download-url-prefix:}") String downloadUrlPrefix,

and change URL creation to:

return URI.create(downloadUrlPrefix + "/" + containerName + "/" + normalizedStorageObjectKey);

Rename normalizeUrlPrefix to normalizeDownloadUrlPrefix and make both thrown messages say:

throw new IllegalStateException("Azure storage download-url-prefix is incomplete");
  • Step 4: Update runtime YAML configuration

In application-test.yml, replace:

url-prefix: "${AZURE_BLOB_URL_PREFIX:https://dcjxb-cdntest.yunzhixue.cn}"

with:

download-url-prefix: "${AZURE_BLOB_DOWNLOAD_URL_PREFIX:https://dcjxbtest.blob.core.chinacloudapi.cn}"

In application-prod.yml, replace:

url-prefix: "${AZURE_BLOB_URL_PREFIX:https://dcjxb.blob.core.chinacloudapi.cn}"

with:

download-url-prefix: "${AZURE_BLOB_DOWNLOAD_URL_PREFIX:https://dcjxb.blob.core.chinacloudapi.cn}"
  • Step 5: Run the focused infrastructure test and verify it passes

Run:

mvn -pl abilities/exam-sprint/infrastructure -Dtest=AzureBlobExamSprintReportStorageTest test

Expected: PASS with Tests run: 8, Failures: 0, Errors: 0, Skipped: 0.

Task 2: Update HTTP-facing tests for the new download host

Files:

  • Modify: ability-center-runtime/src/test/java/cn/yunzhixue/ability/center/examsprint/adapter/http/ExamSprintReportControllerWebMvcTest.java

  • [ ] Step 1: Write the failing WebMvc expectations

Replace exact expected URLs using https://dcjxb-cdntest.yunzhixue.cn/exam-assault-report/ with https://dcjxbtest.blob.core.chinacloudapi.cn/exam-assault-report/. For example:

"https://dcjxbtest.blob.core.chinacloudapi.cn/exam-assault-report/exam-sprint-outlook-report-report-sync-001.pdf"

and:

"https://dcjxbtest.blob.core.chinacloudapi.cn/exam-assault-report/exam-sprint-achievement-report-report-sync-002.pdf"
  • Step 2: Run the focused runtime WebMvc test and verify it fails if code/config is incomplete

Run:

mvn -pl ability-center-runtime -Dtest=ExamSprintReportControllerWebMvcTest test

Expected before Task 1 implementation: FAIL because the old configuration emits CDN URLs. Expected after Task 1 implementation: PASS.

  • Step 3: Re-run the focused runtime WebMvc test after Task 1 changes

Run:

mvn -pl ability-center-runtime -Dtest=ExamSprintReportControllerWebMvcTest test

Expected: PASS with all ExamSprintReportControllerWebMvcTest cases passing.

Task 3: Final verification

Files:

  • Verify only; no additional files should change in this task.

  • [ ] Step 1: Run all directly affected tests

Run:

mvn -pl abilities/exam-sprint/infrastructure -Dtest=AzureBlobExamSprintReportStorageTest test && mvn -pl ability-center-runtime -Dtest=ExamSprintReportControllerWebMvcTest test

Expected: both Maven commands finish with BUILD SUCCESS.

  • Step 2: Inspect the diff for accidental compatibility code or secret changes

Run:

git diff -- abilities/exam-sprint/application/src/main/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportProperties.java abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorage.java ability-center-runtime/src/main/resources/application-test.yml ability-center-runtime/src/main/resources/application-prod.yml abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorageTest.java ability-center-runtime/src/test/java/cn/yunzhixue/ability/center/examsprint/adapter/http/ExamSprintReportControllerWebMvcTest.java

Expected: diff contains only the download-url-prefix rename, Blob host default for test, unchanged production Blob host default, and test expectation updates.

  • Step 3: Report deployment configuration note

Tell the operator that test deployments should use:

AZURE_BLOB_DOWNLOAD_URL_PREFIX=https://dcjxbtest.blob.core.chinacloudapi.cn

and that AZURE_BLOB_URL_PREFIX is intentionally no longer read.

Self-Review

  • Spec coverage: The plan covers the approved rename to download-url-prefix, direct test Blob URL default, no backward compatibility for url-prefix, production config rename, and affected tests.
  • Placeholder scan: No placeholder tasks remain; each step lists exact files, code snippets, commands, and expected outcomes.
  • Type consistency: The property name is consistently downloadUrlPrefix in Java and download-url-prefix in YAML/Spring configuration.