{
  "info": {
    "name": "PaperClub - Public Ordering API",
    "description": "Collection to test PaperClub public ordering flow (sites, cart, brief, coupon, checkout). Public site search supports site name, exact URL/domain matching, and website keywords. Completed briefs require description; title is optional. Public API prices and cart amounts are returned excluding tax. Includes advertiser file upload and submitted article review. Review writes require a current contentVersion. Article approval is explicit and separate from actual publication.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost"
    },
    {
      "key": "apiKey",
      "value": ""
    },
    {
      "key": "articleId",
      "value": ""
    },
    {
      "key": "cartItemId",
      "value": ""
    },
    {
      "key": "couponCode",
      "value": "WELCOME10"
    },
    {
      "key": "siteSearchTerm",
      "value": "e-sante.fr"
    },
    {
      "key": "uploadedDocumentId",
      "value": ""
    },
    {
      "key": "orderItemId",
      "value": ""
    },
    {
      "key": "postId",
      "value": ""
    },
    {
      "key": "contentVersion",
      "value": ""
    },
    {
      "key": "commentId",
      "value": ""
    },
    {
      "key": "excerptQuote",
      "value": ""
    },
    {
      "key": "excerptOccurrence",
      "value": "1"
    }
  ],
  "item": [
    {
      "name": "1) Public Catalog",
      "item": [
        {
          "name": "Get Public Sites",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/sites?limit=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "sites"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "20"
                },
                {
                  "key": "search",
                  "value": "{{siteSearchTerm}}",
                  "disabled": true,
                  "description": "Enable to test search by exact URL/domain or website keywords."
                }
              ]
            },
            "description": "Fetches public sites and stores the first item articleId into {{articleId}}. Returned prices are excluding tax. Optional disabled `search` query can be enabled to test site name, exact URL/domain matching, or website keywords."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "let data = [];",
                  "try { data = pm.response.json(); } catch (e) {}",
                  "if (Array.isArray(data) && data.length > 0 && data[0].articleId) {",
                  "  pm.collectionVariables.set('articleId', data[0].articleId);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Public Topics",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/topics",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "topics"
              ]
            },
            "description": "Returns topic stats used by public discovery."
          }
        }
      ]
    },
    {
      "name": "2) Cart",
      "item": [
        {
          "name": "Get Current Cart",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "me"
              ]
            },
            "description": "Returns current cart amounts excluding tax and stores first cart item id in {{cartItemId}} when present."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "let cart = {};",
                  "try { cart = pm.response.json(); } catch (e) {}",
                  "if (cart && Array.isArray(cart.items) && cart.items.length > 0 && cart.items[0].id) {",
                  "  pm.collectionVariables.set('cartItemId', cart.items[0].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Cart Count",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/count",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "count"
              ]
            },
            "description": "Returns count of cart items."
          }
        },
        {
          "name": "Add Article(s) to Cart",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"items\": [\n    {\n      \"article\": \"{{articleId}}\",\n      \"options\": []\n    }\n  ]\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/add",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "add"
              ]
            },
            "description": "Adds one article into current cart (expects 201)."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
                  "let cart = {};",
                  "try { cart = pm.response.json(); } catch (e) {}",
                  "if (cart && Array.isArray(cart.items) && cart.items.length > 0 && cart.items[0].id) {",
                  "  pm.collectionVariables.set('cartItemId', cart.items[0].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Related Sites",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/related-sites",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "related-sites"
              ]
            },
            "description": "Returns site recommendations based on cart content."
          }
        },
        {
          "name": "Remove One Cart Item (Canonical)",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/items/{{cartItemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "items",
                "{{cartItemId}}"
              ]
            },
            "description": "Deletes one cart item by id and returns updated cart."
          }
        },
        {
          "name": "Empty Cart",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/empty",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "empty"
              ]
            },
            "description": "Empties the cart."
          }
        }
      ]
    },
    {
      "name": "3) Brief",
      "item": [
        {
          "name": "Upload Advertiser Article",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/documents",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "documents"
              ]
            },
            "description": "Uploads synthetic TXT bytes and stores uploadedDocumentId. Replace filename and contentBase64 with the real article (plain base64, no data URL prefix). Maximum 10 MiB; DOC, DOCX, PDF, TXT, ODT and RTF. For attachments use purpose=attachment and brief.files.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"filename\": \"article.txt\",\n  \"contentBase64\": \"QXJ0aWNsZSBkZSB0ZXN0IHBvdXIgdmFsaWRhdGlvbi4K\",\n  \"purpose\": \"article\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
                  "if (pm.response.code === 201) pm.collectionVariables.set('uploadedDocumentId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Save Brief (Completed)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"brief\": {\n    \"cart_item\": \"{{cartItemId}}\",\n    \"status\": \"brief.status.completed\",\n    \"description\": \"Contenu orienté SEO avec un lien interne DoFollow vers la page cible.\",\n    \"keyword\": \"seo\",\n    \"publication_date\": null,\n    \"links\": [\n      {\n        \"anchor\": \"Ancre\",\n        \"url\": \"https://example.com/page-cible\"\n      }\n    ],\n    \"options\": [],\n    \"files\": []\n  }\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/brief",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "brief"
              ]
            },
            "description": "Creates or updates brief data for one cart item and marks it as completed (ready for checkout). `description` is required for completed briefs; `title` is optional and intentionally omitted from this sample."
          }
        },
        {
          "name": "Save Brief with Advertiser Article",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/brief",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "brief"
              ]
            },
            "description": "Run Upload Advertiser Article first. Attach its UUID as articles_provided and enable advertiser_provided_article. The completed brief still requires description and backlink data. Only files belonging to this account with purpose=article are accepted.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"brief\": {\n    \"cart_item\": \"{{cartItemId}}\",\n    \"status\": \"brief.status.completed\",\n    \"description\": \"Contenu orient\\u00e9 SEO avec un lien interne DoFollow vers la page cible.\",\n    \"keyword\": \"seo\",\n    \"publication_date\": null,\n    \"links\": [\n      {\n        \"anchor\": \"Ancre\",\n        \"url\": \"https://example.com/page-cible\"\n      }\n    ],\n    \"options\": [],\n    \"files\": [],\n    \"advertiser_provided_article\": true,\n    \"articles_provided\": [\n      \"{{uploadedDocumentId}}\"\n    ]\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "4) Coupon",
      "item": [
        {
          "name": "Add Coupon",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"coupon\": {\n    \"code\": \"{{couponCode}}\"\n  }\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/add-coupon",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "add-coupon"
              ]
            },
            "description": "Applies a coupon code to the current cart."
          }
        },
        {
          "name": "Remove Coupon",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/carts/remove-coupon",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "carts",
                "remove-coupon"
              ]
            },
            "description": "Removes currently applied coupon."
          }
        }
      ]
    },
    {
      "name": "5) Checkout",
      "item": [
        {
          "name": "Get Wallet Status",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/wallet/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "wallet",
                "me"
              ]
            },
            "description": "Returns wallet available balance and whether the current cart amount excluding tax can be placed."
          },
          "response": []
        },
        {
          "name": "Place Order",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/checkout/place-order",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "checkout",
                "place-order"
              ]
            },
            "description": "Places an order from current cart. Requires a valid cart state (briefs complete, pricing valid, funds/payment conditions)."
          }
        }
      ]
    },
    {
      "name": "6) Submitted Article Review",
      "description": "Discover order_item_id and post_ids, then read the exact article version. Commenting and approval require canReview=true and the latest contentVersion. General and excerpt comments are alternatives. Request corrections or approve only after deliberate review; these actions change the existing workflow. On HTTP 409, reread the article. This folder does not place an order.",
      "item": [
        {
          "name": "Get Public Orders",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/orders",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "orders"
              ]
            },
            "description": "Returns orders and stores the first row order_item_id UUID and first submitted post id when present. order_id is a human reference."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code === 200) {",
                  "  const orders = pm.response.json();",
                  "  const order = orders.find(item => item.post_ids && item.post_ids.length) || orders[0];",
                  "  if (order && order.order_item_id) pm.collectionVariables.set('orderItemId', order.order_item_id);",
                  "  if (order && order.post_ids && order.post_ids.length) pm.collectionVariables.set('postId', order.post_ids[0]);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "List Submitted Articles",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/orders/{{orderItemId}}/posts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "orders",
                "{{orderItemId}}",
                "posts"
              ]
            },
            "description": "Uses the order_item_id UUID. Drafts are excluded. Choose the version to review, then use Read Article before writing. Stores the first submitted post id when present."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code === 200) {",
                  "  const posts = pm.response.json();",
                  "  if (posts.length) pm.collectionVariables.set('postId', posts[0].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Read Article",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/posts/{{postId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "posts",
                "{{postId}}"
              ]
            },
            "description": "Returns HTML, exact plainText, comments, state, canReview and contentVersion. Read the article and save this version before any review write. Sets postId, contentVersion and the last commentId."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Add General Comment",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/posts/{{postId}}/comments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "posts",
                "{{postId}}",
                "comments"
              ]
            },
            "description": "Requires the current version from Read Article and an open review state. Omit quote for a general comment.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contentVersion\": \"{{contentVersion}}\",\n  \"comment\": \"Please clarify the main recommendation.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Add Excerpt Comment",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/posts/{{postId}}/comments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "posts",
                "{{postId}}",
                "comments"
              ]
            },
            "description": "Set excerptQuote to an exact non-empty excerpt from plainText and excerptOccurrence to its 1-based occurrence. The pre-request script JSON-escapes the excerpt, including quotes and line breaks. Read the current article first.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contentVersion\": \"{{contentVersion}}\",\n  \"comment\": \"Please clarify this passage.\",\n  \"quote\": {{excerptQuoteJson}},\n  \"occurrence\": {{excerptOccurrence}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.variables.set('excerptQuoteJson', JSON.stringify(pm.variables.get('excerptQuote') || ''));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Delete Comment",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/comments/{{commentId}}/delete",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "comments",
                "{{commentId}}",
                "delete"
              ]
            },
            "description": "Removes the chosen comment while review is open, using the version of its article. The response includes remaining comments.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contentVersion\": \"{{contentVersion}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Request Corrections",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/posts/{{postId}}/needs-review",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "posts",
                "{{postId}}",
                "needs-review"
              ]
            },
            "description": "Save at least one comment first. Requests corrections through the existing workflow and revision limits. Requires the latest contentVersion and canReview=true.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contentVersion\": \"{{contentVersion}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Approve Article",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-PaperClub-API-Key",
                "value": "{{apiKey}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/public/posts/{{postId}}/validate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "public",
                "posts",
                "{{postId}}",
                "validate"
              ]
            },
            "description": "Run only after explicit approval of the exact current article. Requires contentVersion and canReview=true. Optionally add publicationDate as YYYY-MM-DD (today or later). Approval is not actual publication.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contentVersion\": \"{{contentVersion}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
                  "if (pm.response.code < 400) {",
                  "  const post = pm.response.json();",
                  "  if (post.id) pm.collectionVariables.set('postId', post.id);",
                  "  if (post.contentVersion) pm.collectionVariables.set('contentVersion', post.contentVersion);",
                  "  const comments = post.comments || [];",
                  "  if (comments.length) pm.collectionVariables.set('commentId', comments[comments.length - 1].id);",
                  "}"
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}
