# Generic Marketplace Module — Platform-Service Design

> **Scope:** A product-agnostic marketplace/store module in `platform-service` that any ByteLyst app can use to publish, discover, purchase, review, and install user-created templates.
>
> **Date:** 2026-03-01
> **Status:** ✅ COMPLETE (2026-03-02)
> **Module:** `src/modules/marketplace/` — 4 files (types.ts, repository.ts, routes.ts, marketplace.test.ts)
> **Cosmos Containers:** `marketplace_listings`, `marketplace_reviews`, `marketplace_installs`, `marketplace_certifications`, `marketplace_reports`, `marketplace_votes`
> **Routes:** Catalog, listing CRUD, reviews, installs, certification workflow, reports, admin
> **Tests:** 32 Vitest tests

---

## 1. Why Build This in Common Platform?

Multiple ByteLyst apps need a marketplace for user-created content:

| App            | Template Type                                               | Example                                |
| -------------- | ----------------------------------------------------------- | -------------------------------------- |
| **JarvisJr**   | Agent templates (personas, prompts, voice config)           | "FAANG Interview Prep Coach"           |
| **MindLyst**   | Brain Packs (brain configs, triage rules, default memories) | "Freelancer Finance Brain Pack"        |
| **ChronoMind** | Routine templates, timer presets                            | "Morning Routine for Parents (45 min)" |
| **NomGap**     | Fasting protocols, custom meal plans                        | "Ramadan Intermittent Protocol"        |
| **PeakPulse**  | Route presets, challenge templates                          | "Colorado 14ers Checklist"             |

Building this once in platform-service means every app gets: catalog, search, reviews, ratings, comments, purchases, certification, and analytics — for free.

---

## 2. What Already Exists in Platform-Service

| Existing Module            | Reusable For Marketplace?                      | Gap                                                                       |
| -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------- |
| **items**                  | Item CRUD, types, statuses, visibility, labels | Tracker-scoped (bugs/features), not generic listings                      |
| **comments**               | Threaded comments (CRUD, author-only edit)     | Currently tied to `tracker_comments` container — needs generic `entityId` |
| **votes**                  | Upvote toggle, count per item                  | Currently tied to `tracker_votes` — needs generic `entityId`              |
| **public**                 | Unauthenticated browsing, submissions, voting  | Tracker-specific routes — needs generic catalog routes                    |
| **feedback**               | In-app feedback collection                     | Could feed into review system                                             |
| **products**               | Product registry (productId lookup)            | Marketplace listings are per-product                                      |
| **subscriptions + stripe** | Payment infrastructure                         | Could handle paid template purchases                                      |
| **blob**                   | File storage (SAS tokens)                      | Template screenshots, preview assets                                      |

**Conclusion:** ~60% of infrastructure exists. The main gaps are: listings with JSON payloads, star ratings/reviews, certification workflow, install tracking, discovery/search, and versioning.

---

## 3. Data Model

### 3.1 Cosmos Containers (New)

| Container                    | Partition Key | Purpose                     |
| ---------------------------- | ------------- | --------------------------- |
| `marketplace_listings`       | `/productId`  | Published template listings |
| `marketplace_reviews`        | `/listingId`  | Star ratings + text reviews |
| `marketplace_installs`       | `/userId`     | Track who installed what    |
| `marketplace_certifications` | `/listingId`  | Certification audit trail   |
| `marketplace_reports`        | `/listingId`  | User abuse/flag reports     |

### 3.2 Core Types

