|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Throwaway script — creates the 10 remaining open issues for OpenDataMask. |
| 3 | +# Runs once via GitHub Actions then the branch is deleted. |
| 4 | +# Issues already created directly: #26 (arch-1), #27 (backend-1), #28 (backend-2) |
| 5 | +set -euo pipefail |
| 6 | + |
| 7 | +REPO="MaximumTrainer/OpenDataMask" |
| 8 | +API="https://api.github.com/repos/${REPO}/issues" |
| 9 | + |
| 10 | +create_issue() { |
| 11 | + local title="$1" |
| 12 | + local body="$2" |
| 13 | + local result |
| 14 | + result=$(jq -n --arg t "$title" --arg b "$body" '{title: $t, body: $b}' \ |
| 15 | + | curl -sf -X POST \ |
| 16 | + -H "Authorization: Bearer ${GH_TOKEN}" \ |
| 17 | + -H "Accept: application/vnd.github+json" \ |
| 18 | + -H "X-GitHub-Api-Version: 2022-11-28" \ |
| 19 | + "${API}" -d @-) |
| 20 | + local num |
| 21 | + num=$(echo "$result" | jq -r '.number') |
| 22 | + echo "Created #${num}: ${title}" |
| 23 | +} |
| 24 | + |
| 25 | +# ── test-1 ──────────────────────────────────────────────────────────────────── |
| 26 | +create_issue \ |
| 27 | + "Add @WebMvcTest tests: ColumnCommentController, DataPreviewController, GeneratorPresetController" \ |
| 28 | + "## Problem |
| 29 | +Three controllers have no test coverage: |
| 30 | +- \`ColumnCommentController\` |
| 31 | +- \`DataPreviewController\` |
| 32 | +- \`GeneratorPresetController\` |
| 33 | +
|
| 34 | +## Required Changes |
| 35 | +Create the following test files under \`backend/src/test/kotlin/com/opendatamask/adapter/input/rest/\`: |
| 36 | +- \`ColumnCommentControllerTest.kt\` |
| 37 | +- \`DataPreviewControllerTest.kt\` |
| 38 | +- \`GeneratorPresetControllerTest.kt\` |
| 39 | +
|
| 40 | +Each test class should use \`@WebMvcTest\` with \`@WithMockUser\` and cover: |
| 41 | +- Happy-path GET / POST / PUT / DELETE returning expected status codes |
| 42 | +- 404 when the resource is not found |
| 43 | +- 400 / 403 for invalid input or permission errors |
| 44 | +
|
| 45 | +## Notes |
| 46 | +- Mock all service dependencies with \`@MockBean\` |
| 47 | +- Use \`any<Type>()\` not \`any()\` for Mockito matchers on \`@NonNull\` params |
| 48 | +- Follow existing patterns in \`WorkspaceControllerTest.kt\` |
| 49 | +
|
| 50 | +## Acceptance Criteria |
| 51 | +- 3 new test files with ≥ 6 test cases each |
| 52 | +- All 405+ existing backend tests continue to pass" |
| 53 | + |
| 54 | +# ── test-2 ──────────────────────────────────────────────────────────────────── |
| 55 | +create_issue \ |
| 56 | + "Add @WebMvcTest tests: JobScheduleController, PrivacyHubController, PrivacyReportController" \ |
| 57 | + "## Problem |
| 58 | +Three controllers have no test coverage: |
| 59 | +- \`JobScheduleController\` |
| 60 | +- \`PrivacyHubController\` |
| 61 | +- \`PrivacyReportController\` |
| 62 | +
|
| 63 | +## Required Changes |
| 64 | +Create the following test files under \`backend/src/test/kotlin/com/opendatamask/adapter/input/rest/\`: |
| 65 | +- \`JobScheduleControllerTest.kt\` |
| 66 | +- \`PrivacyHubControllerTest.kt\` |
| 67 | +- \`PrivacyReportControllerTest.kt\` |
| 68 | +
|
| 69 | +Each test class should use \`@WebMvcTest\` with \`@WithMockUser\` and cover: |
| 70 | +- Happy-path GET / POST / PUT / DELETE |
| 71 | +- 404 when resource not found |
| 72 | +- 403 when user lacks permission |
| 73 | +
|
| 74 | +## Notes |
| 75 | +- Mock all service dependencies with \`@MockBean\` |
| 76 | +- Follow existing patterns in \`JobControllerTest.kt\` |
| 77 | +
|
| 78 | +## Acceptance Criteria |
| 79 | +- 3 new test files with ≥ 6 test cases each |
| 80 | +- All 405+ existing backend tests continue to pass" |
| 81 | + |
| 82 | +# ── test-3 ──────────────────────────────────────────────────────────────────── |
| 83 | +create_issue \ |
| 84 | + "Add @WebMvcTest tests: SchemaChangeController, SensitivityScanController, SubsetConfigController" \ |
| 85 | + "## Problem |
| 86 | +Three controllers have no test coverage: |
| 87 | +- \`SchemaChangeController\` |
| 88 | +- \`SensitivityScanController\` |
| 89 | +- \`SubsetConfigController\` |
| 90 | +
|
| 91 | +## Required Changes |
| 92 | +Create the following test files under \`backend/src/test/kotlin/com/opendatamask/adapter/input/rest/\`: |
| 93 | +- \`SchemaChangeControllerTest.kt\` |
| 94 | +- \`SensitivityScanControllerTest.kt\` |
| 95 | +- \`SubsetConfigControllerTest.kt\` |
| 96 | +
|
| 97 | +Each test class should use \`@WebMvcTest\` with \`@WithMockUser\` and cover: |
| 98 | +- Happy-path GET / POST / PUT / DELETE |
| 99 | +- 404 when resource not found |
| 100 | +- Scan-specific: trigger endpoint returns 202 Accepted on success |
| 101 | +
|
| 102 | +## Notes |
| 103 | +- Mock all service dependencies with \`@MockBean\` |
| 104 | +- Follow existing patterns in \`WorkspaceControllerTest.kt\` |
| 105 | +
|
| 106 | +## Acceptance Criteria |
| 107 | +- 3 new test files with ≥ 6 test cases each |
| 108 | +- All 405+ existing backend tests continue to pass" |
| 109 | + |
| 110 | +# ── test-4 ──────────────────────────────────────────────────────────────────── |
| 111 | +create_issue \ |
| 112 | + "Add @WebMvcTest tests: WebhookController, WorkspaceExportController" \ |
| 113 | + "## Problem |
| 114 | +Two controllers have no test coverage: |
| 115 | +- \`WebhookController\` |
| 116 | +- \`WorkspaceExportController\` |
| 117 | +
|
| 118 | +## Required Changes |
| 119 | +Create the following test files under \`backend/src/test/kotlin/com/opendatamask/adapter/input/rest/\`: |
| 120 | +- \`WebhookControllerTest.kt\` |
| 121 | +- \`WorkspaceExportControllerTest.kt\` |
| 122 | +
|
| 123 | +Each test class should use \`@WebMvcTest\` with \`@WithMockUser\` and cover: |
| 124 | +- Happy-path GET / POST / PUT / DELETE |
| 125 | +- Export: response contains expected \`Content-Disposition: attachment\` header |
| 126 | +- Webhook: delivery endpoint returns 200 on valid payload, 400 on invalid HMAC |
| 127 | +
|
| 128 | +## Notes |
| 129 | +- Mock all service dependencies with \`@MockBean\` |
| 130 | +- Follow existing patterns in \`WorkspaceControllerTest.kt\` |
| 131 | +
|
| 132 | +## Acceptance Criteria |
| 133 | +- 2 new test files with ≥ 6 test cases each |
| 134 | +- All 405+ existing backend tests continue to pass" |
| 135 | + |
| 136 | +# ── test-5 ──────────────────────────────────────────────────────────────────── |
| 137 | +create_issue \ |
| 138 | + "Replace stub PortContractTest with real port contract verification" \ |
| 139 | + "## Problem |
| 140 | +\`backend/src/test/kotlin/com/opendatamask/domain/port/PortContractTest.kt\` currently contains only: |
| 141 | +\`\`\`kotlin |
| 142 | +assertTrue(true) |
| 143 | +\`\`\` |
| 144 | +This is a meaningless stub that gives false confidence. |
| 145 | +
|
| 146 | +## Required Changes |
| 147 | +Replace the stub with real contract verification using Spring's reflection API or classpath scanning: |
| 148 | +
|
| 149 | +1. **Use-case interfaces** — verify every \`@Service\` class in \`application.service\` implements exactly one interface from \`domain.port.input\` |
| 150 | +2. **Output ports** — verify every \`@Repository\` class in \`adapter.output.persistence\` implements its corresponding interface from \`domain.port.output\` |
| 151 | +3. **No leaked adapter imports in domain** — assert no class in \`domain.*\` imports anything from \`adapter.*\` |
| 152 | +
|
| 153 | +## Acceptance Criteria |
| 154 | +- \`PortContractTest\` contains at least 3 meaningful test methods |
| 155 | +- Tests fail if a service or repository breaks the hexagonal wiring contract |
| 156 | +- All 405+ existing backend tests continue to pass" |
| 157 | + |
| 158 | +# ── fe-1 ────────────────────────────────────────────────────────────────────── |
| 159 | +create_issue \ |
| 160 | + "Frontend: add API clients for Privacy Hub, Privacy Reports, Sensitivity Scan" \ |
| 161 | + "## Problem |
| 162 | +The backend exposes \`PrivacyHubController\`, \`PrivacyReportController\`, and \`SensitivityScanController\` but there are no corresponding frontend API client modules, making these features inaccessible from the UI. |
| 163 | +
|
| 164 | +## Required Changes |
| 165 | +Create the following files in \`frontend/src/api/\`: |
| 166 | +
|
| 167 | +### \`privacy.ts\` |
| 168 | +\`\`\`typescript |
| 169 | +// GET /workspaces/{id}/privacy-hub -> getPrivacyHub(workspaceId) |
| 170 | +// GET /workspaces/{id}/privacy-reports -> listPrivacyReports(workspaceId) |
| 171 | +// GET /workspaces/{id}/privacy-reports/{id} -> getPrivacyReport(workspaceId, reportId) |
| 172 | +// POST /workspaces/{id}/privacy-reports -> generatePrivacyReport(workspaceId) |
| 173 | +\`\`\` |
| 174 | +
|
| 175 | +### \`sensitivityScan.ts\` |
| 176 | +\`\`\`typescript |
| 177 | +// GET /workspaces/{id}/sensitivity-scans -> listSensitivityScans(workspaceId) |
| 178 | +// POST /workspaces/{id}/sensitivity-scans -> triggerScan(workspaceId) |
| 179 | +// GET /workspaces/{id}/sensitivity-scans/{id} -> getScanLog(workspaceId, scanId) |
| 180 | +\`\`\` |
| 181 | +
|
| 182 | +## Acceptance Criteria |
| 183 | +- Both API modules use the shared axios client from \`api/client.ts\` |
| 184 | +- Full TypeScript types matching backend DTOs |
| 185 | +- All existing frontend Vitest tests continue to pass" |
| 186 | + |
| 187 | +# ── fe-2 ────────────────────────────────────────────────────────────────────── |
| 188 | +create_issue \ |
| 189 | + "Frontend: add API clients for Webhooks, Generator Presets, Job Schedule" \ |
| 190 | + "## Problem |
| 191 | +The backend exposes \`WebhookController\`, \`GeneratorPresetController\`, and \`JobScheduleController\` but there are no corresponding frontend API client modules. |
| 192 | +
|
| 193 | +## Required Changes |
| 194 | +Create the following files in \`frontend/src/api/\`: |
| 195 | +
|
| 196 | +### \`webhooks.ts\` |
| 197 | +\`\`\`typescript |
| 198 | +// CRUD for /workspaces/{id}/webhooks |
| 199 | +// POST /workspaces/{id}/webhooks/{id}/test -> testWebhook(workspaceId, webhookId) |
| 200 | +\`\`\` |
| 201 | +
|
| 202 | +### \`presets.ts\` |
| 203 | +\`\`\`typescript |
| 204 | +// CRUD for /workspaces/{id}/generator-presets |
| 205 | +// GET /generator-presets/shared -> listSharedPresets() |
| 206 | +\`\`\` |
| 207 | +
|
| 208 | +### \`schedules.ts\` |
| 209 | +\`\`\`typescript |
| 210 | +// CRUD for /workspaces/{id}/job-schedules |
| 211 | +// POST /workspaces/{id}/job-schedules/{id}/enable -> enableSchedule(...) |
| 212 | +// POST /workspaces/{id}/job-schedules/{id}/disable -> disableSchedule(...) |
| 213 | +\`\`\` |
| 214 | +
|
| 215 | +## Acceptance Criteria |
| 216 | +- All 3 API modules use the shared axios client |
| 217 | +- Full TypeScript types matching backend DTOs |
| 218 | +- All existing frontend Vitest tests continue to pass" |
| 219 | + |
| 220 | +# ── fe-3 ────────────────────────────────────────────────────────────────────── |
| 221 | +create_issue \ |
| 222 | + "Frontend: add API clients for Schema Changes, Subset Config, Data Preview" \ |
| 223 | + "## Problem |
| 224 | +The backend exposes \`SchemaChangeController\`, \`SubsetConfigController\`, and \`DataPreviewController\` but there are no corresponding frontend API client modules. |
| 225 | +
|
| 226 | +## Required Changes |
| 227 | +Create the following files in \`frontend/src/api/\`: |
| 228 | +
|
| 229 | +### \`schemaChanges.ts\` |
| 230 | +\`\`\`typescript |
| 231 | +// GET /workspaces/{id}/schema-changes -> listSchemaChanges(workspaceId) |
| 232 | +// POST /workspaces/{id}/schema-changes/detect -> detectChanges(workspaceId) |
| 233 | +// POST /workspaces/{id}/schema-changes/{id}/ack -> acknowledgeChange(workspaceId, changeId) |
| 234 | +\`\`\` |
| 235 | +
|
| 236 | +### \`subsets.ts\` |
| 237 | +\`\`\`typescript |
| 238 | +// CRUD for /workspaces/{id}/subset-configs |
| 239 | +\`\`\` |
| 240 | +
|
| 241 | +### \`preview.ts\` |
| 242 | +\`\`\`typescript |
| 243 | +// POST /workspaces/{id}/data-preview -> previewData(workspaceId, request) |
| 244 | +\`\`\` |
| 245 | +
|
| 246 | +## Acceptance Criteria |
| 247 | +- All 3 API modules use the shared axios client |
| 248 | +- Full TypeScript types matching backend DTOs |
| 249 | +- All existing frontend Vitest tests continue to pass" |
| 250 | + |
| 251 | +# ── fe-4 ────────────────────────────────────────────────────────────────────── |
| 252 | +create_issue \ |
| 253 | + "Frontend: add API clients for Column Comments and Workspace Export/Import" \ |
| 254 | + "## Problem |
| 255 | +The backend exposes \`ColumnCommentController\` and \`WorkspaceExportController\` but there are no corresponding frontend API client modules. |
| 256 | +
|
| 257 | +## Required Changes |
| 258 | +
|
| 259 | +### Create \`frontend/src/api/comments.ts\` |
| 260 | +\`\`\`typescript |
| 261 | +// GET /workspaces/{id}/column-comments -> listComments(workspaceId) |
| 262 | +// POST /workspaces/{id}/column-comments -> createComment(workspaceId, data) |
| 263 | +// PUT /workspaces/{id}/column-comments/{commentId} -> updateComment(...) |
| 264 | +// DELETE /workspaces/{id}/column-comments/{commentId} -> deleteComment(...) |
| 265 | +\`\`\` |
| 266 | +
|
| 267 | +### Extend \`frontend/src/api/workspaces.ts\` |
| 268 | +\`\`\`typescript |
| 269 | +// GET /workspaces/{id}/export -> exportWorkspace(workspaceId): Blob |
| 270 | +// POST /workspaces/import -> importWorkspace(file: File) |
| 271 | +\`\`\` |
| 272 | +
|
| 273 | +## Acceptance Criteria |
| 274 | +- New \`comments.ts\` module created; \`workspaces.ts\` extended |
| 275 | +- Export returns a \`Blob\` and triggers file download in the UI |
| 276 | +- Full TypeScript types matching backend DTOs |
| 277 | +- All existing frontend Vitest tests continue to pass" |
| 278 | + |
| 279 | +# ── fe-5 ────────────────────────────────────────────────────────────────────── |
| 280 | +create_issue \ |
| 281 | + "Frontend: WorkspaceDetailView should display live workspace statistics" \ |
| 282 | + "## Problem |
| 283 | +\`WorkspaceDetailView.vue\` only shows static metadata (name, owner, created date). The Overview tab has no live data — no connection count, no table configuration count, no job history summary. |
| 284 | +
|
| 285 | +## Required Changes |
| 286 | +
|
| 287 | +### Backend |
| 288 | +Add a \`GET /workspaces/{id}/stats\` endpoint returning: |
| 289 | +\`\`\`json |
| 290 | +{ |
| 291 | + \"connectionCount\": 3, |
| 292 | + \"tableConfigCount\": 12, |
| 293 | + \"totalJobsRun\": 47, |
| 294 | + \"lastJobStatus\": \"SUCCESS\", |
| 295 | + \"lastJobAt\": \"2026-04-01T10:00:00Z\" |
| 296 | +} |
| 297 | +\`\`\` |
| 298 | +
|
| 299 | +### Frontend |
| 300 | +- Add \`getWorkspaceStats(workspaceId)\` to \`frontend/src/api/workspaces.ts\` |
| 301 | +- Update \`WorkspaceDetailView.vue\` to fetch and display the stats on mount |
| 302 | +- Show loading skeleton while stats are being fetched |
| 303 | +- Show error state if the fetch fails |
| 304 | +
|
| 305 | +## Acceptance Criteria |
| 306 | +- Overview tab displays live counts and last job status |
| 307 | +- Stats refresh when navigating back to the workspace |
| 308 | +- All existing frontend tests continue to pass" |
| 309 | + |
| 310 | +echo "All issues created successfully." |
0 commit comments