|
| 1 | +# PR_26163_074-assets-multi-file-upload-project-write |
| 2 | + |
| 3 | +## Branch Validation |
| 4 | + |
| 5 | +- Current branch: `main` |
| 6 | +- Expected branch: `main` |
| 7 | +- Branch validation: PASS |
| 8 | + |
| 9 | +## Summary |
| 10 | + |
| 11 | +Assets now supports multi-file upload for upload-capable asset types: Images, Audio, Fonts, and Data. Each valid selected file creates a separate owner-scoped asset record, the File column uses the actual uploaded filename, and each stored path is generated under the current project path: |
| 12 | + |
| 13 | +- `projects/<projectId>/image/<filename>` |
| 14 | +- `projects/<projectId>/audio/<filename>` |
| 15 | +- `projects/<projectId>/font/<filename>` |
| 16 | +- `projects/<projectId>/data/<filename>` |
| 17 | + |
| 18 | +Multi-file uploads now open an in-page upload diagnostics dialog that updates during the batch. It shows the current file, file count progress, bytes uploaded, total bytes, BPS, human-readable speed, ETA, elapsed time, per-file OK/WARN/FAIL/SKIP rows, and written/failed/skipped/warnings summary counters. |
| 19 | + |
| 20 | +Sprite, Vector, and Palette References remain Reference-only for MVP. Projectile remains absent from usage values. Shared Tags type-ahead behavior is unchanged. |
| 21 | + |
| 22 | +## Requirement Checklist |
| 23 | + |
| 24 | +| Requirement | Status | Evidence | |
| 25 | +| --- | --- | --- | |
| 26 | +| Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` first | PASS | Read before implementation. | |
| 27 | +| Verify branch is `main` before changes | PASS | `git branch --show-current` returned `main`. | |
| 28 | +| Fix `codex_review.diff` output encoding as readable UTF-8 | PASS | Regenerated via `node scripts/write-codex-review-artifacts.mjs`; Playwright test `codex review diff artifact is readable UTF-8 text` passed. | |
| 29 | +| Multi-file upload for Images | PASS | Playwright selected two Image files and verified two rows plus `projects/.../image/...` path. | |
| 30 | +| Multi-file upload for Audio | PASS | Playwright selected two Audio files and verified two rows plus `projects/.../audio/...` path. | |
| 31 | +| Multi-file upload for Fonts | PASS | Playwright selected two Font files and verified two rows plus `projects/.../font/...` path. | |
| 32 | +| Multi-file upload for Data | PASS | Playwright selected two Data files and verified two rows plus `projects/.../data/...` path. | |
| 33 | +| File input supports multiple files where upload is allowed | PASS | Playwright asserts `Upload File` has `multiple = true` for upload rows. | |
| 34 | +| Each valid selected file creates one asset record row | PASS | Playwright validates one row per valid selected file for Images, Audio, Fonts, and Data. | |
| 35 | +| Uploaded file paths stay under `/projects/` with current project id and asset type | PASS | Playwright validates stored paths matching `projects/<ULID>/image/`, `audio/`, `font/`, and `data/`. | |
| 36 | +| Do not write files outside `/projects/` | PASS | Catalog upload stored paths are generated by `catalogUploadStoredPath()` using only `projects/<projectId>/<asset-role-folder>/<filename>`. | |
| 37 | +| Do not generate fake filenames | PASS | UI and repository use the selected `File.name`; tests verify actual filenames render in rows and metadata. | |
| 38 | +| Asset record stores generated project-relative path | PASS | Asset metadata and batch log show `storedPath` values under `projects/...`. | |
| 39 | +| Batch upload logs OK/WARN/FAIL/SKIP | PASS | Playwright diagnostic batch verifies all four statuses render in `data-asset-tool-batch-log`. | |
| 40 | +| Upload dialog opens for multi-file upload | PASS | Playwright verifies `data-asset-tool-upload-dialog` becomes visible after Save. | |
| 41 | +| Progress updates while upload is running | PASS | Playwright verifies the dialog phase reaches `Uploading` before the final complete state. | |
| 42 | +| Current file and file count progress render | PASS | Playwright verifies current file text and `/ 2` file count progress during upload. | |
| 43 | +| Bytes uploaded and total bytes render | PASS | Playwright verifies total bytes and bytes uploaded are not `0 B` during the clean batch. | |
| 44 | +| BPS, speed, ETA, and elapsed render | PASS | Playwright verifies BPS is nonzero, speed contains `/s`, and ETA/elapsed show seconds. | |
| 45 | +| Per-file OK/WARN/FAIL/SKIP rows render in dialog | PASS | Playwright verifies dialog rows for `OK`, `WARN`, `FAIL`, and `SKIP`. | |
| 46 | +| Batch summary renders written/failed/skipped/warnings | PASS | Playwright verifies dialog counters for written, failed, skipped, and warnings. | |
| 47 | +| One failed file does not stop remaining uploads unless global | PASS | Playwright diagnostic batch includes a bad extension FAIL followed by a later OK row. | |
| 48 | +| No silent fallback when progress cannot be calculated | PASS | Zero-byte upload produces a visible dialog WARN row: progress could not be calculated. | |
| 49 | +| Missing project id fails visibly | PASS | Playwright `?handoff=missing` run shows FAIL and SKIP log rows and leaves asset count at `0`. | |
| 50 | +| Sprite, Vector, Palette References remain Reference-only | PASS | Playwright verifies each has `Source = Reference` and no Upload File control. | |
| 51 | +| Projectile remains removed from Usage values | PASS | Existing Assets coverage still asserts usage options equal the approved list and exclude Projectile. | |
| 52 | +| Shared Tags type-ahead preserved | PASS | Existing Assets coverage still adds a shared Tag and uses it through the Assets tag datalist. | |
| 53 | +| Records remain owner-scoped | PASS | Existing Assets coverage still verifies user 2 cannot see user 1's asset row. | |
| 54 | + |
| 55 | +## Batch Upload Evidence |
| 56 | + |
| 57 | +- Clean Image batch: `2 written, 0 failed, 0 skipped, 0 warnings`. |
| 58 | +- Diagnostic Image batch: `3 written, 1 failed, 1 skipped, 1 warnings`. |
| 59 | +- Upload dialog clean-batch final counters: |
| 60 | + - Written: `2` |
| 61 | + - Failed: `0` |
| 62 | + - Skipped: `0` |
| 63 | + - Warnings: `0` |
| 64 | +- Upload dialog diagnostic-batch final counters: |
| 65 | + - Written: `3` |
| 66 | + - Failed: `1` |
| 67 | + - Skipped: `1` |
| 68 | + - Warnings: `1` |
| 69 | +- Upload progress fields verified: |
| 70 | + - Current File |
| 71 | + - File Count |
| 72 | + - Bytes Uploaded |
| 73 | + - Total Bytes |
| 74 | + - BPS |
| 75 | + - Speed |
| 76 | + - ETA |
| 77 | + - Elapsed |
| 78 | +- Logged per-file statuses: |
| 79 | + - `OK: batch-status-ok.png` |
| 80 | + - `WARN: batch-status-warning.png` |
| 81 | + - `FAIL: batch-status-bad.exe` |
| 82 | + - `SKIP: batch-status-ok.png` |
| 83 | +- Missing project id batch: `0 written, 1 failed, 1 skipped, 0 warnings`. |
| 84 | + |
| 85 | +## Project Path Evidence |
| 86 | + |
| 87 | +Playwright verified selected asset metadata with these path patterns: |
| 88 | + |
| 89 | +- `projects/<ULID>/image/batch-image-a.png` |
| 90 | +- `projects/<ULID>/audio/batch-audio-a.wav` |
| 91 | +- `projects/<ULID>/font/batch-font-a.woff2` |
| 92 | +- `projects/<ULID>/data/batch-data-a.json` |
| 93 | + |
| 94 | +## Changed Files |
| 95 | + |
| 96 | +- `toolbox/assets/index.html` |
| 97 | +- `toolbox/assets/assets.js` |
| 98 | +- `src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js` |
| 99 | +- `tests/playwright/tools/AssetToolMockRepository.spec.mjs` |
| 100 | +- `docs_build/dev/reports/playwright_v8_coverage_report.txt` |
| 101 | +- `docs_build/dev/reports/codex_review.diff` |
| 102 | +- `docs_build/dev/reports/codex_changed_files.txt` |
| 103 | +- `docs_build/dev/reports/PR_26163_074-assets-multi-file-upload-project-write.md` |
| 104 | + |
| 105 | +## Impacted Lanes |
| 106 | + |
| 107 | +- runtime: Assets browser tool behavior. |
| 108 | +- integration: Assets DB/mock adapter path generation and owner-scoped records. |
| 109 | +- Playwright: Yes, targeted Assets coverage updated. |
| 110 | + |
| 111 | +## Testing Performed |
| 112 | + |
| 113 | +- PASS: `node --check toolbox/assets/assets.js` |
| 114 | +- PASS: `node --check src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js` |
| 115 | +- PASS: `node --check tests/playwright/tools/AssetToolMockRepository.spec.mjs` |
| 116 | +- PASS: `git diff --check -- toolbox/assets/index.html toolbox/assets/assets.js src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js tests/playwright/tools/AssetToolMockRepository.spec.mjs docs_build/dev/reports/playwright_v8_coverage_report.txt` |
| 117 | +- PASS: `npx playwright test tests/playwright/tools/AssetToolMockRepository.spec.mjs --workers=1 --reporter=list` (6 passed; final run includes upload dialog/progress diagnostics) |
| 118 | +- PASS: `npm run test:workspace-v2` (workspace-contract lane, 5 passed) |
| 119 | + |
| 120 | +Initial targeted Playwright intentionally failed before artifact regeneration because the pre-existing `codex_review.diff` was not readable UTF-8. After regenerating with the Node artifact writer, the same lane passed. |
| 121 | + |
| 122 | +## V8 Coverage |
| 123 | + |
| 124 | +- PASS: `docs_build/dev/reports/playwright_v8_coverage_report.txt` generated by the final targeted Assets Playwright run. |
| 125 | +- PASS: `toolbox/assets/assets.js` covered at 96% function coverage. |
| 126 | +- WARN: `src/dev-runtime/persistence/tool-repositories/assets-mock-repository.js` is server-side mock adapter code and is not collected directly by browser V8 coverage; it is exercised through the API-backed Playwright flow. |
| 127 | + |
| 128 | +## Skipped Lanes |
| 129 | + |
| 130 | +- Full samples smoke: SKIPPED by explicit request. Safe to skip because this PR only changes the Assets tool UI, the Assets mock adapter path generation, targeted Assets Playwright tests, and reports. No sample loader/runtime game sample behavior changed. |
| 131 | + |
| 132 | +## Manual Validation Steps |
| 133 | + |
| 134 | +1. Open `toolbox/assets/index.html`. |
| 135 | +2. Click `Reset Asset Library`. |
| 136 | +3. Open `Images`, click `Add Images`, choose multiple image files, select Usage, and Save. |
| 137 | +4. Confirm one row appears per valid selected file and the Status Log shows a batch summary. |
| 138 | +5. Confirm the Upload Diagnostics dialog shows current file, file count, bytes uploaded, total bytes, BPS, speed, ETA, elapsed time, per-file statuses, and written/failed/skipped/warnings counters. |
| 139 | +6. Click `View` for an uploaded asset and confirm `Stored path` starts with `projects/<projectId>/image/`. |
| 140 | +7. Repeat for Audio, Fonts, and Data and confirm the matching `audio`, `font`, and `data` path folders. |
| 141 | +8. Open `Sprites`, `Vectors`, and `Palette References` and confirm they remain Reference-only. |
| 142 | +9. Open `toolbox/assets/index.html?handoff=missing`, attempt a multi-file Image upload, and confirm the visible FAIL/SKIP batch log with zero saved rows. |
| 143 | + |
| 144 | +## Review Artifacts |
| 145 | + |
| 146 | +- `docs_build/dev/reports/codex_review.diff` |
| 147 | +- `docs_build/dev/reports/codex_changed_files.txt` |
| 148 | +- `tmp/PR_26163_074-assets-multi-file-upload-project-write_delta.zip` |
0 commit comments