bms-session-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bms-session-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "BMS Session API integration for HOSxP hospital databases. Provides skills for querying hospital data and building healthcare applications.",
|
|
5
|
+
"homepage": "https://www.npmjs.com/package/bms-session-plugin"
|
|
6
|
+
}
|
package/.mcp.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bms-session-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Claude Code plugin for BMS Session API and HOSxP hospital databases",
|
|
5
|
+
"files": [
|
|
6
|
+
".claude-plugin/",
|
|
7
|
+
"skills/",
|
|
8
|
+
".mcp.json"
|
|
9
|
+
],
|
|
10
|
+
"keywords": [
|
|
11
|
+
"claude-code-plugin",
|
|
12
|
+
"bms",
|
|
13
|
+
"hosxp",
|
|
14
|
+
"hospital",
|
|
15
|
+
"mcp",
|
|
16
|
+
"healthcare",
|
|
17
|
+
"thailand"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT"
|
|
20
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bms-session
|
|
3
|
+
description: This skill should be used when the user asks to "query HOSxP database", "connect to BMS", "use bms-session-id", "query hospital data", "build HOSxP dashboard", "access patient records", mentions "BMS Session", "HOSxP", "hospital database Thailand", or works with Thai hospital systems using HN/VN/AN identifiers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# BMS Session API — HOSxP Hospital Database Integration
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Provide guidance for querying and building applications against HOSxP hospital databases using the BMS Session API. HOSxP is the most widely used hospital information system in Thailand.
|
|
11
|
+
|
|
12
|
+
## When MCP Server Is Available
|
|
13
|
+
|
|
14
|
+
If the `bms-session` MCP server is connected, use its tools directly:
|
|
15
|
+
|
|
16
|
+
1. Read `bms://session-info` resource first to understand the database type and constraints
|
|
17
|
+
2. Use `list_tables` with a pattern filter to discover relevant tables (e.g., `list_tables({ pattern: "patient*" })`)
|
|
18
|
+
3. Use `describe_table` to understand column structure before writing queries
|
|
19
|
+
4. Use `query` to execute SQL and return results
|
|
20
|
+
|
|
21
|
+
Always use `LIMIT` to avoid returning excessive rows.
|
|
22
|
+
|
|
23
|
+
## When MCP Server Is Not Available
|
|
24
|
+
|
|
25
|
+
Build queries using the REST API directly. The flow:
|
|
26
|
+
|
|
27
|
+
### Step 1: Validate Session
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
GET https://hosxp.net/phapi/PasteJSON?Action=GET&code={bms-session-id}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Extract from response:
|
|
34
|
+
- `result.user_info.bms_url` — API base URL
|
|
35
|
+
- `result.user_info.bms_session_code` — Bearer token (fallback: `result.key_value`)
|
|
36
|
+
- `result.user_info.bms_database_type` — "MariaDB" or "PostgreSQL"
|
|
37
|
+
- `result.user_info.bms_database_name` — Database name
|
|
38
|
+
|
|
39
|
+
### Step 2: Execute Queries
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
POST {bms_url}/api/sql
|
|
43
|
+
Headers: Authorization: Bearer {bms_session_code}, Content-Type: application/json
|
|
44
|
+
Body: { "sql": "SELECT ...", "app": "MyApp" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Response contains: `data` (rows), `field_name` (columns), `record_count`, `MessageCode`.
|
|
48
|
+
|
|
49
|
+
## Quick Code Patterns
|
|
50
|
+
|
|
51
|
+
### Python
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import requests
|
|
55
|
+
|
|
56
|
+
SESSION_ID = "your-session-id"
|
|
57
|
+
# Step 1: Get session
|
|
58
|
+
session = requests.get(f"https://hosxp.net/phapi/PasteJSON?Action=GET&code={SESSION_ID}").json()
|
|
59
|
+
url = session["result"]["user_info"]["bms_url"]
|
|
60
|
+
token = session["result"]["user_info"].get("bms_session_code") or session["result"].get("key_value")
|
|
61
|
+
|
|
62
|
+
# Step 2: Query
|
|
63
|
+
result = requests.post(f"{url}/api/sql",
|
|
64
|
+
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
|
65
|
+
json={"sql": "SELECT hn, pname, fname, lname FROM patient LIMIT 10", "app": "MyApp"}
|
|
66
|
+
).json()
|
|
67
|
+
print(result["data"])
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### TypeScript
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const SESSION_ID = "your-session-id";
|
|
74
|
+
// Step 1: Get session
|
|
75
|
+
const session = await fetch(`https://hosxp.net/phapi/PasteJSON?Action=GET&code=${SESSION_ID}`).then(r => r.json());
|
|
76
|
+
const url = session.result.user_info.bms_url;
|
|
77
|
+
const token = session.result.user_info.bms_session_code ?? session.result.key_value;
|
|
78
|
+
|
|
79
|
+
// Step 2: Query
|
|
80
|
+
const result = await fetch(`${url}/api/sql`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
83
|
+
body: JSON.stringify({ sql: "SELECT hn, pname, fname, lname FROM patient LIMIT 10", app: "MyApp" }),
|
|
84
|
+
}).then(r => r.json());
|
|
85
|
+
console.log(result.data);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## HOSxP Database Quick Reference
|
|
89
|
+
|
|
90
|
+
### Key Identifiers
|
|
91
|
+
- **HN** (Hospital Number) — unique patient ID within a hospital
|
|
92
|
+
- **VN** (Visit Number) — unique outpatient visit ID
|
|
93
|
+
- **AN** (Admission Number) — unique inpatient admission ID
|
|
94
|
+
|
|
95
|
+
### Core Tables
|
|
96
|
+
|
|
97
|
+
| Table | Purpose | Key Columns |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `patient` | Patient demographics | `hn`, `pname`, `fname`, `lname`, `birthday`, `sex`, `cid` |
|
|
100
|
+
| `opd` | Outpatient visits | `hn`, `vn`, `vstdate`, `doctor` |
|
|
101
|
+
| `ovst` | Visit details | `vn`, `hn`, `vstdate`, `vsttime`, `main_dep` |
|
|
102
|
+
| `ipt` | Inpatient admissions | `an`, `hn`, `regdate`, `dchdate`, `ward` |
|
|
103
|
+
| `doctor` | Physicians | `code`, `name`, `licenseno` |
|
|
104
|
+
| `drugitems` | Medication catalog | `icode`, `name`, `genericname`, `dosageform` |
|
|
105
|
+
| `icd101` | ICD-10 diagnosis codes | `code`, `name`, `tname` |
|
|
106
|
+
|
|
107
|
+
### Common Relationships
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
patient.hn ─→ opd.hn (patient's visits)
|
|
111
|
+
opd.vn ─→ ovst.vn (visit details)
|
|
112
|
+
opd.vn ─→ opitemrece.vn (prescriptions/charges)
|
|
113
|
+
patient.hn ─→ ipt.hn (admissions)
|
|
114
|
+
ipt.an ─→ iptdrugorder.an (inpatient orders)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Table Naming Patterns
|
|
118
|
+
|
|
119
|
+
| Prefix | Domain |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `patient_*` | Patient-related (demographics, allergies, history) |
|
|
122
|
+
| `opd_*` / `ovst_*` | Outpatient visits |
|
|
123
|
+
| `ipt_*` | Inpatient admissions |
|
|
124
|
+
| `drug*` | Medications and pharmacy |
|
|
125
|
+
| `lab_*` | Laboratory results |
|
|
126
|
+
| `xray_*` / `rad_*` | Radiology |
|
|
127
|
+
| `er_*` | Emergency room |
|
|
128
|
+
| `an_*` / `anc_*` | Antenatal care |
|
|
129
|
+
| `pcu_*` | Primary care unit |
|
|
130
|
+
|
|
131
|
+
## Constraints and Best Practices
|
|
132
|
+
|
|
133
|
+
- **Read-only** — Do not attempt write operations unless explicitly requested
|
|
134
|
+
- **Use LIMIT** — HOSxP databases can have millions of records
|
|
135
|
+
- **Single quotes** — Use `'` for string literals (required for PostgreSQL)
|
|
136
|
+
- **Restricted tables** — `opduser`, `opdconfig`, `sys_var`, `user_var`, `user_jwt` are blocked
|
|
137
|
+
- **Max 20 tables** per query
|
|
138
|
+
- **Supported SQL** — SELECT, DESCRIBE, EXPLAIN, SHOW, WITH (CTE)
|
|
139
|
+
- **Sessions expire** — Default 10 hours, check `expired_second` in session response
|
|
140
|
+
|
|
141
|
+
## Error Handling
|
|
142
|
+
|
|
143
|
+
| MessageCode | Meaning | Action |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| 200 | Success | Process data |
|
|
146
|
+
| 400 | Invalid SQL or bad request | Check SQL syntax |
|
|
147
|
+
| 409 | SQL execution error | Check column/table names |
|
|
148
|
+
| 500 | Server error or session expired | Re-validate session |
|
|
149
|
+
| HTTP 501 | Authentication failure | Session expired, get new session ID |
|
|
150
|
+
|
|
151
|
+
## Additional Resources
|
|
152
|
+
|
|
153
|
+
### Reference Files
|
|
154
|
+
|
|
155
|
+
For detailed documentation, consult:
|
|
156
|
+
- **`references/api-reference.md`** — Complete API specification with all endpoints, parameters, field types, and parameter binding
|
|
157
|
+
- **`references/hosxp-database-guide.md`** — Comprehensive HOSxP table catalog, relationships, and Thai healthcare data patterns
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# BMS Session API Reference
|
|
2
|
+
|
|
3
|
+
## Session Validation
|
|
4
|
+
|
|
5
|
+
### Endpoint
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
GET https://hosxp.net/phapi/PasteJSON?Action=GET&code={bms-session-id}
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Response Structure
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"MessageCode": 200,
|
|
16
|
+
"Message": "OK",
|
|
17
|
+
"result": {
|
|
18
|
+
"system_info": {
|
|
19
|
+
"version": "1.0.0.0",
|
|
20
|
+
"environment": "production"
|
|
21
|
+
},
|
|
22
|
+
"user_info": {
|
|
23
|
+
"name": "User Name",
|
|
24
|
+
"position": "Position",
|
|
25
|
+
"position_id": 1,
|
|
26
|
+
"hospital_code": "00000",
|
|
27
|
+
"doctor_code": "00000",
|
|
28
|
+
"department": "department_name",
|
|
29
|
+
"location": "location_name",
|
|
30
|
+
"is_hr_admin": false,
|
|
31
|
+
"is_director": false,
|
|
32
|
+
"bms_url": "https://hospital.tunnel.hosxp.net",
|
|
33
|
+
"bms_session_port": 53845,
|
|
34
|
+
"bms_session_code": "jwt_token",
|
|
35
|
+
"bms_database_name": "hosxp_db",
|
|
36
|
+
"bms_database_type": "PostgreSQL"
|
|
37
|
+
},
|
|
38
|
+
"key_value": "jwt_token",
|
|
39
|
+
"expired_second": 36000
|
|
40
|
+
},
|
|
41
|
+
"RequestTime": "2025-10-20T12:00:00.000Z"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Key Fields
|
|
46
|
+
|
|
47
|
+
| Path | Purpose |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `result.user_info.bms_url` | Base URL for API calls |
|
|
50
|
+
| `result.user_info.bms_session_code` | Bearer token for authentication |
|
|
51
|
+
| `result.key_value` | Fallback bearer token (same value) |
|
|
52
|
+
| `result.user_info.bms_database_type` | "MariaDB" or "PostgreSQL" — determines SQL dialect |
|
|
53
|
+
| `result.user_info.bms_database_name` | Database name |
|
|
54
|
+
| `result.expired_second` | Session TTL in seconds |
|
|
55
|
+
|
|
56
|
+
## /api/sql — Read Operations
|
|
57
|
+
|
|
58
|
+
### GET Method
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
GET {bms_url}/api/sql?sql=SELECT+VERSION()&app=MyApp
|
|
62
|
+
Authorization: Bearer {bms_session_code}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### POST Method (Recommended)
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
POST {bms_url}/api/sql
|
|
69
|
+
Authorization: Bearer {bms_session_code}
|
|
70
|
+
Content-Type: application/json
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
"sql": "SELECT hn, pname, fname, lname FROM patient LIMIT 10",
|
|
74
|
+
"app": "MyApp"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### POST with Parameter Binding
|
|
79
|
+
|
|
80
|
+
Prevents SQL injection by binding parameters separately:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"sql": "SELECT * FROM patient WHERE birthday = :birthday AND bloodgrp = :bloodgrp",
|
|
85
|
+
"app": "MyApp",
|
|
86
|
+
"params": {
|
|
87
|
+
"birthday": { "value": "2024-01-01", "value_type": "date" },
|
|
88
|
+
"bloodgrp": { "value": "O", "value_type": "string" }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Parameter Types
|
|
94
|
+
|
|
95
|
+
| Type | Description | Example |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| `string` | Text values | `"John"` |
|
|
98
|
+
| `integer` | Whole numbers | `42` |
|
|
99
|
+
| `float` | Decimal numbers | `3.14` |
|
|
100
|
+
| `date` | YYYY-MM-DD | `"2024-01-01"` |
|
|
101
|
+
| `time` | HH:mm:ss | `"08:00:00"` |
|
|
102
|
+
| `datetime` | ISO 8601 | `"2024-01-01T08:00:00"` |
|
|
103
|
+
|
|
104
|
+
### Supported SQL Statements
|
|
105
|
+
|
|
106
|
+
| Statement | Purpose | Example |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| `SELECT` | Retrieve data | `SELECT * FROM patient LIMIT 10` |
|
|
109
|
+
| `DESCRIBE` | Table structure (MariaDB) | `DESCRIBE patient` |
|
|
110
|
+
| `EXPLAIN` | Query execution plan | `EXPLAIN SELECT * FROM patient` |
|
|
111
|
+
| `SHOW` | Database metadata | `SHOW TABLES`, `SHOW DATABASES` |
|
|
112
|
+
| `WITH` | Common Table Expressions | `WITH cte AS (SELECT ...) SELECT * FROM cte` |
|
|
113
|
+
|
|
114
|
+
### Response Format
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"MessageCode": 200,
|
|
119
|
+
"Message": "OK",
|
|
120
|
+
"RequestTime": "2025-10-20T12:00:00.000Z",
|
|
121
|
+
"data": [
|
|
122
|
+
{ "hn": "12345", "pname": "Mr.", "fname": "John", "lname": "Doe" }
|
|
123
|
+
],
|
|
124
|
+
"field": [6, 6, 6, 6],
|
|
125
|
+
"field_name": ["hn", "pname", "fname", "lname"],
|
|
126
|
+
"record_count": 1
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Field Type Codes
|
|
131
|
+
|
|
132
|
+
The `field` array contains type codes for each column:
|
|
133
|
+
|
|
134
|
+
| Code | Type | Description |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| 1 | Boolean | true/false |
|
|
137
|
+
| 2 | Integer | Whole numbers |
|
|
138
|
+
| 3 | Float | Decimal numbers |
|
|
139
|
+
| 4 | DateTime | ISO 8601 format |
|
|
140
|
+
| 5 | Time | HH:mm:ss |
|
|
141
|
+
| 6 | String | Text (most common) |
|
|
142
|
+
| 7 | Blob | Binary data (Base64) |
|
|
143
|
+
| 9 | String (Alt) | Alternative text type |
|
|
144
|
+
|
|
145
|
+
### Error Codes
|
|
146
|
+
|
|
147
|
+
| MessageCode | Meaning |
|
|
148
|
+
|---|---|
|
|
149
|
+
| 200 | Success |
|
|
150
|
+
| 400 | Invalid SQL, bad request, or invalid key |
|
|
151
|
+
| 409 | SQL execution error (bad column/table name) |
|
|
152
|
+
| 500 | Server error or session expired |
|
|
153
|
+
|
|
154
|
+
| HTTP Status | Meaning |
|
|
155
|
+
|---|---|
|
|
156
|
+
| 200 | Request processed (check MessageCode) |
|
|
157
|
+
| 501 | Unauthorized — missing or invalid Bearer token |
|
|
158
|
+
|
|
159
|
+
### Security Restrictions
|
|
160
|
+
|
|
161
|
+
- **Table blacklist**: `opduser`, `opdconfig`, `sys_var`, `user_var`, `user_jwt`
|
|
162
|
+
- **Max 20 tables** per query
|
|
163
|
+
- **No cross-database queries** (dots not allowed in table names)
|
|
164
|
+
- **SQL whitelist**: Only SELECT, DESCRIBE, EXPLAIN, SHOW, WITH allowed
|
|
165
|
+
- Trailing semicolons are removed automatically
|
|
166
|
+
- Backslashes are converted for safety
|
|
167
|
+
|
|
168
|
+
## /api/sql_update — Write Operations
|
|
169
|
+
|
|
170
|
+
Write operations require an additional authentication key and are not covered by default in read-only integrations. Include only when the user explicitly requests write capability.
|
|
171
|
+
|
|
172
|
+
### Authentication Key
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
key = MD5(bms_session_code + "PO7yRv3OdFwK81eg").toUpperCase()
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Upsert (POST)
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"sql": "SELECT hn, fname FROM patient WHERE hn = '12345'",
|
|
183
|
+
"app": "MyApp",
|
|
184
|
+
"key": "MD5_HASH",
|
|
185
|
+
"table_name": "patient",
|
|
186
|
+
"field": [6, 6],
|
|
187
|
+
"data": [{ "hn": "12345", "fname": "Updated Name" }]
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Delete (DELETE method)
|
|
192
|
+
|
|
193
|
+
Same format as upsert. The `sql` identifies records to delete. `data` is ignored.
|
|
194
|
+
|
|
195
|
+
### Write Constraints
|
|
196
|
+
|
|
197
|
+
- `sql` must be a simple SELECT (no JOINs, subqueries, GROUP BY)
|
|
198
|
+
- Table must have exactly one primary key
|
|
199
|
+
- `field` array must match columns in the SELECT query
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# HOSxP Database Guide
|
|
2
|
+
|
|
3
|
+
HOSxP is the most widely used hospital information system (HIS) in Thailand, deployed in over 800 hospitals. This guide covers database conventions, common tables, and query patterns.
|
|
4
|
+
|
|
5
|
+
## Database Platforms
|
|
6
|
+
|
|
7
|
+
HOSxP deployments use either:
|
|
8
|
+
- **MariaDB** (older/most common) — Use `SHOW TABLES`, `DESCRIBE table_name`
|
|
9
|
+
- **PostgreSQL** (newer deployments) — Use `information_schema` queries, single quotes required
|
|
10
|
+
|
|
11
|
+
Always check `bms_database_type` from the session response to determine which dialect to use.
|
|
12
|
+
|
|
13
|
+
## Key Identifiers
|
|
14
|
+
|
|
15
|
+
| Abbreviation | Thai Name | Purpose | Format |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| **HN** | เลขประจำตัวผู้ป่วย | Hospital Number — unique patient ID | String, e.g., `"000001"` |
|
|
18
|
+
| **VN** | เลขครั้งที่มา | Visit Number — outpatient visit ID | String, e.g., `"6801000001"` |
|
|
19
|
+
| **AN** | เลขรับรองการรักษา | Admission Number — inpatient stay ID | String, e.g., `"68/00001"` |
|
|
20
|
+
| **CID** | เลขบัตรประชาชน | Citizen ID (13-digit Thai national ID) | String, 13 chars |
|
|
21
|
+
|
|
22
|
+
## Core Tables
|
|
23
|
+
|
|
24
|
+
### Patient Registration
|
|
25
|
+
|
|
26
|
+
| Table | Description | Key Columns |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `patient` | Master patient index | `hn` (PK), `pname`, `fname`, `lname`, `birthday`, `sex`, `cid`, `bloodgrp` |
|
|
29
|
+
| `patient_pttype` | Patient insurance types | `hn`, `pttype`, `hospmain`, `startdate`, `expiredate` |
|
|
30
|
+
| `patient_drug` | Patient medication records | `hn`, `drugitems_icode`, `vstdate` |
|
|
31
|
+
| `patient_allergy` | Known allergies | `hn`, `agent`, `symptom` |
|
|
32
|
+
|
|
33
|
+
### Outpatient (OPD)
|
|
34
|
+
|
|
35
|
+
| Table | Description | Key Columns |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `opd` | Outpatient visit header | `hn`, `vn`, `vstdate`, `doctor`, `main_dep` |
|
|
38
|
+
| `ovst` | Visit details | `vn` (PK), `hn`, `vstdate`, `vsttime`, `main_dep`, `main_dep_queue` |
|
|
39
|
+
| `ovstdiag` | Visit diagnoses | `vn`, `icd10`, `diagtype` (1=principal, 2=co-morbid) |
|
|
40
|
+
| `opitemrece` | Prescriptions & charges | `vn`, `icode`, `qty`, `unitprice` |
|
|
41
|
+
| `ovstost` | Vital signs | `vn`, `bp_systolic`, `bp_diastolic`, `pulse`, `temperature` |
|
|
42
|
+
|
|
43
|
+
### Inpatient (IPT)
|
|
44
|
+
|
|
45
|
+
| Table | Description | Key Columns |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `ipt` | Admission header | `an` (PK), `hn`, `regdate`, `dchdate`, `ward`, `pression` |
|
|
48
|
+
| `iptdiag` | Admission diagnoses | `an`, `icd10`, `diagtype` |
|
|
49
|
+
| `iptdrugorder` | Inpatient drug orders | `an`, `icode`, `qty`, `orderdate` |
|
|
50
|
+
| `ipt_nurse_note` | Nursing notes | `an`, `note_date`, `note_time`, `note_text` |
|
|
51
|
+
|
|
52
|
+
### Medications & Pharmacy
|
|
53
|
+
|
|
54
|
+
| Table | Description | Key Columns |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `drugitems` | Drug catalog (master) | `icode` (PK), `name`, `genericname`, `dosageform`, `strength` |
|
|
57
|
+
| `drugusage` | Drug usage instructions | `drugusage` (PK), `name`, `name1`, `name2`, `name3` |
|
|
58
|
+
| `drugstock` | Drug inventory | `icode`, `qty`, `warehouse` |
|
|
59
|
+
| `nondrugitems` | Non-drug items (supplies) | `icode` (PK), `name`, `unitprice` |
|
|
60
|
+
|
|
61
|
+
### Laboratory
|
|
62
|
+
|
|
63
|
+
| Table | Description | Key Columns |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `lab_head` | Lab order header | `lab_order_number`, `hn`, `vn`, `order_date` |
|
|
66
|
+
| `lab_order` | Lab order items | `lab_order_number`, `lab_items_code`, `lab_order_result` |
|
|
67
|
+
| `lab_items` | Lab test catalog | `lab_items_code` (PK), `lab_items_name`, `lab_items_unit` |
|
|
68
|
+
|
|
69
|
+
### Reference / Lookup Tables
|
|
70
|
+
|
|
71
|
+
| Table | Description | Key Columns |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `icd101` | ICD-10 diagnosis codes | `code` (PK), `name` (English), `tname` (Thai) |
|
|
74
|
+
| `icd9cm1` | ICD-9-CM procedure codes | `code`, `name`, `tname` |
|
|
75
|
+
| `pttype` | Insurance/payer types | `pttype` (PK), `name`, `nhso_code` |
|
|
76
|
+
| `kskdepartment` | Hospital departments | `depcode` (PK), `department` |
|
|
77
|
+
| `ward` | Ward/bed management | `ward` (PK), `name` |
|
|
78
|
+
| `spclty` | Medical specialties | `spclty` (PK), `name` |
|
|
79
|
+
|
|
80
|
+
## Common Query Patterns
|
|
81
|
+
|
|
82
|
+
### Patient Lookup
|
|
83
|
+
|
|
84
|
+
```sql
|
|
85
|
+
-- By HN
|
|
86
|
+
SELECT hn, pname, fname, lname, birthday, sex FROM patient WHERE hn = '000001'
|
|
87
|
+
|
|
88
|
+
-- By name (Thai)
|
|
89
|
+
SELECT hn, pname, fname, lname FROM patient WHERE fname LIKE '%สมชาย%' LIMIT 20
|
|
90
|
+
|
|
91
|
+
-- By CID
|
|
92
|
+
SELECT hn, pname, fname, lname FROM patient WHERE cid = '1234567890123'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Visit History
|
|
96
|
+
|
|
97
|
+
```sql
|
|
98
|
+
-- Recent OPD visits for a patient
|
|
99
|
+
SELECT o.vn, o.vstdate, d.name as doctor_name, k.department
|
|
100
|
+
FROM ovst o
|
|
101
|
+
LEFT JOIN doctor d ON d.code = o.doctor
|
|
102
|
+
LEFT JOIN kskdepartment k ON k.depcode = o.main_dep
|
|
103
|
+
WHERE o.hn = '000001'
|
|
104
|
+
ORDER BY o.vstdate DESC
|
|
105
|
+
LIMIT 20
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Diagnosis Statistics
|
|
109
|
+
|
|
110
|
+
```sql
|
|
111
|
+
-- Top 10 diagnoses this month
|
|
112
|
+
SELECT od.icd10, i.name as diagnosis, COUNT(*) as visit_count
|
|
113
|
+
FROM ovstdiag od
|
|
114
|
+
JOIN icd101 i ON i.code = od.icd10
|
|
115
|
+
JOIN ovst o ON o.vn = od.vn
|
|
116
|
+
WHERE o.vstdate >= '2026-01-01' AND o.vstdate <= '2026-01-31'
|
|
117
|
+
AND od.diagtype = '1'
|
|
118
|
+
GROUP BY od.icd10, i.name
|
|
119
|
+
ORDER BY visit_count DESC
|
|
120
|
+
LIMIT 10
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Drug Prescriptions
|
|
124
|
+
|
|
125
|
+
```sql
|
|
126
|
+
-- Most prescribed drugs this month
|
|
127
|
+
SELECT d.name as drug_name, d.genericname, COUNT(*) as rx_count
|
|
128
|
+
FROM opitemrece oi
|
|
129
|
+
JOIN drugitems d ON d.icode = oi.icode
|
|
130
|
+
JOIN ovst o ON o.vn = oi.vn
|
|
131
|
+
WHERE o.vstdate >= '2026-01-01'
|
|
132
|
+
AND d.name IS NOT NULL
|
|
133
|
+
GROUP BY d.name, d.genericname
|
|
134
|
+
ORDER BY rx_count DESC
|
|
135
|
+
LIMIT 20
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Patient Counts by Department
|
|
139
|
+
|
|
140
|
+
```sql
|
|
141
|
+
SELECT k.department, COUNT(DISTINCT o.hn) as patient_count, COUNT(*) as visit_count
|
|
142
|
+
FROM ovst o
|
|
143
|
+
JOIN kskdepartment k ON k.depcode = o.main_dep
|
|
144
|
+
WHERE o.vstdate >= '2026-01-01'
|
|
145
|
+
GROUP BY k.department
|
|
146
|
+
ORDER BY visit_count DESC
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Table Discovery Patterns
|
|
150
|
+
|
|
151
|
+
HOSxP has thousands of tables. Use these patterns to find relevant ones:
|
|
152
|
+
|
|
153
|
+
| Looking for | Search pattern | Example tables |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| Patient data | `patient*` | patient, patient_pttype, patient_allergy |
|
|
156
|
+
| Outpatient | `o*`, `opd*`, `ovst*` | opd, ovst, ovstdiag, opitemrece |
|
|
157
|
+
| Inpatient | `ipt*` | ipt, iptdiag, iptdrugorder |
|
|
158
|
+
| Drugs | `drug*` | drugitems, drugusage, drugstock |
|
|
159
|
+
| Lab | `lab_*` | lab_head, lab_order, lab_items |
|
|
160
|
+
| Radiology | `xray_*`, `rad_*` | xray_head, rad_request |
|
|
161
|
+
| Emergency | `er_*` | er_regist, er_nursing_detail |
|
|
162
|
+
| Dental | `*dent*` | patient_dent_diagram |
|
|
163
|
+
| Antenatal | `anc_*` | anc_head, anc_detail |
|
|
164
|
+
| Surgery | `*oper*` | operation_list, operation_detail |
|
|
165
|
+
| Appointment | `*appoint*` | oapp (OPD appointment) |
|
|
166
|
+
| Referral | `*refer*` | referout, referin |
|
|
167
|
+
| Insurance | `pttype*` | pttype, patient_pttype |
|
|
168
|
+
|
|
169
|
+
## Thai Healthcare Context
|
|
170
|
+
|
|
171
|
+
### Insurance Types (pttype)
|
|
172
|
+
|
|
173
|
+
Common Thai healthcare insurance schemes:
|
|
174
|
+
- **UC** (บัตรทอง) — Universal Coverage (NHSO)
|
|
175
|
+
- **SSS** (ประกันสังคม) — Social Security Scheme
|
|
176
|
+
- **CSMBS** (ข้าราชการ) — Civil Servant Medical Benefit Scheme
|
|
177
|
+
- **Self-pay** (จ่ายเอง) — Out-of-pocket
|
|
178
|
+
|
|
179
|
+
### Department Codes
|
|
180
|
+
|
|
181
|
+
Departments vary by hospital but common patterns:
|
|
182
|
+
- Emergency, OPD General, OPD Specialty clinics
|
|
183
|
+
- IPD wards (medical, surgical, pediatric, obstetric)
|
|
184
|
+
- Operating room, ICU, Dental
|
|
185
|
+
|
|
186
|
+
### Data Sensitivity Notes
|
|
187
|
+
|
|
188
|
+
- `cid` (Citizen ID) is personally identifiable — use aggregated data when possible
|
|
189
|
+
- Patient names (`fname`, `lname`) are PII — anonymize in reports
|
|
190
|
+
- Design dashboards to show statistics and trends, not individual patient records
|
|
191
|
+
- The BMS Session system is designed for non-sensitive operational data access
|