```typescript
// ── Listing (the publishable template) ────────────────────

interface MarketplaceListingDoc {
  id: string; // lst_<uuid>
  productId: string; // "jarvisjr" | "mindlyst" | "chronomind" | "nomgap" | "peakpulse"
  templateType: string; // Product-specific: "agent" | "brain_pack" | "routine" | "protocol" | etc.

  // Author
  authorId: string; // userId of creator
  authorName: string; // Display name
  authorAvatarUrl: string | null;

  // Content
  title: string; // "FAANG Interview Prep Coach"
  shortDescription: string; // 1-2 sentence pitch (max 200 chars)
  description: string; // Full markdown description
  tags: string[]; // ["interview", "career", "tech"]
  category: string; // Product-specific categories
  screenshots: string[]; // Blob URLs for preview images
  previewUrl: string | null; // Optional demo/preview link

  // The actual template payload (product-specific JSON)
  payload: Record<string, unknown>; // Generic JSON — each app defines its own schema
  payloadVersion: string; // "1.0", "1.1" — for forward compatibility

  // Pricing
  pricingModel: 'free' | 'paid' | 'freemium';
  priceInCents: number; // 0 for free, e.g. 499 for $4.99
  currency: string; // "usd"

  // Certification
  certificationStatus: 'draft' | 'submitted' | 'in_review' | 'approved' | 'rejected' | 'suspended';
  certificationNotes: string | null; // Reviewer feedback
  certifiedAt: string | null;
  certifiedBy: string | null; // Admin userId

  // Stats (denormalized for fast reads)
  installCount: number;
  reviewCount: number;
  averageRating: number; // 0.0 - 5.0
  voteCount: number; // Upvotes (reuse existing votes pattern)

  // Versioning
  version: string; // "1.0.0"
  previousVersionId: string | null; // Link to previous version

  // Metadata
  visibility: 'private' | 'unlisted' | 'public';
  featured: boolean; // Admin-set
  createdAt: string;
  updatedAt: string;
  publishedAt: string | null;
}

// ── Review (star rating + text) ──────────────────────────

interface MarketplaceReviewDoc {
  id: string; // rev_<uuid>
  listingId: string;
  productId: string;
  authorId: string;
  authorName: string;
  rating: number; // 1-5 stars
  title: string; // Review headline
  body: string; // Review text
  helpful: number; // "Was this helpful?" count
  verified: boolean; // Author actually installed the template
  createdAt: string;
  updatedAt: string;
}

// ── Install (track who installed what) ───────────────────

interface MarketplaceInstallDoc {
  id: string; // inst_<uuid>
  listingId: string;
  productId: string;
  userId: string;
  version: string; // Version at time of install
  installedAt: string;
  uninstalledAt: string | null;
}

// ── Certification (audit trail) ──────────────────────────

interface MarketplaceCertificationDoc {
  id: string; // cert_<uuid>
  listingId: string;
  productId: string;
  action: 'submitted' | 'approved' | 'rejected' | 'suspended' | 'resubmitted';
  performedBy: string; // Admin userId or "system"
  notes: string;
  automatedChecks: {
    // Results from auto-review
    promptSafety: 'pass' | 'fail' | 'warn';
    contentPolicy: 'pass' | 'fail' | 'warn';
    payloadValid: boolean;
    screenshotCount: number;
  } | null;
  createdAt: string;
}

// ── Report (user abuse/flag) ──────────────────────────────

interface MarketplaceReportDoc {
  id: string; // rpt_<uuid>
  listingId: string;
  productId: string;
  reporterId: string; // userId of reporter
  reason: 'spam' | 'harmful' | 'misleading' | 'copyright' | 'inappropriate' | 'other';
  details: string; // Free text explanation
  status: 'open' | 'resolved' | 'dismissed';
  resolvedBy: string | null; // Admin userId
  resolutionNotes: string | null;
  createdAt: string;
  resolvedAt: string | null;
}
```

---

## 4. API Design

### 4.1 Author Endpoints (Authenticated)

| Method   | Path                                | Description                      |
| -------- | ----------------------------------- | -------------------------------- |
| `POST`   | `/marketplace/listings`             | Create draft listing             |
| `GET`    | `/marketplace/listings/mine`        | List my listings                 |
| `GET`    | `/marketplace/listings/:id`         | Get listing detail               |
| `PUT`    | `/marketplace/listings/:id`         | Update draft/rejected listing    |
| `POST`   | `/marketplace/listings/:id/submit`  | Submit for certification         |
| `POST`   | `/marketplace/listings/:id/publish` | Publish approved listing         |
| `DELETE` | `/marketplace/listings/:id`         | Delete listing (author or admin) |

