Skip to content

feat: Phase 2 — Upload-Check-Fix Loop - #2

Open
koalakate wants to merge 19 commits into
mainfrom
phase-2-upload-check-fix
Open

feat: Phase 2 — Upload-Check-Fix Loop#2
koalakate wants to merge 19 commits into
mainfrom
phase-2-upload-check-fix

Conversation

@koalakate

Copy link
Copy Markdown
Owner

Summary

  • Correction engine with 5 correctors: color swap, font substitution, contrast fix, font size bump, alignment snap
  • PPTX exporter: applies corrected CSM back to original PPTX, preserving untouched elements
  • API routes: deck upload/CRUD, check trigger/results, correction accept/dismiss/fix-all/export
  • BullMQ workers: async ingestion, check, and correction pipelines
  • Frontend: design tokens, upload dropzone, deck library, check results with slide preview + issue overlays, side-by-side correction view, Fix All + download
  • E2E tests: Playwright tests covering Jake's full upload-check-fix journey

Test plan

  • ruff check services/ packages/ passes
  • mypy services/ packages/ --ignore-missing-imports passes
  • pytest packages/ services/ tests/ -x --tb=short — 304 tests pass
  • Correction engine: each corrector resolves its target issue type
  • PPTX exporter: re-parsed corrected PPTX matches expected CSM
  • API routes: upload, check trigger, results retrieval, fix-all, export download
  • Workers: full async pipeline from upload to corrected PPTX

🤖 Generated with Claude Code

koalakate and others added 19 commits April 1, 2026 22:36
…d alignment correctors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lides

Implements export_pptx() that opens the original PPTX, matches shapes by
element ID to the corrected CSM, and patches font family/size, text color,
shape fill/line color, table cell colors, and element positions. Untouched
elements (animations, transitions, notes, media) are preserved.

Includes 10 round-trip tests: create PPTX -> parse -> modify CSM -> export
-> re-parse -> verify corrections applied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements Task 3 of Phase 2: REST API endpoints for the upload-check flow.
- POST /api/decks/upload with PPTX validation (type, size, empty checks)
- GET /api/decks (paginated), GET /api/decks/{id}, DELETE (soft-delete)
- POST /api/decks/{id}/check to trigger check runs
- GET /api/checks/{id} with per-slide summaries
- GET /api/checks/{id}/slides/{idx} with issue bounding boxes
- All routes enforce org-scoped RLS via set_tenant_context
- 20 API tests covering upload, CRUD, check trigger, and 404 for wrong org

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements the background job processing layer that connects upload/check/correction
APIs to actual processing logic. Includes ingestion worker (PPTX parsing + thumbnails),
check worker (rule engine + DQS calculation), correction worker (apply fixes + export PPTX),
queue helper for enqueuing jobs, and worker service in docker-compose.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and DESIGN.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…egration

Upload dropzone component with drag-and-drop, file validation, progress bar.
Deck card component with thumbnail, DQS badge, status indicator.
Deck library page with grid layout and loading/empty states.
Upload page auto-triggers check and navigates to results.
TanStack Query hooks for deck CRUD and check triggering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…DQS badge

Implements Task 8 of Phase 2: check results UI with Konva.js canvas rendering,
issue overlay bounding boxes, check panel with grouped issues, circular DQS badge,
check results overview page with slide strip, and slide detail page with side-by-side
preview and issue panel. Adds TanStack Query hooks with auto-polling during checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s/edit, Fix All, and download

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests Jake's full journey (upload → check → Fix All → download) and
Priya's edit-in-place flow (dismiss/accept/edit individual corrections).
Includes 2-minute wall-clock timing assertion per Jake's mandate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix frontend/backend API contract mismatches: deck list (items vs decks),
  correction types (correction_status, expected_value, element_bbox), export
  response (add dqs_after), and deck status field
- Add missing ingestion job enqueue after deck upload
- Fix upload page to navigate to deck detail instead of auto-triggering check
  before ingestion completes
- Read REDIS_URL from environment variable instead of hardcoding localhost
- Fix temp file cleanup on exception in ingestion and correction workers
- Fix font corrector to only replace disallowed fonts, not all fonts
- Fix exporter to only set italic/underline when explicitly specified
- Fix font size corrector to clamp scaled sizes to max bound
- Add org_id verification to correction worker query
- Replace duplicate DqsBadge in deck-card with shared component
- Update E2E test mocks to match corrected API contract

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set correction_status to pending in check worker for correctable issues
- Add missing /decks/[id] detail page with auto-check trigger after parsing
- Fix apiFetch crash on 204 No Content (DELETE) responses
- Add edit correction API endpoint and wire handleEdit to send value
- Add length check for brand_rgb in color corrector
- Fix alignment corrector to apply grid snap before margins (margins take precedence)
- Add useDeck polling for parsing status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix useEffect infinite loop in deck detail page (use ref guard)
- Add "uploaded" status to deck polling to detect ingestion transitions
- Add refetchInterval to export query for async correction worker
- Add rule_details JSONB column to Issue model for full corrector details
- Store full issue details in check worker, reconstruct in correction worker
- Preserve edited correction status in fix-all endpoint
- Set failure status on correction worker errors
- Fix content-type validation that was a no-op
- Replace silent exception swallowing in exporter with logging
- Remove unused DqsBadge import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Stream file upload in chunks to prevent OOM on large payloads
- R2Client now reads credentials from R2Settings (env vars)
- Guard fix_all from enqueuing no-op correction jobs
- Add max_length=500 to EditCorrectionRequest.value
- Remove unstable triggerCheck from useEffect deps
- Use singleton Queue to avoid Redis connection churn
- Add R2 env vars to docker-compose worker service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Prevent fix_all from double-counting already-accepted corrections
- Sanitize uploaded filename to prevent R2 key path traversal
- Normalize bounding boxes from EMU to pixel coordinates in check worker
- Wire original slide thumbnail URLs to CorrectionView (was hardcoded null)
- Fix useFixAll mutation return type to match backend FixAllResponse
- Add .pptx extension to file input accept attribute for browser compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant