Skip to main content

Digital Product Publishing System — Implementation Summary

Date: 2025-10-23
Status: Ready for Implementation
PRD Version: v1.0


Executive Summary

ValkyrAI has 80% of the infrastructure needed to ship a production-grade Digital Product Publishing System. The system leverages existing ThorAPI-generated models, workflows, and ACL security — no major architectural changes required.


What Exists (Foundation)

✅ Data Layer (ThorAPI-Generated)

  • Product, Invoice, LineItem — Commerce models
  • DigitalAsset, DownloadAccess, FileRecord — Fulfillment entities
  • ProductFunnelWizard, FunnelStage, FunnelTemplate — Funnel generation
  • FileUploadSession — Resumable multipart uploads

✅ Services & APIs

  • DigitalFulfillmentService — ACL-based download grants + signed URLs
  • FileController/files/uploads/init, /files/uploads/complete
  • StripeCheckoutModule — Stripe payment integration
  • StripeWebhookModule — Payment success handler
  • AclService/v1/auth/acl/grant, /v1/auth/acl/revoke
  • ValkyrWorkflowService — Async workflow orchestration

✅ Frontend (React/RTK Query)

  • Auto-generated service hooks for all entities
  • FileUploadSession reducers + middleware
  • ProductFunnelWizard hooks

What's Missing (Build Tasks)

1. OpenAPI Schema Enhancements

File: valkyrai/src/main/resources/openapi/api.hbs.yaml

Add to Product schema:

  • contentDataId (UUID) — Link to uploaded file
  • deliveryMode (enum) — DIGITAL_DOWNLOAD, STREAMING, LICENSE_KEY, PHYSICAL
  • maxDownloads (integer) — Download limits
  • expiresAfterDays (integer) — Entitlement expiry

Regenerate: mvn clean install in thorapi, then valkyrai


2. Backend Services (3 files)

a) DppsOrchestrationService.java

  • createProductFromUpload(fileRecordId, request) — Wraps file → product
  • publishProduct(productId, publishRequest) — Creates funnel

b) DppsPurchaseFulfillmentWorkflow.java

  • Registers workflow: DPPS_Purchase_Fulfillment
  • Tasks: VerifyPayment → GrantAccess → NotifyBuyer → PostPurchase

c) DownloadController.java

  • GET /v1/download/{downloadAccessId}?validityMinutes=15
  • Generates signed URLs with ACL checks
  • Enforces download limits + expiry

3. ExecModule Wrapper

DigitalFulfillmentModule.java — Workflow-compatible wrapper for existing DigitalFulfillmentService


4. Frontend Components (4 files)

a) FileUploader.tsx

  • Drag-drop with react-dropzone
  • Resumable uploads via /files/uploads/init + /files/uploads/complete

b) ProductForm.tsx

  • Formik form pre-filled from file metadata
  • Calls useCreateProductMutation()

c) PublishProduct.tsx

  • Triggers useStartFunnelWizardMutation()
  • Polls for completion, then calls publishFunnel endpoint

d) DppsWizard.tsx

  • Orchestrates multi-step flow: Upload → Product → Publish → Complete

5. Email Template

SQL Migration: V999__dpps_email_templates.sql

Template name: dpps_download_ready


Architecture Decisions

✅ Reuse DownloadAccess (Not DigitalDownload)

Decision: The PRD's DigitalDownload entity is already implemented as DownloadAccess with equivalent functionality:

  • digitalAssetId (links to product)
  • principalId (buyer)
  • salesOrderLineItemId (purchase record)
  • downloadToken (UUID)
  • downloadCount, maxDownloadsRemaining
  • grantedAt, expiresAt

No new entity needed.


✅ Funnel Entity: Reuse ProductFunnelWizard

Decision: The PRD's Funnel entity is already implemented as ProductFunnelWizard:

  • productId
  • wizardStatus (DRAFT, IN_PROGRESS, COMPLETED)
  • brand, targetAudience
  • deliveryMode

No new entity needed.


✅ Workflow Execution Model

Decision: Use existing ValkyrWorkflowService async execution:

  • executeWorkflow() returns CompletableFuture
  • State persisted via @Transactional(REQUIRES_NEW) helpers
  • Auth context propagated to async threads

No changes to workflow engine.


✅ ACL Permissions Strategy

Decision: Use existing Spring Security ACL:

  • Upload: Asset lands in ACL-protected folder (creator + ROLE_ADMIN + ROLE_SYSTEM)
  • Purchase: Grant READ to buyer via aclService.grantPermission(oid, buyerUsername, BasePermission.READ)
  • Download: Enforce ACL via @PreAuthorize("hasPermission(#downloadAccessId, 'DownloadAccess', 'READ')")

No new permission model.


Security Review Checklist

  • All asset paths private (never expose raw S3 keys)
  • ACL enforced at object level (Product, DigitalAsset, DownloadAccess)
  • Download routes require ACL + entitlement
  • Signed URLs have TTL ≤ 15 minutes (configurable)
  • SecureField/KMS for Stripe keys
  • Audit logs on grant/revoke
  • Rate limiting on download endpoint (per principal)

