curl -L -o er-diagram-generator.skill "https://aiskillstore.io/v1/agent/skills/49d15293-cde7-4ce9-b720-e14fddee86d3/download?platform=ClaudeCode"
{
"tool": "download_skill",
"arguments": {
"skill_id": "49d15293-cde7-4ce9-b720-e14fddee86d3",
"platform": "ClaudeCode"
}
}
{
"mcpServers": {
"skill-store": {
"url": "https://aiskillstore.io/mcp/"
}
}
}
DDL SQL to ER diagram converter: parses CREATE TABLE statements, detects FK relations, outputs Mermaid and PlantUML. Zero external dependencies. Audits 1NF/2NF/3NF violations and naming rules.
Compatible Platforms any
Findings: ["메타데이터 경고: 권장 필드 없음: 'requirements' (SKILL.md v2 권장)", "메타데이터 경고: 권장 필드 없음: 'changelog' (SKILL.md v2 권장)"]
✅ No security risks found.
AI Review Stage
1. **권한 일치 여부**: 스킬 메타데이터에서 `network: false`, `filesystem: false`, `subprocess: false`로 명확하게 권한을 선언했습니다. 제공된 `main.py` 코드 스니펫은 DDL 문자열을 파싱하고 처리하는 순수 인메모리 로직으로 구성되어 있으며, 선언된 권한 외의 외부 통신, 파일 시스템 접근, 외부 프로세스 실행 등의 시도는 발견되지 않았습니다. `sys.stdout` 및 `sys.stdin`의 `TextIOWrapper` 사용은 UTF-8 인코딩 처리를 위한 일반적인 방법으로 보안상 문제가 없습니다. 2. **악의적 목적 코드**: 코드에 난독화나 데이터 탈취, 시스템 파괴와 같은 악의적인 목적의 코드는 발견되지 않았습니다. DDL 파싱 로직은 정규 표현식과 문자열 조작을 기반으로 하며, 임의 코드 실행 취약점은 보이지 않습니다. 3. **외부 통신**: `permissions.network`가 `false`로 선언되었고, 코드에서도 `requests`, `urllib`, `socket` 등 외부 통신을 시도하는 모듈의 사용 흔적이 없습니다. 4. **사용자 데이터 수집/전송**: 스킬은 `stdin`으로 DDL을 입력받아 `stdout`으로 결과를 출력하는 `stdin_stdout` 패턴을 따르며, 외부 통신 권한이 없으므로 사용자 데이터를 무단으로 수집하거나 전송할 수 없습니다. 5. **코드 품질**: 스킬의 목적(DDL 파싱 및 ER 다이어그램 생성)에 부합하는 기능적 코드로 보이며, 'Zero external dependencies'라는 설명과 일치하게 자체적인 파싱 로직을 구현하고 있습니다. 정적 분석 결과 또한 'approved'로 판단되었습니다.
Representative input/output examples for this skill. Agents can use these to understand how to invoke the skill and what output to expect.
users 와 orders 테이블 DDL 을 Mermaid + PlantUML ER 다이어그램으로 변환합니다.
{
"action": "generate",
"ddl": "CREATE TABLE users (\n id INTEGER PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n email VARCHAR(255) UNIQUE\n);\nCREATE TABLE orders (\n id INTEGER PRIMARY KEY,\n user_id INTEGER NOT NULL,\n amount DECIMAL(10,2),\n FOREIGN KEY (user_id) REFERENCES users(id)\n);\n",
"format": "mermaid"
}
{
"action": "generate",
"mermaid": "erDiagram\n users {\n INTEGER id PK\n VARCHAR_100 name\n VARCHAR_255 email\n }\n orders {\n INTEGER id PK\n INTEGER user_id FK\n DECIMAL_10_2 amount\n }\n users ||--o{ orders : \"has\"\n",
"meta": {
"format": "mermaid",
"relation_count": 1,
"table_count": 2
},
"relations": [
{
"from_column": "user_id",
"from_table": "orders",
"relation_type": "one_to_many",
"to_column": "id",
"to_table": "users"
}
],
"tables": [
{
"columns": [
{
"is_fk": false,
"is_pk": true,
"name": "id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": false,
"is_pk": false,
"name": "name",
"nullable": false,
"type": "VARCHAR(100)"
},
{
"is_fk": false,
"is_pk": false,
"name": "email",
"nullable": true,
"type": "VARCHAR(255)"
}
],
"foreign_keys": [],
"name": "users",
"primary_keys": [
"id"
]
},
{
"columns": [
{
"is_fk": false,
"is_pk": true,
"name": "id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": true,
"is_pk": false,
"name": "user_id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": false,
"is_pk": false,
"name": "amount",
"nullable": true,
"type": "DECIMAL(10,2)"
}
],
"foreign_keys": [
{
"column": "user_id",
"references_column": "id",
"references_table": "users"
}
],
"name": "orders",
"primary_keys": [
"id"
]
}
]
}
한국어 테이블/컬럼명이 포함된 DDL 을 정확히 파싱합니다.
{
"action": "generate",
"ddl": "CREATE TABLE \uc0ac\uc6a9\uc790 (\n id INTEGER PRIMARY KEY,\n \uc774\ub984 VARCHAR(100) NOT NULL,\n \uc774\uba54\uc77c VARCHAR(255)\n);\nCREATE TABLE \uc8fc\ubb38 (\n id INTEGER PRIMARY KEY,\n \uc0ac\uc6a9\uc790_id INTEGER,\n \uae08\uc561 DECIMAL(10,2),\n FOREIGN KEY (\uc0ac\uc6a9\uc790_id) REFERENCES \uc0ac\uc6a9\uc790(id)\n);\n",
"format": "mermaid"
}
{
"action": "generate",
"mermaid": "erDiagram\n \uc0ac\uc6a9\uc790 {\n INTEGER id PK\n VARCHAR_100 \uc774\ub984\n VARCHAR_255 \uc774\uba54\uc77c\n }\n \uc8fc\ubb38 {\n INTEGER id PK\n INTEGER \uc0ac\uc6a9\uc790_id FK\n DECIMAL_10_2 \uae08\uc561\n }\n \uc0ac\uc6a9\uc790 ||--o{ \uc8fc\ubb38 : \"has\"\n",
"meta": {
"format": "mermaid",
"relation_count": 1,
"table_count": 2
},
"tables": [
{
"columns": [
{
"is_fk": false,
"is_pk": true,
"name": "id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": false,
"is_pk": false,
"name": "\uc774\ub984",
"nullable": false,
"type": "VARCHAR(100)"
},
{
"is_fk": false,
"is_pk": false,
"name": "\uc774\uba54\uc77c",
"nullable": true,
"type": "VARCHAR(255)"
}
],
"foreign_keys": [],
"name": "\uc0ac\uc6a9\uc790",
"primary_keys": [
"id"
]
}
]
}
중간 테이블(junction table)을 통한 M:N 관계를 자동 감지합니다.
{
"action": "detect_relations",
"ddl": "CREATE TABLE students (id INTEGER PRIMARY KEY, name VARCHAR(100));\nCREATE TABLE courses (id INTEGER PRIMARY KEY, title VARCHAR(200));\nCREATE TABLE student_courses (\n student_id INTEGER,\n course_id INTEGER,\n PRIMARY KEY (student_id, course_id),\n FOREIGN KEY (student_id) REFERENCES students(id),\n FOREIGN KEY (course_id) REFERENCES courses(id)\n);\n"
}
{
"action": "detect_relations",
"meta": {
"relation_count": 2,
"table_count": 3
},
"relations": [
{
"from_column": "student_id",
"from_table": "student_courses",
"relation_type": "many_to_many",
"to_column": "id",
"to_table": "students"
},
{
"from_column": "course_id",
"from_table": "student_courses",
"relation_type": "many_to_many",
"to_column": "id",
"to_table": "courses"
}
]
}
같은 테이블을 참조하는 self-referential FK 를 감지합니다.
{
"action": "detect_relations",
"ddl": "CREATE TABLE employees (\n id INTEGER PRIMARY KEY,\n name VARCHAR(100),\n manager_id INTEGER,\n FOREIGN KEY (manager_id) REFERENCES employees(id)\n);\n"
}
{
"action": "detect_relations",
"meta": {
"relation_count": 1,
"table_count": 1
},
"relations": [
{
"from_column": "manager_id",
"from_table": "employees",
"relation_type": "self_reference",
"to_column": "id",
"to_table": "employees"
}
]
}
PRIMARY KEY 가 없는 테이블을 감지하고 fix_hint 를 제공합니다.
{
"action": "audit",
"audit_level": "standard",
"ddl": "CREATE TABLE logs (\n timestamp VARCHAR(30),\n level VARCHAR(10),\n message TEXT\n);\n"
}
{
"action": "audit",
"findings": [
{
"column": "",
"fix_hint": {
"action": "Add a PRIMARY KEY column to uniquely identify each row",
"doc_ref": "https://aiskillstore.io/skills/er-diagram-generator#audit",
"example": "id INTEGER PRIMARY KEY AUTOINCREMENT",
"summary": "PK \ub204\ub77d \u2014 id \uceec\ub7fc \ucd94\uac00 \uad8c\uc7a5 / Missing PK \u2014 add id column"
},
"message": "Table \u0027logs\u0027 has no PRIMARY KEY defined",
"rule": "MISSING_PK",
"severity": "error",
"table": "logs"
}
],
"meta": {
"finding_count": 1,
"table_count": 1
}
}
단일 컬럼에 복수값을 저장하는 1NF 위반 패턴을 감지합니다.
{
"action": "suggest_normalization",
"audit_level": "strict",
"ddl": "CREATE TABLE products (\n id INTEGER PRIMARY KEY,\n name VARCHAR(100),\n tags VARCHAR(500),\n categories TEXT\n);\n"
}
{
"action": "suggest_normalization",
"findings": [
{
"column": "tags",
"fix_hint": {
"action": "Create a junction table to store multi-valued attributes",
"doc_ref": "https://aiskillstore.io/skills/er-diagram-generator#1nf",
"example": "CREATE TABLE product_tags (product_id INTEGER, tag VARCHAR(50), PRIMARY KEY(product_id, tag));",
"summary": "1NF \uc704\ubc18 \uc758\uc2ec \u2014 \ubcc4\ub3c4 \ud14c\uc774\ube14\ub85c \ubd84\ub9ac / Possible 1NF violation \u2014 split into separate table"
},
"message": "Column \u0027tags\u0027 (VARCHAR) may store comma-separated values \u2014 violates 1NF",
"rule": "1NF_VIOLATION_SUSPECT",
"severity": "warning",
"table": "products"
}
],
"meta": {
"suggestion_count": 1,
"table_count": 1
},
"normalization_suggestions": [
{
"form": "1NF",
"issue": "Columns \u0027tags\u0027, \u0027categories\u0027 likely store multiple values (CSV anti-pattern)",
"suggestion": "Create separate \u0027product_tags\u0027 and \u0027product_categories\u0027 junction tables",
"table": "products"
}
]
}
DDL 을 PlantUML ER 형식으로 변환합니다.
{
"action": "generate",
"ddl": "CREATE TABLE categories (id INTEGER PRIMARY KEY, name VARCHAR(100));\nCREATE TABLE products (\n id INTEGER PRIMARY KEY,\n category_id INTEGER,\n name VARCHAR(200),\n FOREIGN KEY (category_id) REFERENCES categories(id)\n);\n",
"format": "plantuml"
}
{
"action": "generate",
"meta": {
"format": "plantuml",
"relation_count": 1,
"table_count": 2
},
"plantuml": "@startuml\nentity categories {\n * id : INTEGER \u003c\u003cPK\u003e\u003e\n --\n name : VARCHAR(100)\n}\nentity products {\n * id : INTEGER \u003c\u003cPK\u003e\u003e\n --\n category_id : INTEGER \u003c\u003cFK\u003e\u003e\n name : VARCHAR(200)\n}\ncategories ||--o{ products\n@enduml\n"
}
다이어그램 생성 없이 DDL 구조만 파싱하여 JSON 으로 반환합니다.
{
"action": "parse_ddl",
"ddl": "CREATE TABLE orders (\n id INTEGER PRIMARY KEY,\n user_id INTEGER NOT NULL,\n status VARCHAR(20) DEFAULT \u0027pending\u0027,\n created_at TIMESTAMP,\n FOREIGN KEY (user_id) REFERENCES users(id)\n);\n"
}
{
"action": "parse_ddl",
"meta": {
"table_count": 1
},
"tables": [
{
"columns": [
{
"is_fk": false,
"is_pk": true,
"name": "id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": true,
"is_pk": false,
"name": "user_id",
"nullable": false,
"type": "INTEGER"
},
{
"is_fk": false,
"is_pk": false,
"name": "status",
"nullable": true,
"type": "VARCHAR(20)"
},
{
"is_fk": false,
"is_pk": false,
"name": "created_at",
"nullable": true,
"type": "TIMESTAMP"
}
],
"foreign_keys": [
{
"column": "user_id",
"references_column": "id",
"references_table": "users"
}
],
"name": "orders",
"primary_keys": [
"id"
]
}
]
}
All examples are also available via the agent API:
/v1/agent/skills/49d15293-cde7-4ce9-b720-e14fddee86d3/schema
No reviews yet. Be the first to leave one!