### 4.2 Public Catalog Endpoints (No Auth Required)

| Method | Path                               | Description                                  |
| ------ | ---------------------------------- | -------------------------------------------- |
| `GET`  | `/public/marketplace`              | Browse catalog (paginated, filtered, sorted) |
| `GET`  | `/public/marketplace/:id`          | Get public listing detail                    |
| `GET`  | `/public/marketplace/:id/reviews`  | Get reviews for a listing                    |
| `GET`  | `/public/marketplace/featured`     | Featured/trending listings                   |
| `GET`  | `/public/marketplace/categories`   | List categories for a product                |
| `GET`  | `/public/marketplace/search?q=...` | Full-text search                             |

### 4.3 Consumer Endpoints (Authenticated)

| Method   | Path                                | Description                                |
| -------- | ----------------------------------- | ------------------------------------------ |
| `POST`   | `/marketplace/listings/:id/install` | Install a listing (track + return payload) |
| `DELETE` | `/marketplace/listings/:id/install` | Uninstall                                  |
| `GET`    | `/marketplace/installs`             | List my installed templates                |
| `POST`   | `/marketplace/listings/:id/reviews` | Add review (must have installed)           |
| `PUT`    | `/marketplace/reviews/:id`          | Edit my review                             |
| `DELETE` | `/marketplace/reviews/:id`          | Delete my review                           |
| `POST`   | `/marketplace/listings/:id/vote`    | Upvote toggle (reuse votes pattern)        |

### 4.4 Admin Endpoints (Admin Auth)

| Method | Path                                     | Description               |
| ------ | ---------------------------------------- | ------------------------- |
| `GET`  | `/marketplace/admin/pending`             | Listings awaiting review  |
| `POST` | `/marketplace/admin/:id/approve`         | Approve listing           |
| `POST` | `/marketplace/admin/:id/reject`          | Reject with notes         |
| `POST` | `/marketplace/admin/:id/suspend`         | Suspend published listing |
| `POST` | `/marketplace/admin/:id/feature`         | Toggle featured flag      |
| `GET`  | `/marketplace/admin/stats`               | Marketplace analytics     |
| `GET`  | `/marketplace/admin/reports`             | User abuse reports queue  |
| `POST` | `/marketplace/admin/reports/:id/resolve` | Resolve a report          |

### 4.5 Report/Flag Endpoints (Authenticated)

| Method | Path                               | Description                       |
| ------ | ---------------------------------- | --------------------------------- |
| `POST` | `/marketplace/listings/:id/report` | Flag a listing (reason + details) |
| `GET`  | `/marketplace/reports/mine`        | List my submitted reports         |

### 4.6 Query Parameters for Catalog Browse

```
GET /public/marketplace?productId=jarvisjr
    &templateType=agent
    &category=career
    &tags=interview,tech
    &pricingModel=free
    &minRating=4
    &sortBy=installCount|rating|newest|trending
    &q=interview+prep
    &limit=20
    &offset=0
```

---

## 5. Certification Workflow

```
Author creates listing (draft)
    |
    v
Author submits for review
    |
    v
+-- Automated checks run --------+
|   - Prompt safety scan (LLM)   |
|   - Content policy check        |
|   - Payload schema validation   |
|   - Screenshot count >= 1       |
+--------------------------------+
    |
    +-- Auto-fail? --> REJECTED (with notes)
    |
    v
Manual admin review queue
    |
    +-- APPROVED --> Author can publish
    |
    +-- REJECTED --> Author can edit and resubmit
    |
    v
Published (visible in public catalog)
    |
    +-- Reports/flags --> Admin can SUSPEND
```

### Automated Check Details

| Check                  | What It Does                                                    | Fail Criteria                                                     |
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------- |
| **Prompt safety**      | LLM scans system prompt for harmful content, jailbreaks         | Harmful, deceptive, or policy-violating prompts                   |
| **Content policy**     | Scan title + description for profanity, spam, misleading claims | Profanity, spam keywords, medical/legal claims without disclaimer |
| **Payload validation** | Zod schema validation per product type                          | Invalid JSON structure for the templateType                       |
| **Screenshots**        | Count uploaded screenshots                                      | Less than 1 screenshot                                            |
| **Duplicate check**    | Cosine similarity against existing listings                     | >90% similarity to existing listing                               |