Performance Requirements (From PRD)

Upload

  • Chunk size: 5-32 MB
  • Parallel chunks: ≤ 6
  • Exponential backoff on retry
  • Resume from last completed chunk

Checkout

  • P95 latency: < 2s (entitlement check + signed URL issue)
  • Cache positive checks: 60s
  • Idempotency keys on payment + entitlement writes

Download

  • Signed URL lifetime: 15 minutes (default)
  • Refresh flow supported
  • Throttling per principal
  • P95: < 500ms URL generation

Observability & Metrics

Events to Emit

  • upload.started, upload.completed
  • product.created, product.published
  • checkout.started, checkout.succeeded, checkout.failed
  • entitlement.granted
  • download.issued, download.completed

Prometheus Counters

  • Upload success rate
  • Product creation funnel drop-off
  • Checkout conversion rate
  • Download link redemption rate
  • Error classes (by HTTP status)

Grafana Dashboards

  • TTFP (Time-to-First-Product) histogram
  • Payment → fulfillment latency
  • Download success rate (99.9% SLO)

Testing Strategy

Unit Tests

  • DppsOrchestrationService methods
  • DownloadController ACL enforcement
  • DigitalFulfillmentModule workflow integration

Integration Tests

  • Full flow: Upload → Product → Funnel → Payment → Download
  • ACL permissions: Creator, Buyer, Admin roles
  • Download limits + expiry handling
  • Payment webhook idempotency

E2E Tests

  • Upload 100MB file (resume on network failure)
  • Stripe test mode payment (live webhook)
  • Email delivery via Mailtrap
  • Download link redemption (TTL validation)

Rollout Plan

Phase 1 (Dev) — 1 Week

  • Deploy to staging
  • 3 internal test products
  • Measure: upload reliability, P95 latency
  • Gate: All acceptance criteria pass

Phase 2 (Beta) — 2 Weeks

  • 25 creators invited
  • Stripe test mode only
  • Add revocation + refund handling
  • Gate: < 1% support tickets per 100 orders

Phase 3 (GA) — Ongoing

  • Shopify bridge (RestApiModule)
  • Multi-file products (FileZipModule)
  • Coupons & bundles
  • License key generation (LicenseModule)

Success Criteria (From PRD Section 26)

  • All acceptance criteria pass in staging (Stripe test mode)
  • No mocks remain; only generated services used
  • Observability dashboards deployed (Grafana)
  • Security review signed off (ACL, TTL, revocation tests)
  • Runbooks updated for Support & Ops
  • 3 internal products successfully published and purchased

Open Questions (From PRD Section 24)

  1. Guest checkout vs. account required?

    • Recommendation: Allow guest checkout, auto-create Principal on payment success
  2. Default entitlement expiry?

    • Recommendation: Perpetual (null expiry), with Product-level override
  3. License key generation?

    • Phase 2 feature: Add LicenseModule if needed for SaaS products

Implementation Estimate

Complexity: Medium (Incremental)

  • Backend: 15-20 hours (3 services + 1 controller + 1 module)
  • Frontend: 12-15 hours (4 components + RTK Query wiring)
  • Testing: 8-10 hours (unit + integration + E2E)
  • DevOps: 5 hours (migrations, env vars, Grafana)

Total: 40-50 hours (1-2 weeks for solo developer)


Next Steps

  1. Review & Approve PRD — Stakeholder sign-off
  2. Day 1: OpenAPI schema enhancement → ThorAPI regeneration
  3. Day 2-3: Backend services (orchestration + workflow + download)
  4. Day 4-5: Frontend components (wizard + upload + forms)
  5. Day 6: Integration testing + fixes
  6. Day 7: Staging deployment + internal dogfood

Reference Documents

  • PRD: Original requirement document (26 sections)
  • Implementation Plan: DPPS_IMPLEMENTATION_PLAN.md (detailed)
  • Quick Start: DPPS_QUICK_START.md (day-by-day guide)
  • Tech Context: ValorIDE_docs/techContext.md
  • ACL Guide: web/src/main/resources/templates/typescript-redux-query/README.ACL.md

Risk Mitigation

Risk: Large file upload timeouts

Mitigation: Chunked resumable uploads + CDN ingress endpoints

Risk: Webhook race conditions

Mitigation: Idempotency keys; store provider event IDs; serialize by buyer+invoice

Mitigation: Short TTL + bound to principal; server verifies ACL & entitlement every time


Definition of Done ✅

  • All PRD acceptance criteria pass in staging
  • No mocks; only ThorAPI-generated services
  • Grafana dashboards live
  • Security review complete
  • Runbooks updated
  • 3 products successfully purchased and downloaded

Status: Ready for Implementation
Estimated Delivery: 2 weeks (with existing foundation)