{
  "name": "Meeting Notes UI",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "GET",
        "path": "meeting-notes-ui",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-ui",
      "name": "Webhook UI",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT id, title, type, source, meeting_date, created_at, LEFT(content, 200) as preview FROM meeting_notes ORDER BY created_at DESC LIMIT 50",
        "options": {}
      },
      "id": "postgres-ui",
      "name": "PostgreSQL - Get Data",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        500,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const notes = $input.all().map(i => i.json);\n\nlet noteCards = '';\nfor (const n of notes) {\n  const title = n.title || '\uc81c\ubaa9 \uc5c6\uc74c';\n  const type = n.type || 'original';\n  const source = n.source || 'manual';\n  const date = n.meeting_date || '';\n  const created = new Date(n.created_at).toLocaleDateString('ko-KR');\n  const preview = (n.preview || '').substring(0, 150);\n  noteCards += '<div class=\"note-card\" onclick=\"showDetail(' + n.id + ')\">';\n  noteCards += '<div class=\"note-header\"><span class=\"note-title\">' + title + '</span>';\n  noteCards += '<div class=\"note-meta\"><span class=\"badge badge-type\">' + type + '</span>';\n  noteCards += '<span class=\"badge badge-source\">' + source + '</span></div></div>';\n  noteCards += '<div class=\"note-date\">' + date + ' | ' + created + '</div>';\n  noteCards += '<div class=\"note-preview\">' + preview + '...</div></div>';\n}\n\nconst html = '<!DOCTYPE html><html lang=\"ko\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>\ud68c\uc758\ub85d \uc2dc\uc2a4\ud15c</title><style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#f5f5f5;padding:20px}.container{max-width:1200px;margin:0 auto}h1{color:#333;margin-bottom:20px}.search-box{margin-bottom:20px;display:flex;gap:10px}.search-box input{flex:1;padding:12px;border:1px solid #ddd;border-radius:8px;font-size:16px}.search-box button{padding:12px 24px;background:#007bff;color:white;border:none;border-radius:8px;cursor:pointer}.notes-list{display:grid;gap:15px}.note-card{background:white;padding:20px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,0.1);cursor:pointer}.note-card:hover{box-shadow:0 4px 12px rgba(0,0,0,0.15)}.note-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.note-title{font-size:18px;font-weight:600;color:#333}.note-meta{display:flex;gap:10px}.badge{padding:4px 8px;border-radius:4px;font-size:12px}.badge-type{background:#e3f2fd;color:#1976d2}.badge-source{background:#f3e5f5;color:#7b1fa2}.note-date{color:#666;font-size:14px}.note-preview{color:#555;line-height:1.6;margin-top:10px}.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);justify-content:center;align-items:center}.modal-content{background:white;padding:30px;border-radius:12px;max-width:800px;max-height:80vh;overflow-y:auto;width:90%}.modal-header{display:flex;justify-content:space-between;margin-bottom:20px}.modal-close{cursor:pointer;font-size:24px}#search-results{margin-top:20px}.score{color:#28a745}</style></head><body><div class=\"container\"><h1>\ud68c\uc758\ub85d \uc2dc\uc2a4\ud15c</h1><div class=\"search-box\"><input type=\"text\" id=\"searchInput\" placeholder=\"\uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694\"><button onclick=\"searchNotes()\">\uac80\uc0c9</button></div><div id=\"search-results\"></div><div class=\"notes-list\">' + noteCards + '</div></div><div class=\"modal\" id=\"modal\"><div class=\"modal-content\"><div class=\"modal-header\"><h2 id=\"modal-title\"></h2><span class=\"modal-close\" onclick=\"closeModal()\">&times;</span></div><div id=\"modal-body\"></div></div></div><script>async function showDetail(id){const res=await fetch(\"/webhook/meeting-notes-detail?id=\"+id);const data=await res.json();if(data.success&&data.data){document.getElementById(\"modal-title\").textContent=data.data.title;document.getElementById(\"modal-body\").innerHTML=\"<pre style=white-space:pre-wrap>\"+data.data.content+\"</pre>\";document.getElementById(\"modal\").style.display=\"flex\"}}function closeModal(){document.getElementById(\"modal\").style.display=\"none\"}async function searchNotes(){const query=document.getElementById(\"searchInput\").value;if(!query)return;const res=await fetch(\"/webhook/meeting-notes-search\",{method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:JSON.stringify({query})});const data=await res.json();const resultsDiv=document.getElementById(\"search-results\");if(data.success&&data.results.length>0){let html=\"<h3>\uac80\uc0c9 \uacb0\uacfc</h3>\";data.results.forEach(r=>{html+=\"<div class=note-card onclick=showDetail(\"+r.payload.postgres_id+\")><div class=note-header><span class=note-title>\"+(r.payload.title||\"\uc81c\ubaa9\uc5c6\uc74c\")+\"</span><span class=score>\uc720\uc0ac\ub3c4: \"+(r.score*100).toFixed(1)+\"%</span></div></div>\"});resultsDiv.innerHTML=html}else{resultsDiv.innerHTML=\"<p>\uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.</p>\"}}document.getElementById(\"searchInput\").addEventListener(\"keypress\",e=>{if(e.key===\"Enter\")searchNotes()})</script></body></html>';\n\nreturn [{ json: { html } }];"
      },
      "id": "code-html",
      "name": "Generate HTML",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        750,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "response-ui",
      "name": "Response UI",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1000,
        300
      ]
    }
  ],
  "connections": {
    "Webhook UI": {
      "main": [
        [
          {
            "node": "PostgreSQL - Get Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PostgreSQL - Get Data": {
      "main": [
        [
          {
            "node": "Generate HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate HTML": {
      "main": [
        [
          {
            "node": "Response UI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}