---

## 6. Product-Specific Payload Schemas

Each app defines what goes inside the `payload` field. The marketplace module treats it as opaque JSON — validation is delegated to product-specific Zod schemas.

### JarvisJr Agent Template Payload

```typescript
{
  agentName: string;           // "Coach", "Lingua", etc. (user can rename after install)
  defaultVoice: string;        // Voice ID from TTS provider
  systemPrompt: string;        // The core coaching prompt
  welcomeMessage: string;      // First message when session starts
  coachingFramework: string;   // "socratic" | "cbr" | "free_form" | "structured"
  suggestedSessionLength: number;  // Minutes
  difficultyLevel: string;    // "beginner" | "intermediate" | "advanced"
  tags: string[];
  exampleConversation: string; // Sample dialogue showing the agent in action
}
```

### MindLyst Brain Pack Payload

```typescript
{
  brains: Array<{
    name: string; // "Work", "Finance", etc.
    description: string;
    triageRules: string; // Triage prompt
    defaultCategories: string[];
  }>;
  suggestedRoutine: string; // "Morning brief at 8am, evening wind-down at 9pm"
}
```

### ChronoMind Routine Template Payload

```typescript
{
  routineName: string;
  steps: Array<{
    label: string;
    durationMinutes: number;
    urgency: string;
  }>;
  totalMinutes: number;
  tags: string[];
}
```

### NomGap Protocol Payload

```typescript
{
  protocolName: string;
  fastHours: number;
  eatHours: number;
  description: string;
  difficulty: string;
  electrolyteSchedule: object | null;
  culturalContext: string | null; // "ramadan" | "ekadashi" | etc.
}
```

### PeakPulse Challenge Payload

```typescript
{
  challengeName: string;
  activityType: string;            // "hiking" | "skiing" | "trail_running"
  peaks: Array<{
    name: string;
    elevationMeters: number;
    latitude: number;
    longitude: number;
    difficulty: string;             // "easy" | "moderate" | "hard" | "expert"
    notes: string;
  }>;
  totalPeaks: number;
  region: string;                  // "Colorado", "Alps", etc.
  tags: string[];
}
```

---

## 7. Reuse Strategy — Existing Modules

| Existing Module | How Marketplace Reuses It                                                                                                                             |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **comments**    | **Decision: keep reviews separate.** Reviews are structurally different (star rating, verified install, helpful count). Comments remain tracker-only. |
| **votes**       | Generalize to support `entityType: 'tracker_item' \| 'marketplace_listing'`. Same toggle pattern.                                                     |
| **blob**        | Template screenshots upload via existing SAS token endpoints. New container: `marketplace_assets`.                                                    |
| **stripe**      | Paid template purchases via existing Stripe integration. New `line_item` type for marketplace.                                                        |
| **flags**       | Feature-flag new marketplace features per product.                                                                                                    |
| **delivery**    | Email notifications: "Your listing was approved", "New review on your template".                                                                      |
| **audit**       | Audit trail for certification actions.                                                                                                                |

---

## 8. Implementation Phases

### Phase 1 — Core Marketplace (Sprint 1-2)

New module: `services/platform-service/src/modules/marketplace/`

| File                          | Content                                         |
| ----------------------------- | ----------------------------------------------- |
| `types.ts`                    | All Zod schemas + TypeScript interfaces above   |
| `listing-repository.ts`       | Listing CRUD against `marketplace_listings`     |
| `review-repository.ts`        | Review CRUD against `marketplace_reviews`       |
| `install-repository.ts`       | Install tracking against `marketplace_installs` |
| `certification-repository.ts` | Certification audit trail                       |
| `routes.ts`                   | Author + consumer + public + admin endpoints    |
| `marketplace.test.ts`         | Full test suite                                 |

