{"id":5408,"date":"2025-12-21T16:45:59","date_gmt":"2025-12-21T07:45:59","guid":{"rendered":"https:\/\/secondlife.lol\/?p=5408"},"modified":"2025-12-21T16:46:03","modified_gmt":"2025-12-21T07:46:03","slug":"qhse-report-django-opencode","status":"publish","type":"post","link":"https:\/\/secondlife.lol\/ja\/qhse-report-django-opencode\/","title":{"rendered":"QHSE report \uc790\ub3d9 \uc0dd\uc131: Django\uc640 OpenCode\ub85c \uc2dc\uc791\ud558\uae30"},"content":{"rendered":"<style>.kb-image5408_80031c-e8 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<div class=\"wp-block-kadence-image kb-image5408_80031c-e8\"><figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"512\" height=\"318\" src=\"https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-40.png\" alt=\"QHSE report \uc790\ub3d9 \uc0dd\uc131 \ud504\ub85c\uc138\uc2a4 \uc774\ubbf8\uc9c0\" class=\"kb-img wp-image-5704\" srcset=\"https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-40.png 512w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-40-300x186.png 300w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-40-18x12.png 18w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/figure><\/div>\n\n\n\n<p><a href=\"https:\/\/secondlife.lol\/ja\/opencode-django-nextjs-code-examples\/\">\uc55e \ud3b8<\/a>\u304b\u3089 <strong>Vendor + QhseRecord \ubaa8\ub378<\/strong>\uacfc \uac04\ub2e8\ud55c \ub300\uc2dc\ubcf4\ub4dc\uae4c\uc9c0 \ub9cc\ub4e4\uc5c8\uc73c\ub2c8,<br>\uc774\uc81c \ub0a8\uc740 \uac74 \u201cQHSE report \uc0dd\uc131\ud558\uae30\u201d\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\ud604\uc7a5\uc5d0\uc11c \uc9c4\uc9dc\ub85c \uc694\uad6c\ub418\ub294 \uac74 \ud654\uba74\ubcf4\ub2e4 <strong>\u30d5\u30a1\u30a4\u30eb<\/strong>\uc774\uc8e0.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\uac10\uc0ac\u00b7\uc2ec\uc0ac \ub54c \ub0b4\uc57c \ud558\ub294 \uc6d4\uac04\/\ubd84\uae30\ubcc4 \ub9ac\ud3ec\ud2b8<\/li>\n\n\n\n<li>\uc6d0\uc804 \uc0ac\uc5c5\uc790\uc5d0\uac8c \uc81c\ucd9c\ud558\ub294 <strong>PDF \ubb36\uc74c<\/strong><\/li>\n\n\n\n<li>\ub0b4\ubd80 \ud68c\uc758\uc6a9 \uc694\uc57d \ubcf4\uace0\uc11c<\/li>\n<\/ul>\n\n\n\n<p>\uc774\ubc88 \uae00\uc5d0\uc11c\ub294 \ub2e4\uc74c \ud750\ub984\uc744 \ud55c \ubc88\uc5d0 \uc7a1\uc544\ubd05\ub2c8\ub2e4.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.djangoproject.com\/\" target=\"_blank\" rel=\"noopener\">\u30b8\u30e3\u30f3\u30b4<\/a>\u304b\u3089 <strong>PDF \ub9ac\ud3ec\ud2b8 \ubf08\ub300 \ubf51\uae30<\/strong><\/li>\n\n\n\n<li>\uac04\ub2e8\ud55c <strong>\ud14c\uc2a4\ud2b8 \ucf54\ub4dc<\/strong>\ub85c \ub9ac\ud3ec\ud2b8 \uc0dd\uc131 \uc5ec\ubd80 \uac80\uc99d<\/li>\n\n\n\n<li>\ud130\ubbf8\ub110\uc5d0\uc11c <strong>OpenCode<\/strong>\u3092\u5229\u7528\u3057\u3066\n<ul class=\"wp-block-list\">\n<li>\uc694\uc57d \ubb38\uad6c \uc790\ub3d9 \uc0dd\uc131<\/li>\n\n\n\n<li>\ud15c\ud50c\ub9bf \ub9ac\ud329\ud130\ub9c1<\/li>\n\n\n\n<li>\ud14c\uc2a4\ud2b8 \ubcf4\uc644<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>\uae4c\uc9c0 \uc815\ub9ac\ud574 \ubcfc\uac8c\uc694.<\/p>\n\n\n<style>.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-content-wrap{padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);border-top:3px solid var(--global-palette2, #2B6CB0);border-right:3px solid var(--global-palette2, #2B6CB0);border-bottom:3px solid var(--global-palette2, #2B6CB0);border-left:3px solid var(--global-palette2, #2B6CB0);border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-right-radius:5px;border-bottom-left-radius:5px;box-shadow:0px 0px 14px 0px rgba(0, 0, 0, 0.2);}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-contents-title-wrap{padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-contents-title-wrap{color:var(--global-palette2, #2B6CB0);}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-contents-title{color:var(--global-palette2, #2B6CB0);font-size:28px;font-weight:regular;font-style:normal;}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-content-wrap .kb-table-of-content-list{color:var(--global-palette1, #3182CE);line-height:2em;font-weight:regular;font-style:normal;margin-top:var(--global-kb-spacing-sm, 1.5rem);margin-right:0px;margin-bottom:0px;margin-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-content-wrap .kb-table-of-content-list .kb-table-of-contents__entry:hover{color:var(--global-palette6, #718096);}@media all and (max-width: 1024px){.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-content-wrap{border-top:3px solid var(--global-palette2, #2B6CB0);border-right:3px solid var(--global-palette2, #2B6CB0);border-bottom:3px solid var(--global-palette2, #2B6CB0);border-left:3px solid var(--global-palette2, #2B6CB0);}}@media all and (max-width: 1024px){.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-contents-title{font-size:28px;}}@media all and (max-width: 767px){.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-content-wrap{border-top:3px solid var(--global-palette2, #2B6CB0);border-right:3px solid var(--global-palette2, #2B6CB0);border-bottom:3px solid var(--global-palette2, #2B6CB0);border-left:3px solid var(--global-palette2, #2B6CB0);}.kb-table-of-content-nav.kb-table-of-content-id83_5f28a6-34 .kb-table-of-contents-title{font-size:28px;}}<\/style>\n\n\n<h2 class=\"wp-block-heading\">1. QHSE report \uad6c\uc870\ub97c \uba3c\uc800 \uc815\ub9ac\ud558\uae30<\/h2>\n\n\n\n<p>\uc77c\ub2e8 \ub9ac\ud3ec\ud2b8\ub97c \ucf54\ub4dc\ub85c \ucc0d\uc5b4\ub0b4\ub824\uba74, \u201c\ud2c0\u201d\uc774 \ud544\uc694\ud569\ub2c8\ub2e4.<br>\uc608\uc81c\ub85c \uc6d4\uac04 \ub9ac\ud3ec\ud2b8\ub97c \uc774\ub807\uac8c \uc7a1\uc544\ubcfc \uc218 \uc788\uc5b4\uc694.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud45c\uc9c0<\/li>\n\n\n\n<li>1\uc7a5: \uac1c\uc694 (\uae30\uac04, \ub300\uc0c1 Vendor \uc218, \uae30\ub85d \uc218, \ubbf8\uc885\uacb0 \uc218)<\/li>\n\n\n\n<li>2\uc7a5: Q\/H\/E \uc720\ud615\ubcc4 \ud1b5\uacc4 (\ub9c9\ub300\uadf8\ub798\ud504 \uc774\ubbf8\uc9c0 or \uc22b\uc790 \ud14c\uc774\ube14)<\/li>\n\n\n\n<li>3\uc7a5: \uc8fc\uc694 \uc774\uc288 Top N + \uc870\uce58 \ud604\ud669<\/li>\n\n\n\n<li>\ubd80\ub85d: \uc0c1\uc138 \ub9ac\uc2a4\ud2b8(\ud544\uc694 \uc2dc)<\/li>\n<\/ul>\n\n\n\n<p>\uc2e4\uc81c \ud504\ub85c\uc81d\ud2b8\ub85c \uac00\uba74 \uc774 \uad6c\uc870\ub97c <strong>\uace0\uac1d\uc0ac \ud3ec\ub9f7\uc5d0 \ub9de\uac8c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5<\/strong>\ud558\uba74 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Django\uc5d0\uc11c PDF \uc0dd\uc131 \ubf08\ub300 \ub9cc\ub4e4\uae30<\/h2>\n\n\n\n<p>\uc5ec\uae30\uc11c\ub294 \uc124\uba85\uc744 \uc704\ud574 <strong>WeasyPrint<\/strong> \uac19\uc740 HTML\u2192PDF \ubc29\uc2dd\uc774\ub77c\uace0 \uac00\uc815\ud558\uaca0\uc2b5\ub2c8\ub2e4<br>(\uc2e4\uc81c \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 ReportLab, xhtml2pdf \ub4f1 \uc5b4\ub5a4 \uac78 \uc368\ub3c4 \ub429\ub2c8\ub2e4).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 \uc758\uc874\uc131 \uc124\uce58 (\uc608\uc2dc)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install weasyprint<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2.2 \ub9ac\ud3ec\ud2b8\uc6a9 \ubdf0 \uc791\uc131 (<code>reports\/views.py<\/code>)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import datetime\nfrom django.http import HttpResponse\nfrom django.template.loader import render_to_string\nfrom weasyprint import HTML\n\nfrom vendors.models import Vendor, QhseRecord\n\n\ndef monthly_qhse_report(request, year: int, month: int):\n    # 1. \uae30\uac04 \uc124\uc815\n    start_date = datetime.date(year, month, 1)\n    if month == 12:\n        end_date = datetime.date(year + 1, 1, 1)\n    else:\n        end_date = datetime.date(year, month + 1, 1)\n\n    # 2. \ub370\uc774\ud130 \uc870\ud68c\n    records = QhseRecord.objects.select_related(\"vendor\").filter(\n        occurred_at__gte=start_date,\n        occurred_at__lt=end_date,\n    )\n\n    vendors = Vendor.objects.all().distinct()\n\n    total_records = records.count()\n    open_records = records.filter(is_closed=False).count()\n\n    # \uc720\ud615\ubcc4 \uc9d1\uacc4\n    by_type = {\n        key: records.filter(record_type=key).count()\n        for key, _label in QhseRecord.QHSE_TYPE_CHOICES\n    }\n\n    context = {\n        \"year\": year,\n        \"month\": month,\n        \"vendors\": vendors,\n        \"total_records\": total_records,\n        \"open_records\": open_records,\n        \"by_type\": by_type,\n        \"records\": records,\n    }\n\n    # 3. HTML \ub80c\ub354\ub9c1\n    html_string = render_to_string(\"reports\/monthly_qhse_report.html\", context)\n\n    # 4. PDF \uc0dd\uc131\n    html = HTML(string=html_string)\n    pdf_file = html.write_pdf()\n\n    # 5. \uc751\ub2f5 \ubc18\ud658\n    filename = f\"qhse_report_{year}_{month:02d}.pdf\"\n    response = HttpResponse(pdf_file, content_type=\"application\/pdf\")\n    response&#91;\"Content-Disposition\"] = f'attachment; filename=\"{filename}\"'\n    return response<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 URL \uc5f0\uacb0 (<code>core\/urls.py<\/code> \uc77c\ubd80)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>from reports.views import monthly_qhse_report\n\nurlpatterns += &#91;\n    path(\n        \"reports\/monthly\/&lt;int:year>\/&lt;int:month>\/\",\n        monthly_qhse_report,\n        name=\"monthly_qhse_report\",\n    ),\n]<\/code><\/pre>\n\n\n\n<p>\u3053\u3046\u3059\u308c\u3070 <code>\/reports\/monthly\/2025\/11\/<\/code> \uac19\uc740 URL\ub85c \uc811\uadfc\ud588\uc744 \ub54c<br>\uc6d4\uac04 \ub9ac\ud3ec\ud2b8 PDF\ub97c \ubc14\ub85c \ub0b4\ub824\ubc1b\uc744 \uc218 \uc788\ub294 \uad6c\uc870\uac00 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. \ub9ac\ud3ec\ud2b8 HTML \ud15c\ud50c\ub9bf \uc608\uc2dc<\/h2>\n\n\n\n<p><code>templates\/reports\/monthly_qhse_report.html<\/code>\uc758 \uc544\uc8fc \ub2e8\uc21c\ud55c \uc608\uc2dc\ub294 \uc774\ub807\uac8c \uc7a1\uc744 \uc218 \uc788\uc5b4\uc694:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!doctype html&gt;\n&lt;html lang=&quot;ko&quot;&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;utf-8&quot; \/&gt;\n    &lt;title&gt;Monthly QHSE Report&lt;\/title&gt;\n    &lt;style&gt;\n      body { font-family: sans-serif; font-size: 12px; }\n      h1, h2 { margin-bottom: 4px; }\n      table { width: 100%; border-collapse: collapse; margin-top: 12px; }\n      th, td { border: 1px solid #ccc; padding: 4px 6px; }\n      th { background: #f3f3f3; }\n    &lt;\/style&gt;\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;{{ year }}\ub144 {{ month }}\uc6d4 QHSE \ub9ac\ud3ec\ud2b8&lt;\/h1&gt;\n    &lt;p&gt;\ucd1d \ud611\ub825\uc5c5\uccb4 \uc218: {{ vendors|length }}&lt;\/p&gt;\n    &lt;p&gt;\uc804\uccb4 \uae30\ub85d \uc218: {{ total_records }} \/ \ubbf8\uc885\uacb0: {{ open_records }}&lt;\/p&gt;\n\n    &lt;h2&gt;\uc720\ud615\ubcc4 \ud1b5\uacc4&lt;\/h2&gt;\n    &lt;ul&gt;\n      &lt;li&gt;\ud488\uc9c8(Q): {{ by_type.Q }}&lt;\/li&gt;\n      &lt;li&gt;\uc548\uc804\/\ubcf4\uac74(H): {{ by_type.H }}&lt;\/li&gt;\n      &lt;li&gt;\ud658\uacbd(E): {{ by_type.E }}&lt;\/li&gt;\n    &lt;\/ul&gt;\n\n    &lt;h2&gt;\uc0c1\uc138 \uae30\ub85d (\uc0c1\uc704 \uc77c\ubd80)&lt;\/h2&gt;\n    &lt;table&gt;\n      &lt;thead&gt;\n        &lt;tr&gt;\n          &lt;th&gt;\ubc1c\uc0dd\uc77c&lt;\/th&gt;\n          &lt;th&gt;\ud611\ub825\uc5c5\uccb4&lt;\/th&gt;\n          &lt;th&gt;\u30bf\u30a4\u30d7&lt;\/th&gt;\n          &lt;th&gt;\u30bf\u30a4\u30c8\u30eb&lt;\/th&gt;\n          &lt;th&gt;\uc885\uacb0 \uc5ec\ubd80&lt;\/th&gt;\n        &lt;\/tr&gt;\n      &lt;\/thead&gt;\n      &lt;tbody&gt;\n        {% for r in records|slice:&quot;:20&quot; %}\n          &lt;tr&gt;\n            &lt;td&gt;{{ r.occurred_at }}&lt;\/td&gt;\n            &lt;td&gt;{{ r.vendor.name }}&lt;\/td&gt;\n            &lt;td&gt;{{ r.get_record_type_display }}&lt;\/td&gt;\n            &lt;td&gt;{{ r.title }}&lt;\/td&gt;\n            &lt;td&gt;{% if r.is_closed %}\uc644\ub8cc{% else %}\uc9c4\ud589\uc911{% endif %}&lt;\/td&gt;\n          &lt;\/tr&gt;\n        {% endfor %}\n      &lt;\/tbody&gt;\n    &lt;\/table&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<p>\uc774\uc81c \uc774 \ud15c\ud50c\ub9bf \uc790\uccb4\ub97c <strong>AI\uc5d0\uac8c \ub9e1\uaca8\uc11c \uac1c\uc120<\/strong>\uc2dc\ud0a4\uba74 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub85c \u201cPDF\uac00 \uc798 \ub5a8\uc5b4\uc9c0\ub294\uc9c0\u201d \ud655\uc778\ud558\uae30<\/h2>\n\n\n\n<p>\ub9ac\ud3ec\ud2b8 \uc790\ub3d9\ud654\uc5d0\uc11c \uc911\uc694\ud55c \uac74 \u201c\ucf54\ub4dc \uc218\uc815 \ud6c4\uc5d0\ub3c4 PDF\uac00 \uacc4\uc18d \uc798 \uc0dd\uc131\ub418\ub290\ub0d0\u201d\uc785\ub2c8\ub2e4.<br>\uac04\ub2e8\ud55c Django TestCase \uc608\uc2dc\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># reports\/tests\/test_monthly_report.py\nimport datetime\nfrom django.test import TestCase\nfrom django.urls import reverse\nfrom vendors.models import Vendor, QhseRecord\n\n\nclass MonthlyQhseReportTests(TestCase):\n    def setUp(self):\n        self.vendor = Vendor.objects.create(\n            name=\"\ud14c\uc2a4\ud2b8 \ud611\ub825\uc0ac\",\n            business_id=\"123-45-67890\",\n        )\n        QhseRecord.objects.create(\n            vendor=self.vendor,\n            record_type=\"Q\",\n            title=\"\uc6a9\uc811 \ube44\ub4dc \ubd88\ub7c9\",\n            description=\"\uc2dc\uc6b4\uc804 \uc911 \ube44\ub4dc \ubd88\ub7c9 \ubc1c\uacac\",\n            occurred_at=datetime.date(2025, 11, 15),\n            is_closed=False,\n        )\n\n    def test_report_pdf_is_generated(self):\n        url = reverse(\"monthly_qhse_report\", kwargs={\"year\": 2025, \"month\": 11})\n        response = self.client.get(url)\n        self.assertEqual(response.status_code, 200)\n        self.assertEqual(response&#91;\"Content-Type\"], \"application\/pdf\")\n        self.assertGreater(len(response.content), 1000)\n<\/code><\/pre>\n\n\n\n<p>\uc774 \ud14c\uc2a4\ud2b8 \ud558\ub098\ub9cc \uc788\uc5b4\ub3c4<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>URL\uc774 \uc815\uc0c1 \ub3d9\uc791\ud558\ub294\uc9c0<\/li>\n\n\n\n<li>PDF\ub85c \uc751\ub2f5\ud558\ub294\uc9c0<\/li>\n\n\n\n<li>\ub0b4\uc6a9\uc774 \u201c\ube48 \ud30c\uc77c \uc218\uc900\u201d\uc740 \uc544\ub2cc\uc9c0<br>\ub97c \ucd5c\uc18c\ud55c \uac80\uc99d\ud574 \uc90d\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. OpenCode\uc5d0\uac8c \u201c\uc694\uc57d \uae00 + \uac1c\uc120\uc548\u201d \ub9e1\uae30\uae30<\/h2>\n\n\n\n<p>\uc774\uc81c \uc9c4\uc9dc \uc7ac\ubbf8\uc788\ub294 \ubd80\ubd84\uc785\ub2c8\ub2e4.<br>\ud130\ubbf8\ub110\uc5d0\uc11c \ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8\uc5d0\uc11c <strong>OpenCode<\/strong>\ub97c \ucf1c\uace0, \uc774\ub807\uac8c \ub9d0\ud574\ubcfc \uc218 \uc788\uc5b4\uc694.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.1 \ub9ac\ud3ec\ud2b8 \uc694\uc57d \ud14d\uc2a4\ud2b8 \uc790\ub3d9 \uc0dd\uc131<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/ask reports\/views.py\uc640 monthly_qhse_report.html\uc744 \uae30\ubc18\uc73c\ub85c,\n\ub9ac\ud3ec\ud2b8 \ub9e8 \uc55e\uc5d0 \ub4e4\uc5b4\uac08 \ud55c\uae00 \uc694\uc57d \ubb38\ub2e8\uc744 5\uc904 \uc774\ub0b4\ub85c \uc791\uc131\ud574\uc918.\n\ud611\ub825\uc0ac \uad00\ub9ac\uc790 \uad00\uc810\uc5d0\uc11c \uc77d\uae30 \uc27d\uac8c \uc368\uc918.<\/code><\/pre>\n\n\n\n<p>\u2192 \uc774\uac78 \ubcf5\uc0ac\ud574\uc11c \ud15c\ud50c\ub9bf \uc0c1\ub2e8\uc5d0 \ub123\uc73c\uba74,<br>\ub9ac\ud3ec\ud2b8\uac00 \u201c\uc22b\uc790 \ub098\uc5f4\u201d\uc774 \uc544\ub2c8\ub77c \u201c\uc0ac\ub78c\uc774 \uc77d\uc744 \uc218 \uc788\ub294 \ubcf4\uace0\uc11c\u201d\uac00 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.2 \ud14c\uc2a4\ud2b8 \ucf54\ub4dc \ubcf4\uc644 \uc694\uccad<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/ask test_monthly_report.py\ub97c \uac80\ud1a0\ud574\uc11c\n- \uc5e3\uc9c0 \ucf00\uc774\uc2a4\n- \ub370\uc774\ud130\uac00 \uc5c6\uc744 \ub54c\uc758 \ub3d9\uc791\n- \uc798\ubabb\ub41c \uc6d4\/\uc5f0\ub3c4 \uc694\uccad\n\uc744 \uac80\uc99d\ud558\ub294 \ud14c\uc2a4\ud2b8 \ud568\uc218\ub97c 2~3\uac1c \ub354 \ucd94\uac00\ud574\uc918.<\/code><\/pre>\n\n\n\n<p>AI\uac00 \ud14c\uc2a4\ud2b8 \ubcf4\uc644\uc548\uc744 \uc81c\uc548\ud574\uc8fc\uba74,<br>\ud14c\uc2a4\ud2b8 \uc2e0\ub8b0\uc131\uc774 \ube60\ub974\uac8c \uc62c\ub77c\uac11\ub2c8\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.3 \ub9ac\ud329\ud130\ub9c1 + \uc2a4\ud0c0\uc77c \uac1c\uc120<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/ask monthly_qhse_report \ubdf0\uc758 \ubcf5\uc7a1\ub3c4\ub97c \uc904\uc774\uae30 \uc704\ud574\n\ucffc\ub9ac \ub85c\uc9c1\uacfc \ud1b5\uacc4 \uacc4\uc0b0\uc744 \ubcc4\ub3c4 service \ud568\uc218\ub85c \ubd84\ub9ac\ud558\ub294 \ub9ac\ud329\ud130\ub9c1 \ucf54\ub4dc\ub97c \uc81c\uc548\ud574\uc918.<\/code><\/pre>\n\n\n\n<p>\uc774\ub7f0 \uc2dd\uc73c\ub85c<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ubdf0\ub294 \u201c\uc785\ucd9c\ub825 \uc911\uc2ec\u201d<\/li>\n\n\n\n<li>\uc11c\ube44\uc2a4 \ud568\uc218\ub294 \u201c\ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\u201d<br>\uc73c\ub85c \ubd84\ub9ac\ud558\ub294 \ud328\ud134\uc744 <strong>AI\uc640 \ud568\uaed8 \uc5f0\uc2b5<\/strong>\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">6. QHSE dashboard \uc640 \uc5f0\uacb0\ud574\uc11c \u201c\ud074\ub9ad \ud55c \ubc88\uc73c\ub85c \ub9ac\ud3ec\ud2b8 \ubc1b\uae30\u201d<\/h2>\n\n\n<style>.kb-image5408_15a7b0-83 .kb-image-has-overlay:after{opacity:0.3;border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-right-radius:5px;border-bottom-left-radius:5px;}.kb-image5408_15a7b0-83 img.kb-img, .kb-image5408_15a7b0-83 .kb-img img{border-top-left-radius:5px;border-top-right-radius:5px;border-bottom-right-radius:5px;border-bottom-left-radius:5px;box-shadow:0px 0px 14px 0px rgba(0, 0, 0, 0.2);}<\/style>\n<div class=\"wp-block-kadence-image kb-image5408_15a7b0-83\"><figure class=\"aligncenter size-medium_large\"><img decoding=\"async\" width=\"768\" height=\"436\" src=\"https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1-768x436.jpg\" alt=\"QHSE report \uc0dd\uc131 \uc774\ubbf8\uc9c0\" class=\"kb-img wp-image-5705\" srcset=\"https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1-768x436.jpg 768w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1-300x171.jpg 300w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1-600x341.jpg 600w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1-18x10.jpg 18w, https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-41-1.jpg 1200w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure><\/div>\n\n\n\n<p>\uc55e \uae00\uc5d0\uc11c \ub9cc\ub4e0 \ub300\uc2dc\ubcf4\ub4dc\uc5d0, \ub2e4\uc74c \uc815\ub3c4 \uae30\ub2a5\ub9cc \ubd99\uc5ec\ub3c4 \ud604\uc7a5 \ub290\ub08c\uc774 \ud655 \uc0b4\uc544\ub0a9\ub2c8\ub2e4.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ub300\uc2dc\ubcf4\ub4dc \uc0c1\ub2e8\uc5d0 \u201c\uc774\ubc88 \ub2ec \ub9ac\ud3ec\ud2b8 \ub2e4\uc6b4\ub85c\ub4dc\u201d \ubc84\ud2bc<\/li>\n\n\n\n<li><code>\/reports\/monthly\/2025\/11\/<\/code> \uac19\uc740 URL\ub85c \ubc14\ub85c \uc5f0\uacb0<\/li>\n<\/ul>\n\n\n\n<p>Next.js \ucabd\uc5d0\uc11c\ub294<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \uc608: app\/qhse\/page.tsx \ub0b4 \uc77c\ubd80\nimport Link from \"next\/link\";\n\n&lt;button className=\"rounded-lg border px-4 py-2 text-sm\">\n  &lt;Link href=\"\/api\/proxy\/reports\/monthly\/2025\/11\">\n    \uc774\ubc88 \ub2ec \ub9ac\ud3ec\ud2b8 PDF \ub2e4\uc6b4\ub85c\ub4dc\n  &lt;\/Link>\n&lt;\/button><\/code><\/pre>\n\n\n\n<p>\uc774 \ubc84\ud2bc\uc744 \ud074\ub9ad\ud558\uba74<br>\uad00\ub9ac\uc790 \uc785\uc7a5\uc5d0\uc11c\ub294 \u201c\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c \ubc14\ub85c \uacf5\uc2dd \ub9ac\ud3ec\ud2b8\ub85c \uc5f0\uacb0\ub418\ub294 \uacbd\ud5d8\u201d\uc744 \uc904 \uc218 \uc788\uc8e0.<\/p>\n\n\n\n<p>\ub098\uc911\uc5d0\ub294 \uae30\uac04 \uc120\ud0dd(DatePicker) + \ud30c\ub77c\ubbf8\ud130 \uae30\ubc18\uc73c\ub85c \ud655\uc7a5\ud558\uba74 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u3088\u304f\u3042\u308b\u8cea\u554f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Q1. QHSE report PDF \uc0dd\uc131\uc740 \ubc18\ub4dc\uc2dc WeasyPrint\ub97c \uc368\uc57c \ud558\ub098\uc694?<\/h3>\n\n\n\n<p>\uc544\ub2c8\uc694. <a href=\"https:\/\/www.reportlab.com\/\" target=\"_blank\" rel=\"noopener\">\u30ec\u30dd\u30fc\u30c8\u30e9\u30dc<\/a>, <a href=\"https:\/\/github.com\/xhtml2pdf\/xhtml2pdf\" target=\"_blank\" rel=\"noopener\">xhtml2pdf<\/a>, <a href=\"https:\/\/wkhtmltopdf.org\/\" target=\"_blank\" rel=\"noopener\">wkhtmltopdf<\/a> \ub4f1 \uc5b4\ub5a4 PDF \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc368\ub3c4 \ub429\ub2c8\ub2e4.<br>\uc911\uc694\ud55c \uac74 \u201c\ud15c\ud50c\ub9bf + \ub370\uc774\ud130 + \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\u201d \uad6c\uc870\ub97c \uc720\uc9c0\ud558\ub294 \uac83\uc774\uc5d0\uc694.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Q2. SME \ud658\uacbd\uc5d0\uc11c\ub294 \ubcf4\uc548 \ub54c\ubb38\uc5d0 \ud074\ub77c\uc6b0\ub4dc AI\ub97c \ubabb \uc4f0\uba74 \uc5b4\ub5a1\ud558\uc8e0?<\/h3>\n\n\n\n<p>\uadf8 \uacbd\uc6b0 <strong>\ub85c\uceec LLM + \uc0ac\ub0b4\ub9dd \uc804\uc6a9 OpenCode \ud658\uacbd<\/strong>\uc744 \uace0\ub824\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>\ud504\ub86c\ud504\ud2b8 \uad6c\uc870\uc640 \uc544\ud0a4\ud14d\ucc98\ub294 \uadf8\ub300\ub85c \ub450\uace0, \ubaa8\ub378\ub9cc \ub0b4\ubd80\ub85c \uad50\uccb4\ud558\ub294 \uc2dd\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Q3. QHSE dashboard \uc640 PDF \ub9ac\ud3ec\ud2b8\uc758 \uc9c0\ud45c\uac00 \uc11c\ub85c \ub2e4\ub974\uba74 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub098\uc694?<\/h3>\n\n\n\n<p>\uadf8\ub798\uc11c \uac00\ub2a5\ud55c \ud55c <strong>\uac19\uc740 \ucffc\ub9ac\/\uc11c\ube44\uc2a4 \ud568\uc218<\/strong>\ub97c \uacf5\uc720\ud574\uc57c \ud569\ub2c8\ub2e4.<br>\uc608\ub97c \ub4e4\uc5b4 <code>services\/qhse_stats.py<\/code> \uac19\uc740 \ubaa8\ub4c8\uc744 \ub9cc\ub4e4\uace0,<br>\ub300\uc2dc\ubcf4\ub4dc\uc640 \ub9ac\ud3ec\ud2b8 \ubaa8\ub450 \uadf8 \ubaa8\ub4c8\ub9cc \ud638\ucd9c\ud558\ub3c4\ub85d \uc124\uacc4\ud558\ub294 \uac8c \uc88b\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Q4. \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uc5d0\uc11c \u201clen(response.content) &gt; 1000\u201d \uac19\uc740 \uac80\uc0ac\ub294 \ub108\ubb34 \ub7ec\ud504\ud55c\uac00\uc694?<\/h3>\n\n\n\n<p>\ub9de\uc544\uc694, \ucd5c\uc18c \ub808\ubca8 \uac80\uc99d\uc77c \ubfd0\uc785\ub2c8\ub2e4.<br>\ub098\uc911\uc5d0\ub294 PDF \ub0b4\ubd80 \ud14d\uc2a4\ud2b8 \uc77c\ubd80\ub97c \ucd94\ucd9c\ud574 \uac80\uc0ac\ud558\uac70\ub098,<br>\uc0dd\uc131 \uc77c\uc790\ub97c \ube44\uad50\ud558\ub294 \ub4f1 \ub354 \uc815\uad50\ud55c \ud14c\uc2a4\ud2b8\ub97c \ucd94\uac00\ud558\ub294 \uac8c \uc88b\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Q5. \ub9ac\ud3ec\ud2b8\uc5d0 \uadf8\ub798\ud504\ub098 \ucc28\ud2b8 \uc774\ubbf8\uc9c0\ub97c \ub123\uc73c\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud558\ub098\uc694?<\/h3>\n\n\n\n<p>\uc77c\ubc18\uc801\uc73c\ub85c\ub294<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Matplotlib \ub4f1\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uba3c\uc800 PNG\ub85c \uc0dd\uc131\ud558\uace0<\/li>\n\n\n\n<li>\ud15c\ud50c\ub9bf\uc5d0 <code>&lt;img src=&quot;...&quot;&gt;<\/code>\ub85c \uc0bd\uc785<\/li>\n\n\n\n<li>PDF \ub80c\ub354\ub9c1 \uc2dc \ud30c\uc77c\uc744 \ud568\uaed8 \uc77d\uc5b4\ub4e4\uc774\ub294 \ubc29\uc2dd\uc73c\ub85c \uad6c\ud604\ud569\ub2c8\ub2e4.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Q6. OpenCode\ub97c CI\/CD \ud30c\uc774\ud504\ub77c\uc778\uc5d0\ub3c4 \uc5f0\ub3d9\ud560 \uc218 \uc788\ub098\uc694?<\/h3>\n\n\n\n<p>\uac00\ub2a5\uc740 \ud558\uc9c0\ub9cc, \ucc98\uc74c\uc5d0\ub294 <strong>\uac1c\ubc1c\uc790 \ub85c\uceec \ud130\ubbf8\ub110<\/strong>\uc5d0\uc11c\ub9cc \uc0ac\uc6a9\ud558\ub294 \uac83\uc744 \ucd94\ucc9c\ud569\ub2c8\ub2e4.<br>CI\uc5d0 \ubd99\uc774\ub824\uba74 \ud504\ub86c\ud504\ud2b8\u00b7\ubcf4\uc548\u00b7\ube44\uc6a9 \uad00\ub9ac\uae4c\uc9c0 \uace0\ub824\ud574\uc57c \ud574\uc11c,<br>\uc77c\ub2e8\uc740 \u201c\ucf54\ub529 \uc5b4\uc2dc\uc2a4\ud134\ud2b8 + \uc124\uacc4\/\ubb38\uc11c\ud654 \ub3c4\uc6b0\ubbf8\u201d \uc5ed\ud560\uc5d0 \uc9d1\uc911\ud558\ub294 \uac8c \uc548\uc804\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u6574\u7406\u3059\u308b<\/h2>\n\n\n\n<p>\uc774\ubc88 \ud3b8\uc5d0\uc11c\ub294 <strong>\ud14c\uc2a4\ud2b8 + PDF \uc0dd\uc131<\/strong>\uc774\ub77c\ub294<br>\uc2e4\uc81c \ud604\uc7a5\uc5d0\uc11c \ubc14\ub85c \uc4f0\uc774\ub294 \uae30\ub2a5\uc744 \uc608\uc81c\ub85c,<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Django\uc5d0\uc11c \uc6d4\uac04 \ub9ac\ud3ec\ud2b8 PDF\ub97c \ucc0d\uc5b4\ub0b4\ub294 \ubdf0\uc640 \ud15c\ud50c\ub9bf<\/li>\n\n\n\n<li>\ucd5c\uc18c\ud55c\uc758 \uac80\uc99d\uc744 \uc704\ud55c \ud14c\uc2a4\ud2b8 \ucf54\ub4dc<\/li>\n\n\n\n<li>\ud130\ubbf8\ub110\uc5d0\uc11c\uc758 AI \ubcf4\uc870 \ud750\ub984(OpenCode \ud65c\uc6a9)<\/li>\n<\/ul>\n\n\n\n<p>\uae4c\uc9c0 \ud55c \ubc88\uc5d0 \uc815\ub9ac\ud574 \ubd24\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc624\ub298 \ubc14\ub85c \ud574\ubcfc \uc218 \uc788\ub294 \uc561\uc158 3\uac00\uc9c0\ub97c \uc815\ub9ac\ud558\uba74<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0 reports \uc571 \ud558\ub098 \ub9cc\ub4e4\uae30<\/strong>\n<ul class=\"wp-block-list\">\n<li>\uac00\uc7a5 \ub2e8\uc21c\ud55c HTML \ud15c\ud50c\ub9bf + PDF \ucd9c\ub825 \ubdf0\ubd80\ud130 \uc2dc\ub3c4<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\ud14c\uc2a4\ud2b8 \ucf54\ub4dc 1\uac1c\ub77c\ub3c4 \ucd94\uac00\ud574\ubcf4\uae30<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u201cPDF\uac00 200 OK\ub85c \ub9ac\ud134\ub418\uace0, \uc6a9\ub7c9\uc774 \uc77c\uc815 \uc774\uc0c1\uc778\uc9c0\u201d\ub9cc \uac80\uc0ac\ud574\ub3c4 \ud070 \ucc28\uc774<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\ud130\ubbf8\ub110\uc5d0\uc11c AI\uc5d0\uac8c \ub9ac\ud3ec\ud2b8 \uc694\uc57d \ubb38\uc7a5\uacfc \ub9ac\ud329\ud130\ub9c1 \uc81c\uc548 \ub9e1\uae30\uae30<\/strong>\n<ul class=\"wp-block-list\">\n<li>\uc9c1\uc811 \uc4f0\uba74 30\ubd84 \uac78\ub9b4 \uae00\uc744 3\ubd84 \uc548\uc5d0 \uc5bb\uc5b4\ubcf4\uace0, \ud544\uc694 \ubd80\ubd84\ub9cc \uc190\ubcf4\ub294 \uacbd\ud5d8 \ud574\ubcf4\uae30<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>\ub9c8\uc9c0\ub9c9\uc73c\ub85c, \uc2a4\uc2a4\ub85c\uc5d0\uac8c \ud55c \ubc88 \ubb3c\uc5b4\ubcf4\uba74 \uc88b\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201c\ub0b4\uac00 \uc9c0\uae08 \uad00\ub9ac \uc911\uc778 \ud488\uc9c8\u00b7\uc548\uc804\u00b7\ud658\uacbd \ub370\uc774\ud130\ub97c<br>\uc774\ub7f0 \uc2dd\uc758 \uc790\ub3d9 \ub9ac\ud3ec\ud2b8\ub85c \ubc14\uafd4\ub450\uba74,<br>\ub2e4\uc74c \uac10\uc0ac\u00b7\uc2ec\uc0ac \ub54c \uc5bc\ub9c8\ub098 \ub35c \ud798\ub4e4\uae4c?\u201d<\/p>\n<\/blockquote>\n\n\n\n<p>\ub2e4\uc74c \ud3b8\uc5d0\uc11c\ub294<br>\u201c\ub9ac\ud3ec\ud2b8 \uc790\ub3d9 \uc0dd\uc131\uc5d0 \uc2a4\ucf00\uc904\ub7ec(\uc608: Celery + cron)\uc640 \uba54\uc77c \ubc1c\uc1a1\uae4c\uc9c0 \ubd99\uc774\ub294 \ud750\ub984\u201d\uc744<br>\uc774\uc5b4\uc11c \uc815\ub9ac\ud574 \ubcfc\uac8c\uc694.<\/p>","protected":false},"excerpt":{"rendered":"<p>\uc55e \ud3b8\uc5d0\uc11c Vendor + QhseRecord \ubaa8\ub378\uacfc \uac04\ub2e8\ud55c \ub300\uc2dc\ubcf4\ub4dc\uae4c\uc9c0 \ub9cc\ub4e4\uc5c8\uc73c\ub2c8,\uc774\uc81c \ub0a8\uc740&#8230;<\/p>","protected":false},"author":3,"featured_media":5704,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[7],"tags":[812,1041,1166,1163,1167,1162,153,1168,1164,1165],"class_list":["post-5408","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-coding","tag-django","tag-opencode","tag-pdf-","tag-1163","tag-1167","tag-1162","tag-153","tag-1168","tag-1164","tag-1165"],"taxonomy_info":{"category":[{"value":7,"label":"\uc778\uacf5\uc9c0\ub2a5(AI)"}],"post_tag":[{"value":812,"label":"Django"},{"value":1041,"label":"OpenCode"},{"value":1166,"label":"PDF \ub9ac\ud3ec\ud2b8"},{"value":1163,"label":"\ub9ac\ud3ec\ud2b8\uc790\ub3d9\ud654"},{"value":1167,"label":"\uc6d0\uc804\ud488\uc9c8"},{"value":1162,"label":"\uc6d0\uc804\ud611\ub825\uc0ac"},{"value":153,"label":"\uc6f9\uac1c\ubc1c"},{"value":1168,"label":"\uc790\ub3d9\ubcf4\uace0\uc11c"},{"value":1164,"label":"\ud14c\uc2a4\ud2b8\ucf54\ub4dc"},{"value":1165,"label":"\ud488\uc9c8\ub370\uc774\ud130"}]},"featured_image_src_large":["https:\/\/secondlife.lol\/wp-content\/uploads\/2025\/12\/image-40.png",512,318,false],"author_info":{"display_name":"TERE","author_link":"https:\/\/secondlife.lol\/ja\/author\/tere\/"},"comment_info":0,"category_info":[{"term_id":7,"name":"\uc778\uacf5\uc9c0\ub2a5(AI)","slug":"ai-coding","term_group":0,"term_taxonomy_id":7,"taxonomy":"category","description":"","parent":20,"count":69,"filter":"raw","cat_ID":7,"category_count":69,"category_description":"","cat_name":"\uc778\uacf5\uc9c0\ub2a5(AI)","category_nicename":"ai-coding","category_parent":20}],"tag_info":[{"term_id":812,"name":"Django","slug":"django","term_group":0,"term_taxonomy_id":812,"taxonomy":"post_tag","description":"","parent":0,"count":10,"filter":"raw"},{"term_id":1041,"name":"OpenCode","slug":"opencode","term_group":0,"term_taxonomy_id":1041,"taxonomy":"post_tag","description":"","parent":0,"count":10,"filter":"raw"},{"term_id":1166,"name":"PDF \ub9ac\ud3ec\ud2b8","slug":"pdf-%eb%a6%ac%ed%8f%ac%ed%8a%b8","term_group":0,"term_taxonomy_id":1166,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":1163,"name":"\ub9ac\ud3ec\ud2b8\uc790\ub3d9\ud654","slug":"%eb%a6%ac%ed%8f%ac%ed%8a%b8%ec%9e%90%eb%8f%99%ed%99%94","term_group":0,"term_taxonomy_id":1163,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":1167,"name":"\uc6d0\uc804\ud488\uc9c8","slug":"%ec%9b%90%ec%a0%84%ed%92%88%ec%a7%88","term_group":0,"term_taxonomy_id":1167,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":1162,"name":"\uc6d0\uc804\ud611\ub825\uc0ac","slug":"%ec%9b%90%ec%a0%84%ed%98%91%eb%a0%a5%ec%82%ac","term_group":0,"term_taxonomy_id":1162,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":153,"name":"\uc6f9\uac1c\ubc1c","slug":"%ec%9b%b9%ea%b0%9c%eb%b0%9c","term_group":0,"term_taxonomy_id":153,"taxonomy":"post_tag","description":"","parent":0,"count":5,"filter":"raw"},{"term_id":1168,"name":"\uc790\ub3d9\ubcf4\uace0\uc11c","slug":"%ec%9e%90%eb%8f%99%eb%b3%b4%ea%b3%a0%ec%84%9c","term_group":0,"term_taxonomy_id":1168,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":1164,"name":"\ud14c\uc2a4\ud2b8\ucf54\ub4dc","slug":"%ed%85%8c%ec%8a%a4%ed%8a%b8%ec%bd%94%eb%93%9c","term_group":0,"term_taxonomy_id":1164,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":1165,"name":"\ud488\uc9c8\ub370\uc774\ud130","slug":"%ed%92%88%ec%a7%88%eb%8d%b0%ec%9d%b4%ed%84%b0","term_group":0,"term_taxonomy_id":1165,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"}],"_links":{"self":[{"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/posts\/5408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/comments?post=5408"}],"version-history":[{"count":5,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/posts\/5408\/revisions"}],"predecessor-version":[{"id":5709,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/posts\/5408\/revisions\/5709"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/media\/5704"}],"wp:attachment":[{"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/media?parent=5408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/categories?post=5408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secondlife.lol\/ja\/wp-json\/wp\/v2\/tags?post=5408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}