{
  "info": {
    "_postman_id": "a8f5e2c1-9b34-4d7a-8e12-3f6a9c0d1e2b",
    "name": "Artikel Generator REST API",
    "description": "Dokumentasi Postman Collection lengkap untuk REST API Artikel Generator (Elysia JS, TypeScript, SQLite, Drizzle ORM, Zod).\n\n### Cara Penggunaan:\n1. Import file JSON ini ke Postman.\n2. Pastikan variabel collection `base_url` bernilai `http://localhost:8000`.\n3. Jalankan endpoint **Auth -> Login User** terlebih dahulu. Script pada tab *Tests* di endpoint Login akan otomatis menyimpan JWT token ke variabel collection `{{token}}`.\n4. Seluruh endpoint yang membutuhkan autentikasi otomatis menggunakan Bearer Token dari `{{token}}`.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{token}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "http://localhost:8000",
      "type": "string"
    },
    {
      "key": "token",
      "value": "",
      "type": "string"
    },
    {
      "key": "user_id",
      "value": "user-uuid-here",
      "type": "string"
    },
    {
      "key": "portal_id",
      "value": "portal-uuid-here",
      "type": "string"
    },
    {
      "key": "article_id",
      "value": "article-uuid-here",
      "type": "string"
    },
    {
      "key": "bank_id",
      "value": "bank-uuid-here",
      "type": "string"
    },
    {
      "key": "subscription_id",
      "value": "subscription-uuid-here",
      "type": "string"
    },
    {
      "key": "user_subscription_id",
      "value": "user-subscription-uuid-here",
      "type": "string"
    },
    {
      "key": "transaction_id",
      "value": "transaction-uuid-here",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "1. Hello & Health Check",
      "description": "Endpoint untuk mengecek status server dan pesan Hello World.",
      "item": [
        {
          "name": "Welcome / Root Endpoint",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/",
              "host": ["{{base_url}}"],
              "path": [""]
            },
            "description": "Endpoint utama untuk memastikan server berjalan."
          },
          "response": []
        },
        {
          "name": "Get Hello World Message",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/hello",
              "host": ["{{base_url}}"],
              "path": ["hello"]
            },
            "description": "Mengembalikan pesan Hello World dari database SQLite."
          },
          "response": []
        }
      ]
    },
    {
      "name": "2. Auth",
      "description": "Endpoint Autentikasi User (Register, Login, Logout).",
      "item": [
        {
          "name": "Register User Baru",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"username\": \"johndoe\",\n  \"password\": \"password123\",\n  \"email\": \"johndoe@example.com\",\n  \"phone\": \"081234567890\",\n  \"first_name\": \"John\",\n  \"last_name\": \"Doe\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/auth/register",
              "host": ["{{base_url}}"],
              "path": ["auth", "register"]
            },
            "description": "Membuat akun baru pengguna dengan default role `guest`."
          },
          "response": []
        },
        {
          "name": "Login User",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.token) {",
                  "        pm.collectionVariables.set('token', res.data.token);",
                  "        if (res.data.user && res.data.user.id) {",
                  "            pm.collectionVariables.set('user_id', res.data.user.id);",
                  "        }",
                  "        console.log('JWT Token berhasil disimpan ke collection variable {{token}}');",
                  "    }",
                  "} catch (e) {",
                  "    console.error('Gagal menyimpan token:', e);",
                  "}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identity\": \"johndoe\",\n  \"password\": \"password123\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/auth/login",
              "host": ["{{base_url}}"],
              "path": ["auth", "login"]
            },
            "description": "Login menggunakan username atau email (`identity`) dan `password`. Otomatis menyimpan JWT token ke variabel `{{token}}`."
          },
          "response": []
        },
        {
          "name": "Logout User",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/auth/logout",
              "host": ["{{base_url}}"],
              "path": ["auth", "logout"]
            },
            "description": "Menghapus sesi login user."
          },
          "response": []
        }
      ]
    },
    {
      "name": "3. User",
      "description": "Endpoint Manajemen User (Membutuhkan Bearer Token).",
      "item": [
        {
          "name": "Create User Baru",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"username\": \"adminuser\",\n  \"password\": \"adminpass123\",\n  \"email\": \"admin@example.com\",\n  \"phone\": \"081122334455\",\n  \"first_name\": \"Admin\",\n  \"last_name\": \"Utama\",\n  \"role\": \"admin\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/users",
              "host": ["{{base_url}}"],
              "path": ["users"]
            },
            "description": "Menambahkan user baru dengan password yang ter-hash. Pilihan role: `admin`, `customer`, `guest`."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort Users",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/users?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["users"],
              "query": [
                {
                  "key": "page",
                  "value": "1",
                  "description": "Halaman ke-n (default: 1)"
                },
                {
                  "key": "limit",
                  "value": "10",
                  "description": "Jumlah data per halaman (1-100, default: 10)"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | username | email | phone | first_name | last_name | role | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "username",
                  "value": "",
                  "description": "Filter berdasarkan username",
                  "disabled": true
                },
                {
                  "key": "email",
                  "value": "",
                  "description": "Filter berdasarkan email",
                  "disabled": true
                },
                {
                  "key": "phone",
                  "value": "",
                  "description": "Filter berdasarkan nomor telepon",
                  "disabled": true
                },
                {
                  "key": "first_name",
                  "value": "",
                  "description": "Filter berdasarkan nama depan",
                  "disabled": true
                },
                {
                  "key": "last_name",
                  "value": "",
                  "description": "Filter berdasarkan nama belakang",
                  "disabled": true
                },
                {
                  "key": "role",
                  "value": "customer",
                  "description": "Filter role: admin | customer | guest",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar pengguna dengan filter, opsi pagination, dan opsi sortir."
          },
          "response": []
        },
        {
          "name": "Detail User by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/users/{{user_id}}",
              "host": ["{{base_url}}"],
              "path": ["users", "{{user_id}}"]
            },
            "description": "Mengambil informasi detail user berdasarkan ID."
          },
          "response": []
        },
        {
          "name": "Update Data User by ID",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"first_name\": \"John Updated\",\n  \"last_name\": \"Doe Updated\",\n  \"phone\": \"081234567899\",\n  \"role\": \"customer\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/users/{{user_id}}",
              "host": ["{{base_url}}"],
              "path": ["users", "{{user_id}}"]
            },
            "description": "Memperbarui informasi user berdasarkan ID."
          },
          "response": []
        },
        {
          "name": "Hapus User by ID",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/users/{{user_id}}",
              "host": ["{{base_url}}"],
              "path": ["users", "{{user_id}}"]
            },
            "description": "Menghapus data user berdasarkan ID."
          },
          "response": []
        }
      ]
    },
    {
      "name": "4. Trend Portal",
      "description": "Endpoint Manajemen Trend Portal & RSS Feed.\n- Read Portal: Admin, Customer, Guest\n- Fetch RSS Feeds: Admin & Customer (Guest Forbidden)\n- Create/Update/Delete Portal: Admin Only",
      "item": [
        {
          "name": "Fetch RSS Feeds dari Semua Portal",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/trend-portals/feeds?limit=10",
              "host": ["{{base_url}}"],
              "path": ["trend-portals", "feeds"],
              "query": [
                {
                  "key": "limit",
                  "value": "10",
                  "description": "Jumlah item berita per portal (1-50, default: 10)"
                },
                {
                  "key": "search",
                  "value": "teknologi",
                  "description": "Kata kunci pencarian berita pada RSS feed",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar berita RSS terbaru secara real-time (On-Demand) dari seluruh Trend Portal yang terdaftar (Admin & Customer only)."
          },
          "response": []
        },
        {
          "name": "Fetch RSS Feeds by Portal ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/trend-portals/{{portal_id}}/feeds?limit=10",
              "host": ["{{base_url}}"],
              "path": ["trend-portals", "{{portal_id}}", "feeds"],
              "query": [
                {
                  "key": "limit",
                  "value": "10",
                  "description": "Jumlah item berita (1-50, default: 10)"
                },
                {
                  "key": "search",
                  "value": "AI",
                  "description": "Kata kunci pencarian berita pada RSS feed",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar berita RSS terbaru secara real-time (On-Demand) dari satu Trend Portal berdasarkan ID (Admin & Customer only)."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort Trend Portal",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/trend-portals?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["trend-portals"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | nama_portal | link_rss | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "nama_portal",
                  "value": "",
                  "description": "Filter berdasarkan nama portal",
                  "disabled": true
                },
                {
                  "key": "link_rss",
                  "value": "",
                  "description": "Filter berdasarkan link RSS",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar Trend Portal (Dapat diakses oleh admin, customer, dan guest)."
          },
          "response": []
        },
        {
          "name": "Detail Trend Portal by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/trend-portals/{{portal_id}}",
              "host": ["{{base_url}}"],
              "path": ["trend-portals", "{{portal_id}}"]
            },
            "description": "Mengambil detail satu Trend Portal berdasarkan ID."
          },
          "response": []
        },
        {
          "name": "Create Trend Portal Baru (Admin Only)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('portal_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nama_portal\": \"Antara News Tekno\",\n  \"link_rss\": \"https://www.antaranews.com/rss/tekno.xml\",\n  \"deskripsi\": \"Portal berita teknologi terkini dari Antara News\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/trend-portals",
              "host": ["{{base_url}}"],
              "path": ["trend-portals"]
            },
            "description": "Menambahkan data Trend Portal baru (Admin only)."
          },
          "response": []
        },
        {
          "name": "Update Trend Portal by ID (Admin Only)",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nama_portal\": \"Antara News Teknologi Updated\",\n  \"link_rss\": \"https://www.antaranews.com/rss/tekno.xml\",\n  \"deskripsi\": \"Deskripsi portal telah diperbarui\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/trend-portals/{{portal_id}}",
              "host": ["{{base_url}}"],
              "path": ["trend-portals", "{{portal_id}}"]
            },
            "description": "Memperbarui data Trend Portal berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Hapus Trend Portal by ID (Admin Only)",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/trend-portals/{{portal_id}}",
              "host": ["{{base_url}}"],
              "path": ["trend-portals", "{{portal_id}}"]
            },
            "description": "Menghapus data Trend Portal berdasarkan ID (Admin only)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "5. Article",
      "description": "Endpoint Generator Artikel AI & CRUD (Admin & Customer only, Guest tidak diizinkan).",
      "item": [
        {
          "name": "Create Artikel / Auto Generate AI",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('article_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"keyword\": \"Perkembangan Artificial Intelligence di Indonesia 2026\",\n  \"image\": \"https://images.unsplash.com/photo-1677442136019-21780ecad995\",\n  \"image_alt\": \"Ilustrasi Artificial Intelligence\",\n  \"auto_generate\": true\n}"
            },
            "url": {
              "raw": "{{base_url}}/articles",
              "host": ["{{base_url}}"],
              "path": ["articles"]
            },
            "description": "Membuat artikel baru. Jika `auto_generate` bernilai `true` (default), artikel masuk antrean generate AI di latar belakang (HTTP 202). Jika `false`, disimpan sebagai draf (HTTP 201)."
          },
          "response": []
        },
        {
          "name": "Trigger Generate / Regenerate Artikel by ID",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/articles/{{article_id}}/generate",
              "host": ["{{base_url}}"],
              "path": ["articles", "{{article_id}}", "generate"]
            },
            "description": "Memicu generate AI untuk draf artikel atau melakukan regenerate artikel yang sudah selesai/gagal di latar belakang (Admin & Customer)."
          },
          "response": []
        },
        {
          "name": "List, Filter & Paginate Artikel",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/articles?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["articles"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | keyword | title | status | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "keyword",
                  "value": "",
                  "description": "Filter berdasarkan keyword",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "completed",
                  "description": "draft | queued | processing | completed | failed",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar artikel dengan filter status, keyword, serta pagination dan sorting (Admin & Customer)."
          },
          "response": []
        },
        {
          "name": "Detail Artikel by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/articles/{{article_id}}",
              "host": ["{{base_url}}"],
              "path": ["articles", "{{article_id}}"]
            },
            "description": "Mengambil detail lengkap artikel beserta status proses AI dan pesan error jika gagal (Admin & Customer)."
          },
          "response": []
        },
        {
          "name": "Update Manual Artikel by ID",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"keyword\": \"Perkembangan AI di Indonesia\",\n  \"title\": \"Judul Artikel yang Diperbarui Secara Manual\",\n  \"meta_description\": \"Deskripsi meta SEO singkat maksimal 255 karakter.\",\n  \"content\": \"<p>Konten artikel yang telah diedit secara manual.</p>\",\n  \"image\": \"https://images.unsplash.com/photo-1677442136019-21780ecad995\",\n  \"image_alt\": \"Ilustrasi AI Updated\",\n  \"status\": \"completed\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/articles/{{article_id}}",
              "host": ["{{base_url}}"],
              "path": ["articles", "{{article_id}}"]
            },
            "description": "Memperbarui konten, judul, keyword, image, atau status (`draft` | `completed`) artikel secara manual (Admin & Customer)."
          },
          "response": []
        },
        {
          "name": "Hapus Artikel by ID",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/articles/{{article_id}}",
              "host": ["{{base_url}}"],
              "path": ["articles", "{{article_id}}"]
            },
            "description": "Menghapus artikel berdasarkan ID (Admin & Customer)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "6. Bank",
      "description": "Endpoint Manajemen Rekening Bank Tujuan Pembayaran (Admin Only).",
      "item": [
        {
          "name": "Create Bank Baru",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('bank_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nomor_rekening\": \"1234567890\",\n  \"nama_rekening\": \"PT Artikel Eiai Indonesia\",\n  \"nama_bank\": \"BCA\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/banks",
              "host": ["{{base_url}}"],
              "path": ["banks"]
            },
            "description": "Menambahkan informasi rekening bank baru (Admin only)."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort Bank",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/banks?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["banks"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | nomor_rekening | nama_rekening | nama_bank | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "nomor_rekening",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "nama_rekening",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "nama_bank",
                  "value": "BCA",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar rekening bank (Admin only)."
          },
          "response": []
        },
        {
          "name": "Detail Bank by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/banks/{{bank_id}}",
              "host": ["{{base_url}}"],
              "path": ["banks", "{{bank_id}}"]
            },
            "description": "Mengambil detail satu rekening bank berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Update Bank by ID",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nomor_rekening\": \"0987654321\",\n  \"nama_rekening\": \"PT Artikel Eiai Indonesia\",\n  \"nama_bank\": \"Bank Mandiri\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/banks/{{bank_id}}",
              "host": ["{{base_url}}"],
              "path": ["banks", "{{bank_id}}"]
            },
            "description": "Memperbarui informasi rekening bank berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Hapus Bank by ID",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/banks/{{bank_id}}",
              "host": ["{{base_url}}"],
              "path": ["banks", "{{bank_id}}"]
            },
            "description": "Menghapus informasi rekening bank berdasarkan ID (Admin only)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "7. Subscription",
      "description": "Endpoint Manajemen Paket Subscription (Admin Only).",
      "item": [
        {
          "name": "Create Subscription Baru",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('subscription_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nama_subscription\": \"Paket Pro Bulanan\",\n  \"deskripsi\": \"Akses penuh generator artikel AI dan RSS Trend Portal selama 30 hari\",\n  \"durasi\": 30,\n  \"harga\": 150000\n}"
            },
            "url": {
              "raw": "{{base_url}}/subscriptions",
              "host": ["{{base_url}}"],
              "path": ["subscriptions"]
            },
            "description": "Menambahkan informasi paket subscription baru (`durasi` dalam satuan hari, `harga` dalam satuan mata uang integer) (Admin only)."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort Subscription",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/subscriptions?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["subscriptions"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | nama_subscription | durasi | harga | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "nama_subscription",
                  "value": "",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar paket subscription (Admin only)."
          },
          "response": []
        },
        {
          "name": "Detail Subscription by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/subscriptions/{{subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["subscriptions", "{{subscription_id}}"]
            },
            "description": "Mengambil detail satu paket subscription berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Update Subscription by ID",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"nama_subscription\": \"Paket Pro Bulanan (Promo)\",\n  \"deskripsi\": \"Harga spesial promo bulanan\",\n  \"durasi\": 30,\n  \"harga\": 125000\n}"
            },
            "url": {
              "raw": "{{base_url}}/subscriptions/{{subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["subscriptions", "{{subscription_id}}"]
            },
            "description": "Memperbarui informasi paket subscription berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Hapus Subscription by ID",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/subscriptions/{{subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["subscriptions", "{{subscription_id}}"]
            },
            "description": "Menghapus informasi paket subscription berdasarkan ID (Admin only)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "8. User Subscription",
      "description": "Endpoint Manajemen Langganan User (Admin Only).",
      "item": [
        {
          "name": "Create User Subscription Baru",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('user_subscription_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"user_id\": \"{{user_id}}\",\n  \"subscription_id\": \"{{subscription_id}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/user-subscriptions",
              "host": ["{{base_url}}"],
              "path": ["user-subscriptions"]
            },
            "description": "Menambahkan langganan subscription untuk user tertentu. Field `expired_at` bersifat opsional (jika tidak diisi, otomatis dihitung dari durasi paket subscription)."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort User Subscription",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/user-subscriptions?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["user-subscriptions"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | expired_at | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "user_id",
                  "value": "{{user_id}}",
                  "disabled": true
                },
                {
                  "key": "subscription_id",
                  "value": "{{subscription_id}}",
                  "disabled": true
                },
                {
                  "key": "status_subscription",
                  "value": "active",
                  "description": "active | expired",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar langganan user dengan kalkulasi status `active`/`expired` secara dinamis (Admin only)."
          },
          "response": []
        },
        {
          "name": "Detail User Subscription by ID",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/user-subscriptions/{{user_subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["user-subscriptions", "{{user_subscription_id}}"]
            },
            "description": "Mengambil detail satu user subscription berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Update User Subscription by ID",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"user_id\": \"{{user_id}}\",\n  \"subscription_id\": \"{{subscription_id}}\",\n  \"expired_at\": \"2026-12-31T23:59:59.000Z\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/user-subscriptions/{{user_subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["user-subscriptions", "{{user_subscription_id}}"]
            },
            "description": "Memperbarui data langganan user berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Hapus User Subscription by ID",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/user-subscriptions/{{user_subscription_id}}",
              "host": ["{{base_url}}"],
              "path": ["user-subscriptions", "{{user_subscription_id}}"]
            },
            "description": "Menghapus data user subscription berdasarkan ID (Admin only)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "9. Transaction",
      "description": "Endpoint Transaksi Pembelian Subscription.\n- Create Transaksi: Guest/Customer (hanya status pending & tanpa note) atau Admin (bisa atur user_id, status, & note)\n- List, Detail, Update/Approve, Delete: Admin Only",
      "item": [
        {
          "name": "Create Transaksi (Customer / Guest)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('transaction_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"subscription_id\": \"{{subscription_id}}\",\n  \"jumlah_transaksi\": 150000,\n  \"bank_customer\": \"BCA - 5432109876 a.n John Doe\",\n  \"bank_id\": \"{{bank_id}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/transactions",
              "host": ["{{base_url}}"],
              "path": ["transactions"]
            },
            "description": "Membuat transaksi pembayaran subscription baru sebagai Customer/Guest (otomatis berstatus `pending` dan tidak boleh mengirim field `status` atau `note`)."
          },
          "response": []
        },
        {
          "name": "Create Transaksi (Admin)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "try {",
                  "    const res = pm.response.json();",
                  "    if (res.status === 'success' && res.data && res.data.id) {",
                  "        pm.collectionVariables.set('transaction_id', res.data.id);",
                  "    }",
                  "} catch (e) {}"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"user_id\": \"{{user_id}}\",\n  \"subscription_id\": \"{{subscription_id}}\",\n  \"jumlah_transaksi\": 150000,\n  \"bank_customer\": \"BCA - 5432109876 a.n John Doe\",\n  \"bank_id\": \"{{bank_id}}\",\n  \"status\": \"success\",\n  \"note\": \"Pembayaran telah diverifikasi secara manual oleh Admin\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/transactions",
              "host": ["{{base_url}}"],
              "path": ["transactions"]
            },
            "description": "Membuat transaksi oleh Admin. Admin dapat menentukan `user_id`, `status` (`pending` | `success` | `rejected`), dan `note`."
          },
          "response": []
        },
        {
          "name": "List, Filter, Paginate & Sort Transaksi (Admin Only)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/transactions?page=1&limit=10&sortBy=created_at&sortOrder=desc",
              "host": ["{{base_url}}"],
              "path": ["transactions"],
              "query": [
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "limit",
                  "value": "10"
                },
                {
                  "key": "sortBy",
                  "value": "created_at",
                  "description": "id | jumlah_transaksi | status | created_at | updated_at"
                },
                {
                  "key": "sortOrder",
                  "value": "desc",
                  "description": "asc | desc"
                },
                {
                  "key": "status",
                  "value": "pending",
                  "description": "pending | success | rejected",
                  "disabled": true
                },
                {
                  "key": "user_id",
                  "value": "{{user_id}}",
                  "disabled": true
                },
                {
                  "key": "subscription_id",
                  "value": "{{subscription_id}}",
                  "disabled": true
                },
                {
                  "key": "bank_id",
                  "value": "{{bank_id}}",
                  "disabled": true
                }
              ]
            },
            "description": "Mengambil daftar transaksi (Admin only)."
          },
          "response": []
        },
        {
          "name": "Detail Transaksi by ID (Admin Only)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/transactions/{{transaction_id}}",
              "host": ["{{base_url}}"],
              "path": ["transactions", "{{transaction_id}}"]
            },
            "description": "Mengambil detail satu transaksi berdasarkan ID (Admin only)."
          },
          "response": []
        },
        {
          "name": "Update & Approve Transaksi by ID (Admin Only)",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"success\",\n  \"note\": \"Bukti transfer valid, langganan diaktifkan.\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/transactions/{{transaction_id}}",
              "host": ["{{base_url}}"],
              "path": ["transactions", "{{transaction_id}}"]
            },
            "description": "Memperbarui transaksi dan mengubah status (misal approval ke `success`, yang otomatis mengaktifkan user subscription & mengubah role user menjadi `customer`) (Admin only)."
          },
          "response": []
        },
        {
          "name": "Hapus Transaksi by ID (Admin Only)",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/transactions/{{transaction_id}}",
              "host": ["{{base_url}}"],
              "path": ["transactions", "{{transaction_id}}"]
            },
            "description": "Menghapus data transaksi berdasarkan ID (Admin only)."
          },
          "response": []
        }
      ]
    }
  ]
}