**Estimated:** ~800-1000 lines, ~40-50 tests.

### Phase 2 — Automated Certification (Sprint 3)

- LLM-based prompt safety scan
- Content policy checker
- Payload schema validation per product type
- Auto-reject pipeline

### Phase 3 — Paid Templates + Revenue Share (Sprint 4)

- Stripe integration for marketplace purchases
- Revenue share tracking (70% author / 30% platform)
- Payout management

### Phase 4 — Discovery and Analytics (Sprint 5)

- Trending algorithm (installs x recency x rating)
- Featured curation (admin)
- Author analytics dashboard
- Recommendation engine ("Users who installed X also installed Y")

---

## 9. Cosmos Container Cost Impact

| Container                    | Estimated Docs (Year 1) | RU Impact                  |
| ---------------------------- | ----------------------- | -------------------------- |
| `marketplace_listings`       | ~5,000                  | Low (mostly reads)         |
| `marketplace_reviews`        | ~20,000                 | Low                        |
| `marketplace_installs`       | ~100,000                | Medium (high write volume) |
| `marketplace_certifications` | ~10,000                 | Low                        |
| `marketplace_reports`        | ~2,000                  | Low                        |

Serverless Cosmos DB: ~$0.25/100K RU. Total estimated cost: **<$5/month** at launch scale.

Additional blob container needed: `marketplace_assets` (screenshots, preview images) — uses existing `blob` module SAS token endpoints.

---

## 10. Rate Limiting

All public marketplace endpoints inherit the rate limiting from the `public` module pattern:

| Endpoint Type         | Rate Limit          |
| --------------------- | ------------------- |
| Public browse/search  | 60 req/min per IP   |
| Public listing detail | 60 req/min per IP   |
| Report/flag           | 5 req/min per IP    |
| Install               | 30 req/min per user |
| Review                | 10 req/min per user |

---

## 11. Versioning and Update Workflow

When an author updates a published listing:

1. Author edits listing and bumps `version` field (e.g., 1.0.0 -> 1.1.0)
2. Updated listing goes through certification again (same workflow)
3. Once approved, the listing is updated in-place (same `id`)
4. `previousVersionId` points to a snapshot of the old version
5. Users who installed v1.0.0 see a "Update Available" badge on their agent card
6. Update is optional — users keep their customizations, only the base template payload changes
7. Delivery module sends email: "A template you installed has been updated"

---

## 12. Dashboard UI (Admin + Tracker)

### Admin Dashboard — Marketplace Management

New pages under `/ops/marketplace/`:

| Page                         | Features                                                     |
| ---------------------------- | ------------------------------------------------------------ |
| `/ops/marketplace`           | Overview: pending reviews, total listings, installs, revenue |
| `/ops/marketplace/pending`   | Certification queue: approve/reject with notes               |
| `/ops/marketplace/listings`  | All listings: filter by product, status, author              |
| `/ops/marketplace/analytics` | Charts: installs over time, top listings, revenue            |

### Per-App — Marketplace Browse UI

Each app builds its own browse UI consuming the public API:

```
/marketplace                    — Browse catalog (grid of cards)
/marketplace/:id                — Listing detail (description, reviews, install button)
/marketplace/mine               — My published templates
/marketplace/create             — Create/edit listing wizard
/marketplace/installed          — My installed templates
```

---

## 13. Cross-App Benefits Summary

| App            | Without Generic Marketplace                   | With Generic Marketplace                         |
| -------------- | --------------------------------------------- | ------------------------------------------------ |
| **JarvisJr**   | Build custom agent store from scratch         | Just define payload schema, get full marketplace |
| **MindLyst**   | Brain Pack sharing via simple deep links only | Full catalog, reviews, ratings, discovery        |
| **ChronoMind** | Routine sharing not planned                   | Community routine templates with ratings         |
| **NomGap**     | Custom protocols stuck in-app                 | Share protocols, cultural fasting templates      |
| **PeakPulse**  | No sharing mechanism                          | Route/challenge templates from community         |
