Expose sort_order on CreateExamPrepUnitInput; insert applies explicit index with sibling shifting (aligned with LMS course create). Updated Swagger and LMS-Personas Postman collection. Co-authored-by: Cursor <cursoragent@cursor.com>
287 lines
9.3 KiB
JSON
287 lines
9.3 KiB
JSON
{
|
|
"info": {
|
|
"_postman_id": "e2b904c1-a8d7-4132-90c9-4f6619c82b91",
|
|
"name": "LMS Personas - Catalog CRUD",
|
|
"description": "Regenerated against `/api/v1/personas`. Bearer auth; permissions: personas.list, personas.create, personas.get, personas.update, personas.delete.\n\nResponse persona objects include `profile_picture` and `gender` keys always (JSON `null` when unset). Practices reference catalog rows via `persona_id`.\n\nRun folder top-to-bottom: Create captures `persona_id`; Delete removes that row.\nOptional: set collection variable `persona_id` manually (e.g. `1`) for read-only tests without Create/Delete.",
|
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
},
|
|
"auth": {
|
|
"type": "bearer",
|
|
"bearer": [
|
|
{
|
|
"key": "token",
|
|
"value": "{{access_token}}",
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"variable": [
|
|
{
|
|
"key": "base_url",
|
|
"value": "http://localhost:8080"
|
|
},
|
|
{
|
|
"key": "access_token",
|
|
"value": ""
|
|
},
|
|
{
|
|
"key": "persona_id",
|
|
"value": "1",
|
|
"type": "string"
|
|
}
|
|
],
|
|
"item": [
|
|
{
|
|
"name": "01 - Personas CRUD",
|
|
"item": [
|
|
{
|
|
"name": "Create persona",
|
|
"event": [
|
|
{
|
|
"listen": "test",
|
|
"script": {
|
|
"exec": [
|
|
"pm.test(\"Status code is 201\", function () {",
|
|
" pm.response.to.have.status(201);",
|
|
"});",
|
|
"const body = pm.response.json();",
|
|
"pm.test(\"Persona in data\", function () {",
|
|
" pm.expect(body.success).to.be.true;",
|
|
" pm.expect(body.data.id).to.be.a(\"number\");",
|
|
" pm.expect(body.data).to.have.property(\"profile_picture\");",
|
|
" pm.expect(body.data).to.have.property(\"gender\");",
|
|
"});",
|
|
"pm.collectionVariables.set(\"persona_id\", String(body.data.id));"
|
|
],
|
|
"type": "text/javascript"
|
|
}
|
|
}
|
|
],
|
|
"request": {
|
|
"method": "POST",
|
|
"header": [
|
|
{
|
|
"key": "Content-Type",
|
|
"value": "application/json",
|
|
"type": "text"
|
|
}
|
|
],
|
|
"body": {
|
|
"mode": "raw",
|
|
"raw": "{\n \"name\": \"Postman Coach\",\n \"description\": \"Smoke-test persona from Postman\",\n \"profile_picture\": \"https://cdn.example.com/personas/postman-coach.png\",\n \"gender\": \"female\",\n \"is_active\": true\n}"
|
|
},
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas"
|
|
]
|
|
},
|
|
"description": "Maps to `domain.CreateLmsPersonaInput`: `name` required; others optional. Whitespace-only `gender` omitted on save."
|
|
},
|
|
"response": []
|
|
},
|
|
{
|
|
"name": "List personas (default paging)",
|
|
"event": [
|
|
{
|
|
"listen": "test",
|
|
"script": {
|
|
"exec": [
|
|
"pm.test(\"Status code is 200\", function () {",
|
|
" pm.response.to.have.status(200);",
|
|
"});",
|
|
"const body = pm.response.json();",
|
|
"pm.test(\"List envelope\", function () {",
|
|
" pm.expect(body.data.personas).to.be.an(\"array\");",
|
|
" pm.expect(body.data.total_count).to.be.a(\"number\");",
|
|
" pm.expect(body.data.limit).to.be.a(\"number\");",
|
|
" pm.expect(body.data.offset).to.be.a(\"number\");",
|
|
"});"
|
|
],
|
|
"type": "text/javascript"
|
|
}
|
|
}
|
|
],
|
|
"request": {
|
|
"method": "GET",
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas?limit=20&offset=0",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas"
|
|
],
|
|
"query": [
|
|
{
|
|
"key": "active_only",
|
|
"value": "true",
|
|
"description": "Omit or true: only active. false: include inactive."
|
|
},
|
|
{
|
|
"key": "limit",
|
|
"value": "20",
|
|
"description": "Defaults to 20 if invalid omitted; capped at 200 server-side."
|
|
},
|
|
{
|
|
"key": "offset",
|
|
"value": "0"
|
|
}
|
|
]
|
|
},
|
|
"description": "Query `active_only` defaults server-side to true unless value is literally `false`."
|
|
},
|
|
"response": []
|
|
},
|
|
{
|
|
"name": "List personas (include inactive)",
|
|
"request": {
|
|
"method": "GET",
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas?active_only=false&limit=50&offset=0",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas"
|
|
],
|
|
"query": [
|
|
{
|
|
"key": "active_only",
|
|
"value": "false"
|
|
},
|
|
{
|
|
"key": "limit",
|
|
"value": "50"
|
|
},
|
|
{
|
|
"key": "offset",
|
|
"value": "0"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"response": []
|
|
},
|
|
{
|
|
"name": "Get persona by ID",
|
|
"event": [
|
|
{
|
|
"listen": "test",
|
|
"script": {
|
|
"exec": [
|
|
"pm.test(\"Status code is 200\", function () {",
|
|
" pm.response.to.have.status(200);",
|
|
"});",
|
|
"const body = pm.response.json();",
|
|
"pm.test(\"Stable persona keys\", function () {",
|
|
" pm.expect(body.data.name).to.be.a(\"string\");",
|
|
" pm.expect(body.data).to.have.property(\"profile_picture\");",
|
|
" pm.expect(body.data).to.have.property(\"gender\");",
|
|
"});"
|
|
],
|
|
"type": "text/javascript"
|
|
}
|
|
}
|
|
],
|
|
"request": {
|
|
"method": "GET",
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas/{{persona_id}}",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas",
|
|
"{{persona_id}}"
|
|
]
|
|
}
|
|
},
|
|
"response": []
|
|
},
|
|
{
|
|
"name": "Update persona",
|
|
"event": [
|
|
{
|
|
"listen": "test",
|
|
"script": {
|
|
"exec": [
|
|
"pm.test(\"Status code is 200\", function () {",
|
|
" pm.response.to.have.status(200);",
|
|
"});",
|
|
"const body = pm.response.json();",
|
|
"pm.test(\"Updated persona\", function () {",
|
|
" pm.expect(body.data.profile_picture).to.include(\"alex-v2\");",
|
|
" pm.expect(body.data.gender).to.eql(\"neutral\");",
|
|
" pm.expect(body.data.name).to.include(\"updated\");",
|
|
"});"
|
|
],
|
|
"type": "text/javascript"
|
|
}
|
|
}
|
|
],
|
|
"request": {
|
|
"method": "PUT",
|
|
"header": [
|
|
{
|
|
"key": "Content-Type",
|
|
"value": "application/json",
|
|
"type": "text"
|
|
}
|
|
],
|
|
"body": {
|
|
"mode": "raw",
|
|
"raw": "{\n \"name\": \"Postman Coach (updated)\",\n \"profile_picture\": \"https://cdn.example.com/personas/alex-v2.png\",\n \"gender\": \"neutral\"\n}"
|
|
},
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas/{{persona_id}}",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas",
|
|
"{{persona_id}}"
|
|
]
|
|
},
|
|
"description": "`UpdateLmsPersonaInput`: all fields optional. `\"gender\": \"\"` clears gender. Empty `name` is rejected."
|
|
},
|
|
"response": []
|
|
},
|
|
{
|
|
"name": "Delete persona",
|
|
"request": {
|
|
"method": "DELETE",
|
|
"url": {
|
|
"raw": "{{base_url}}/api/v1/personas/{{persona_id}}",
|
|
"host": [
|
|
"{{base_url}}"
|
|
],
|
|
"path": [
|
|
"api",
|
|
"v1",
|
|
"personas",
|
|
"{{persona_id}}"
|
|
]
|
|
},
|
|
"description": "Deletes catalog row; practices with this `persona_id` get it cleared (SET NULL)."
|
|
},
|
|
"response": []
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|