{
 "system": "S3",
 "title": "S3 - Activity Report & Course Registration (PRC)",
 "schema": "PRC",
 "database": "PSDBPRDDB",
 "engine": "SQL Server 2022",
 "status": "target_design",
 "tor": "7.13",
 "source": "RLPD-Dev-P2_SRS-S3_PRC v2.0.0",
 "generated": "2026-06-14",
 "table_count": 28,
 "tables": [
  {
   "name": "Province",
   "group": "1.1 Lookups (master/reference)",
   "requirement": "REQ-PRC-001",
   "columns": [
    {
     "name": "ProvinceId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Code",
     "type": "varchar(10)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "รหัสย่อจังหวัด ('BKK','CMI')"
    },
    {
     "name": "NameTh",
     "type": "nvarchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อจังหวัดภาษาไทย"
    },
    {
     "name": "NameEn",
     "type": "nvarchar(150)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ชื่อจังหวัดภาษาอังกฤษ"
    },
    {
     "name": "Region",
     "type": "nvarchar(50)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ภูมิภาค (เหนือ/อีสาน/กลาง/ใต้)"
    },
    {
     "name": "MapX",
     "type": "decimal(6,2)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "พิกัด X บน SVG silhouette (heatmap)"
    },
    {
     "name": "MapY",
     "type": "decimal(6,2)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "พิกัด Y บน SVG silhouette (heatmap)"
    },
    {
     "name": "Sequence",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ลำดับแสดง"
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "สถานะใช้งาน"
    }
   ],
   "primary_key": [
    "ProvinceId"
   ],
   "unique": [
    [
     "Code"
    ]
   ],
   "checks": [],
   "foreign_keys": [],
   "indexes": []
  },
  {
   "name": "MemberType",
   "group": "1.1 Lookups (master/reference)",
   "requirement": "REQ-PRC-002",
   "columns": [
    {
     "name": "MemberTypeId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Code",
     "type": "varchar(30)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "GOV/BUSINESS/YOUTH/TEACHER/CITIZEN"
    },
    {
     "name": "NameTh",
     "type": "nvarchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'เจ้าหน้าที่รัฐ','ภาคธุรกิจ','เยาวชน','ครู/บุคลากรการศึกษา','ประชาชน'"
    },
    {
     "name": "Sequence",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "MemberTypeId"
   ],
   "unique": [
    [
     "Code"
    ]
   ],
   "checks": [],
   "foreign_keys": [],
   "indexes": []
  },
  {
   "name": "KnowledgeType",
   "group": "1.1 Lookups (master/reference)",
   "requirement": "REQ-PRC-006",
   "columns": [
    {
     "name": "KnowledgeTypeId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Code",
     "type": "varchar(30)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ARTICLE/VIDEO/INFOGRAPHIC/SOCIAL/SEMINAR"
    },
    {
     "name": "NameTh",
     "type": "nvarchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'บทความ','วิดีโอ','Infographic','สื่อสังคมออนไลน์','การอบรม/สัมมนา'"
    },
    {
     "name": "Sequence",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "KnowledgeTypeId"
   ],
   "unique": [
    [
     "Code"
    ]
   ],
   "checks": [],
   "foreign_keys": [],
   "indexes": []
  },
  {
   "name": "OrgUnit",
   "group": "1.1 Lookups (master/reference)",
   "requirement": "cross-cutting",
   "columns": [
    {
     "name": "OrgUnitId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Code",
     "type": "varchar(50)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "รหัสกอง ('KSS','KPS')"
    },
    {
     "name": "NameTh",
     "type": "nvarchar(300)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อหน่วยงาน"
    },
    {
     "name": "ParentOrgUnitId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "OrgUnit",
      "ref_column": "OrgUnitId"
     },
     "description": "กองแม่ (self-ref)"
    },
    {
     "name": "IsInternal",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ภายในกรมฯ vs ภายนอก"
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "OrgUnitId"
   ],
   "unique": [
    [
     "Code"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "ParentOrgUnitId",
     "ref_table": "OrgUnit",
     "ref_column": "OrgUnitId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Role",
   "group": "1.1 Lookups (master/reference)",
   "requirement": "Auth",
   "columns": [
    {
     "name": "RoleId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Code",
     "type": "varchar(30)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ADMIN/OFFICER_KSS/OFFICER_OTHER/TRAINER/VIEWER/CITIZEN"
    },
    {
     "name": "NameTh",
     "type": "nvarchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ป้ายชื่อบทบาท"
    },
    {
     "name": "Description",
     "type": "nvarchar(500)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "คำอธิบายสิทธิ์"
    },
    {
     "name": "Sequence",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "RoleId"
   ],
   "unique": [
    [
     "Code"
    ]
   ],
   "checks": [],
   "foreign_keys": [],
   "indexes": []
  },
  {
   "name": "AppUser",
   "group": "1.2 Identity / Auth (thin mirror)",
   "requirement": "Auth",
   "columns": [
    {
     "name": "AppUserId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "ExternalSubject",
     "type": "varchar(255)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "OIDC 'sub' / Keycloak UUID / AD sAMAccountName / ThaiD pairwise"
    },
    {
     "name": "AuthSource",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "AD / KEYCLOAK / THAID"
    },
    {
     "name": "Username",
     "type": "nvarchar(255)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "mirrors SSO username (unique เมื่อ not null — ดู IX section)"
    },
    {
     "name": "DisplayName",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อ-สกุลแสดงผล"
    },
    {
     "name": "Email",
     "type": "nvarchar(150)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "อีเมล (จาก token claim)"
    },
    {
     "name": "Phone",
     "type": "varchar(30)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "เบอร์ติดต่อ"
    },
    {
     "name": "OrgUnitId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "OrgUnit",
      "ref_column": "OrgUnitId"
     },
     "description": "สังกัด (data-scoping default)"
    },
    {
     "name": "TrainerId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Trainer",
      "ref_column": "TrainerId"
     },
     "description": "ถ้า user เป็นวิทยากร -> ผูก Trainer (TRAINER-sees-own)"
    },
    {
     "name": "MemberId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Member",
      "ref_column": "MemberId"
     },
     "description": "ถ้า user เป็น CITIZEN/ศิษย์เก่า -> ผูก Member"
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "active flag"
    },
    {
     "name": "LastLoginAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "AppUserId"
   ],
   "unique": [
    [
     "ExternalSubject"
    ]
   ],
   "checks": [
    "AuthSource IN ('AD','KEYCLOAK','THAID')"
   ],
   "foreign_keys": [
    {
     "column": "OrgUnitId",
     "ref_table": "OrgUnit",
     "ref_column": "OrgUnitId"
    },
    {
     "column": "TrainerId",
     "ref_table": "Trainer",
     "ref_column": "TrainerId"
    },
    {
     "column": "MemberId",
     "ref_table": "Member",
     "ref_column": "MemberId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "UX_PRC_AppUser_Username",
     "columns": [
      "Username"
     ],
     "filter": "Username IS NOT NULL",
     "unique": true
    }
   ]
  },
  {
   "name": "RoleAssignment",
   "group": "1.2 Identity / Auth (thin mirror)",
   "requirement": "Auth",
   "columns": [
    {
     "name": "RoleAssignmentId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "AppUserId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "RoleId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Role",
      "ref_column": "RoleId"
     },
     "description": ""
    },
    {
     "name": "GrantedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "GrantedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ADMIN ผู้มอบสิทธิ์"
    },
    {
     "name": "IsActive",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "RoleAssignmentId"
   ],
   "unique": [
    [
     "AppUserId",
     "RoleId"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "AppUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "RoleId",
     "ref_table": "Role",
     "ref_column": "RoleId"
    },
    {
     "column": "GrantedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_RoleAssignment_User",
     "columns": [
      "AppUserId"
     ],
     "filter": "IsActive = 1",
     "unique": false
    }
   ]
  },
  {
   "name": "Course",
   "group": "1.3 Course Catalog",
   "requirement": "REQ-PRC-003/008/009/012/013",
   "columns": [
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "CourseCode",
     "type": "varchar(40)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "รหัสหลักสูตร human-facing ('HR-LDR-2569')"
    },
    {
     "name": "Title",
     "type": "nvarchar(500)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อหลักสูตร"
    },
    {
     "name": "Category",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "EXECUTIVE / PROJECT (REQ-009)"
    },
    {
     "name": "Level",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "BASIC / INTER / ADV = ต้น/กลาง/สูง (REQ-013)"
    },
    {
     "name": "Hours",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนชั่วโมง"
    },
    {
     "name": "Mode",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ONSITE / ONLINE / HYBRID (REQ-012)"
    },
    {
     "name": "ProvinceId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Province",
      "ref_column": "ProvinceId"
     },
     "description": "จังหวัดจัดอบรม (heatmap)"
    },
    {
     "name": "OnsiteVenue",
     "type": "nvarchar(500)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "สถานที่จริง (ONSITE/HYBRID)"
    },
    {
     "name": "OnlineUrl",
     "type": "nvarchar(1000)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "URL ห้องออนไลน์ (ONLINE/HYBRID; เก็บคู่ onsite ได้ — REQ-012)"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "DRAFT/OPEN/NEAR_FULL/CLOSED/PUBLISHED"
    },
    {
     "name": "IsDraft",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ฉบับร่าง (draft/publish — REQ-008)"
    },
    {
     "name": "TargetCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนเป้าหมาย"
    },
    {
     "name": "EnrolledCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนที่ลงทะเบียนแล้ว (denormalized counter)"
    },
    {
     "name": "OpenAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันเปิดรับสมัคร"
    },
    {
     "name": "CloseAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันปิดรับสมัคร"
    },
    {
     "name": "StartAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันเริ่มอบรม"
    },
    {
     "name": "CoverColor",
     "type": "varchar(20)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "สีปก (#hex)"
    },
    {
     "name": "TrainerId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Trainer",
      "ref_column": "TrainerId"
     },
     "description": "วิทยากรหลัก"
    },
    {
     "name": "Objective",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วัตถุประสงค์"
    },
    {
     "name": "HasCert",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ออกประกาศนียบัตรหรือไม่"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "CourseId"
   ],
   "unique": [
    [
     "CourseCode"
    ]
   ],
   "checks": [
    "Category IN ('EXECUTIVE','PROJECT')",
    "Level IN ('BASIC','INTER','ADV')",
    "Mode IN ('ONSITE','ONLINE','HYBRID')",
    "Status IN ('DRAFT','OPEN','NEAR_FULL','CLOSED','PUBLISHED')"
   ],
   "foreign_keys": [
    {
     "column": "ProvinceId",
     "ref_table": "Province",
     "ref_column": "ProvinceId"
    },
    {
     "column": "TrainerId",
     "ref_table": "Trainer",
     "ref_column": "TrainerId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Course_Status",
     "columns": [
      "Status",
      "IsDraft"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_Course_Province",
     "columns": [
      "ProvinceId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_Course_Category",
     "columns": [
      "Category",
      "Level"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "ProjectCourse",
   "group": "1.3 Course Catalog",
   "requirement": "REQ-PRC-003/008/009/012/013",
   "columns": [
    {
     "name": "ProjectCourseId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "ProjectId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Project",
      "ref_column": "ProjectId"
     },
     "description": ""
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "ProjectCourseId"
   ],
   "unique": [
    [
     "ProjectId",
     "CourseId"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "ProjectId",
     "ref_table": "Project",
     "ref_column": "ProjectId"
    },
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "CoursePrerequisite",
   "group": "1.3 Course Catalog",
   "requirement": "REQ-PRC-008",
   "columns": [
    {
     "name": "CoursePrerequisiteId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": "หลักสูตรที่มีเงื่อนไข"
    },
    {
     "name": "PrerequisiteCourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": "หลักสูตรที่ต้องผ่านก่อน"
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "CoursePrerequisiteId"
   ],
   "unique": [
    [
     "CourseId",
     "PrerequisiteCourseId"
    ]
   ],
   "checks": [
    "CourseId <> PrerequisiteCourseId"
   ],
   "foreign_keys": [
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "PrerequisiteCourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Project",
   "group": "1.4 Project / Budget",
   "requirement": "REQ-PRC-003/004",
   "columns": [
    {
     "name": "ProjectId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "ProjectCode",
     "type": "varchar(40)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'PJ-2569-01' (human-facing)"
    },
    {
     "name": "Name",
     "type": "nvarchar(500)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อโครงการ"
    },
    {
     "name": "Budget",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "งบประมาณตั้งต้น"
    },
    {
     "name": "Spent",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ใช้จ่ายแล้ว (denormalized)"
    },
    {
     "name": "TargetCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "เป้าหมายผู้เข้าอบรม"
    },
    {
     "name": "EnrolledCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ลงทะเบียนแล้ว (denormalized)"
    },
    {
     "name": "OwnerName",
     "type": "nvarchar(200)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ชื่อผู้รับผิดชอบ (demo free text)"
    },
    {
     "name": "OwnerUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ผู้รับผิดชอบ (ถ้า map ได้)"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ACTIVE/CLOSED/SUSPENDED"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "2-step delete (soft)"
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "ProjectId"
   ],
   "unique": [
    [
     "ProjectCode"
    ]
   ],
   "checks": [
    "Status IN ('ACTIVE','CLOSED','SUSPENDED')"
   ],
   "foreign_keys": [
    {
     "column": "OwnerUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "BudgetCalculation",
   "group": "1.4 Project / Budget",
   "requirement": "REQ-PRC-004",
   "columns": [
    {
     "name": "BudgetCalculationId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "ProjectId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Project",
      "ref_column": "ProjectId"
     },
     "description": ""
    },
    {
     "name": "CourseCost",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ค่าใช้จ่ายโครงการ"
    },
    {
     "name": "AdminCost",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ค่าใช้จ่ายบริหาร"
    },
    {
     "name": "HeadCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนผู้เข้าอบรม (ต้อง > 0)"
    },
    {
     "name": "TotalCost",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "= CourseCost + AdminCost"
    },
    {
     "name": "PerHeadCost",
     "type": "decimal(15,2)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "= TotalCost / HeadCount (snapshot, คำนวณที่ app)"
    },
    {
     "name": "CalculatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "เวลาที่กดยืนยัน"
    },
    {
     "name": "ConfirmedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ผู้กดยืนยัน"
    },
    {
     "name": "Note",
     "type": "nvarchar(500)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "BudgetCalculationId"
   ],
   "unique": [],
   "checks": [
    "HeadCount > 0"
   ],
   "foreign_keys": [
    {
     "column": "ProjectId",
     "ref_table": "Project",
     "ref_column": "ProjectId"
    },
    {
     "column": "ConfirmedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Trainer",
   "group": "1.5 Trainer",
   "requirement": "REQ-PRC-003/013",
   "columns": [
    {
     "name": "TrainerId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Name",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อ-สกุล"
    },
    {
     "name": "OrgUnitId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "OrgUnit",
      "ref_column": "OrgUnitId"
     },
     "description": "สังกัด"
    },
    {
     "name": "OrgText",
     "type": "nvarchar(300)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "สังกัด (free text fallback)"
    },
    {
     "name": "Education",
     "type": "nvarchar(500)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วุฒิการศึกษา"
    },
    {
     "name": "Phone",
     "type": "varchar(40)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "LineId",
     "type": "varchar(100)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "LINE"
    },
    {
     "name": "TotalHours",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชั่วโมงสอนสะสม (denormalized)"
    },
    {
     "name": "CourseCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนหลักสูตร (denormalized)"
    },
    {
     "name": "BadgeColor",
     "type": "varchar(20)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "สี avatar"
    },
    {
     "name": "SelfEditEnabled",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "อนุญาตให้แก้ไขข้อมูลตนเอง"
    },
    {
     "name": "HasPendingEdit",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "มีคำขอแก้ไขรออนุมัติ"
    },
    {
     "name": "AppUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "บัญชีผู้ใช้ของวิทยากร (TRAINER-sees-own)"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "TrainerId"
   ],
   "unique": [],
   "checks": [],
   "foreign_keys": [
    {
     "column": "OrgUnitId",
     "ref_table": "OrgUnit",
     "ref_column": "OrgUnitId"
    },
    {
     "column": "AppUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "TrainerSpecialty",
   "group": "1.5 Trainer",
   "requirement": "REQ-PRC-003/013",
   "columns": [
    {
     "name": "TrainerSpecialtyId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "TrainerId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Trainer",
      "ref_column": "TrainerId"
     },
     "description": ""
    },
    {
     "name": "Specialty",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "สาขาเชี่ยวชาญ (free-form skill tag)"
    }
   ],
   "primary_key": [
    "TrainerSpecialtyId"
   ],
   "unique": [
    [
     "TrainerId",
     "Specialty"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "TrainerId",
     "ref_table": "Trainer",
     "ref_column": "TrainerId"
    }
   ],
   "indexes": []
  },
  {
   "name": "TrainerEditRequest",
   "group": "1.5 Trainer",
   "requirement": "REQ-PRC-003",
   "columns": [
    {
     "name": "TrainerEditRequestId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "TrainerId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Trainer",
      "ref_column": "TrainerId"
     },
     "description": ""
    },
    {
     "name": "ProposedJson",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ข้อมูลที่ขอแก้ (JSON diff/snapshot)"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "PENDING/APPROVED/REJECTED"
    },
    {
     "name": "RequestedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ผู้ยื่นคำขอ"
    },
    {
     "name": "RequestedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "ReviewedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ADMIN ผู้พิจารณา"
    },
    {
     "name": "ReviewedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "ReviewNote",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "TrainerEditRequestId"
   ],
   "unique": [],
   "checks": [
    "Status IN ('PENDING','APPROVED','REJECTED')"
   ],
   "foreign_keys": [
    {
     "column": "TrainerId",
     "ref_table": "Trainer",
     "ref_column": "TrainerId"
    },
    {
     "column": "RequestedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "ReviewedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Member",
   "group": "1.6 Member / Alumni",
   "requirement": "REQ-PRC-002/013",
   "columns": [
    {
     "name": "MemberId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "Name",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อ-สกุล"
    },
    {
     "name": "MemberTypeId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "MemberType",
      "ref_column": "MemberTypeId"
     },
     "description": "ประเภท"
    },
    {
     "name": "OrgUnitId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "OrgUnit",
      "ref_column": "OrgUnitId"
     },
     "description": "สังกัด"
    },
    {
     "name": "OrgText",
     "type": "nvarchar(300)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "สังกัด (free text)"
    },
    {
     "name": "ProvinceId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Province",
      "ref_column": "ProvinceId"
     },
     "description": "จังหวัด"
    },
    {
     "name": "Tel",
     "type": "varchar(40)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "Email",
     "type": "nvarchar(150)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "JoinedAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันที่เข้าร่วม"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "soft-delete (REQ-PRC-002)"
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "MemberId"
   ],
   "unique": [],
   "checks": [],
   "foreign_keys": [
    {
     "column": "MemberTypeId",
     "ref_table": "MemberType",
     "ref_column": "MemberTypeId"
    },
    {
     "column": "OrgUnitId",
     "ref_table": "OrgUnit",
     "ref_column": "OrgUnitId"
    },
    {
     "column": "ProvinceId",
     "ref_table": "Province",
     "ref_column": "ProvinceId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Member_Type",
     "columns": [
      "MemberTypeId",
      "ProvinceId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "Enrollment",
   "group": "1.6 Member / Alumni",
   "requirement": "REQ-PRC-002/013",
   "columns": [
    {
     "name": "EnrollmentId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "MemberId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Member",
      "ref_column": "MemberId"
     },
     "description": ""
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": ""
    },
    {
     "name": "BatchId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Batch",
      "ref_column": "BatchId"
     },
     "description": "รุ่นที่เข้า (REQ-013)"
    },
    {
     "name": "EnrolledAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "EnrollmentId"
   ],
   "unique": [
    [
     "MemberId",
     "CourseId",
     "BatchId"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "MemberId",
     "ref_table": "Member",
     "ref_column": "MemberId"
    },
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "BatchId",
     "ref_table": "Batch",
     "ref_column": "BatchId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Enrollment_Member",
     "columns": [
      "MemberId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_Enrollment_Course",
     "columns": [
      "CourseId",
      "BatchId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "Registration",
   "group": "1.7 Registration & Approval",
   "requirement": "REQ-PRC-008/010",
   "columns": [
    {
     "name": "RegistrationId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "RegistrationNo",
     "type": "varchar(40)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'REG-2569-1801' (human-facing)"
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": ""
    },
    {
     "name": "ApplicantName",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อผู้สมัคร (อาจยังไม่ใช่ Member)"
    },
    {
     "name": "MemberTypeId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "MemberType",
      "ref_column": "MemberTypeId"
     },
     "description": "ประเภทผู้สมัคร"
    },
    {
     "name": "MemberId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Member",
      "ref_column": "MemberId"
     },
     "description": "ผูก Member (หลังอนุมัติ/ถ้ามี)"
    },
    {
     "name": "Email",
     "type": "nvarchar(150)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "อีเมลติดต่อ"
    },
    {
     "name": "Channel",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "WEB_PORTAL/WALKIN/EMAIL/PHONE"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "PENDING/APPROVED/REJECTED/NEEDS_FIX"
    },
    {
     "name": "HasDocs",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "แนบเอกสารครบ"
    },
    {
     "name": "EmailSent",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ส่งอีเมลแจ้งผลแล้ว (denormalized)"
    },
    {
     "name": "SubmittedAt",
     "type": "date",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "วันยื่น"
    },
    {
     "name": "ReviewedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "OFFICER_KSS ผู้พิจารณา"
    },
    {
     "name": "ReviewedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "ReviewNote",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "เหตุผลปฏิเสธ/ขอแก้ไข"
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "RegistrationId"
   ],
   "unique": [
    [
     "RegistrationNo"
    ]
   ],
   "checks": [
    "Channel IN ('WEB_PORTAL','WALKIN','EMAIL','PHONE')",
    "Status IN ('PENDING','APPROVED','REJECTED','NEEDS_FIX')"
   ],
   "foreign_keys": [
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "MemberTypeId",
     "ref_table": "MemberType",
     "ref_column": "MemberTypeId"
    },
    {
     "column": "MemberId",
     "ref_table": "Member",
     "ref_column": "MemberId"
    },
    {
     "column": "ReviewedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Registration_Status",
     "columns": [
      "Status",
      "SubmittedAt"
     ],
     "filter": null,
     "unique": false
    },
    {
     "name": "IX_PRC_Registration_Course",
     "columns": [
      "CourseId"
     ],
     "filter": null,
     "unique": false
    },
    {
     "name": "IX_PRC_Registration_Submitted",
     "columns": [
      "SubmittedAt"
     ],
     "filter": null,
     "unique": false
    }
   ]
  },
  {
   "name": "Batch",
   "group": "1.8 Batch",
   "requirement": "REQ-PRC-013",
   "columns": [
    {
     "name": "BatchId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": ""
    },
    {
     "name": "BatchNo",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "เลขรุ่น"
    },
    {
     "name": "YearBE",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ปี พ.ศ. (label ตาม demo — ดู cross-cutting)"
    },
    {
     "name": "StartAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันเริ่มรุ่น"
    },
    {
     "name": "EndAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันจบรุ่น"
    },
    {
     "name": "TargetCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "เป้าหมาย"
    },
    {
     "name": "CompletedCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนผ่าน (denormalized)"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "BatchId"
   ],
   "unique": [
    [
     "CourseId",
     "BatchNo"
    ]
   ],
   "checks": [],
   "foreign_keys": [
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Certificate",
   "group": "1.9 Certificate",
   "requirement": "REQ-PRC-013/014",
   "columns": [
    {
     "name": "CertificateId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "CertificateNo",
     "type": "varchar(40)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'CT-2569-0001'"
    },
    {
     "name": "CourseId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Course",
      "ref_column": "CourseId"
     },
     "description": ""
    },
    {
     "name": "MemberId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Member",
      "ref_column": "MemberId"
     },
     "description": ""
    },
    {
     "name": "BatchId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Batch",
      "ref_column": "BatchId"
     },
     "description": "รุ่น"
    },
    {
     "name": "RecipientName",
     "type": "nvarchar(200)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อบนใบ (snapshot)"
    },
    {
     "name": "Score",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "คะแนน 0-100"
    },
    {
     "name": "Result",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "PASS/FAIL (ผ่านเกณฑ์/ไม่ผ่านเกณฑ์)"
    },
    {
     "name": "IssuedAt",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันออก (NULL ถ้ายังไม่ออก/FAIL)"
    },
    {
     "name": "IsOriginalIssued",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ออกฉบับต้นฉบับแล้ว"
    },
    {
     "name": "ReprintCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนพิมพ์ซ้ำ (>0 => watermark 'สำเนา')"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "CertificateId"
   ],
   "unique": [
    [
     "CertificateNo"
    ]
   ],
   "checks": [
    "Score IS NULL OR Score BETWEEN 0 AND 100",
    "Result IN ('PASS','FAIL')"
   ],
   "foreign_keys": [
    {
     "column": "CourseId",
     "ref_table": "Course",
     "ref_column": "CourseId"
    },
    {
     "column": "MemberId",
     "ref_table": "Member",
     "ref_column": "MemberId"
    },
    {
     "column": "BatchId",
     "ref_table": "Batch",
     "ref_column": "BatchId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Certificate_Course",
     "columns": [
      "CourseId",
      "BatchId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_Certificate_Member",
     "columns": [
      "MemberId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "CertificatePrintLog",
   "group": "1.9 Certificate",
   "requirement": "REQ-PRC-014",
   "columns": [
    {
     "name": "Id",
     "type": "bigint",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "CertificateId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Certificate",
      "ref_column": "CertificateId"
     },
     "description": ""
    },
    {
     "name": "PrintType",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ORIGINAL/COPY (ต้นฉบับ/สำเนา)"
    },
    {
     "name": "HasWatermark",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ประทับลายน้ำ 'สำเนา' (COPY => 1)"
    },
    {
     "name": "PrintedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "PrintedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "Id"
   ],
   "unique": [],
   "checks": [
    "PrintType IN ('ORIGINAL','COPY')"
   ],
   "foreign_keys": [
    {
     "column": "CertificateId",
     "ref_table": "Certificate",
     "ref_column": "CertificateId"
    },
    {
     "column": "PrintedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "Equipment",
   "group": "1.10 Equipment",
   "requirement": "REQ-PRC-005",
   "columns": [
    {
     "name": "EquipmentId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "EquipmentCode",
     "type": "varchar(40)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "'RLPD-PROJ-001'"
    },
    {
     "name": "Name",
     "type": "nvarchar(500)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อครุภัณฑ์"
    },
    {
     "name": "ResponsibleName",
     "type": "nvarchar(200)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ผู้รับผิดชอบ (demo free text)"
    },
    {
     "name": "ResponsibleUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ผู้รับผิดชอบ (ถ้า map)"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ACTIVE/RETURNED/DAMAGED/REPLACING (ใช้งาน/ส่งคืน/ชำรุด/อยู่ระหว่างทดแทน)"
    },
    {
     "name": "AcquiredAt",
     "type": "date",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "วันได้มา (ใช้คำนวณอายุ 5 ปี)"
    },
    {
     "name": "Value",
     "type": "decimal(15,2)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "มูลค่า"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "EquipmentId"
   ],
   "unique": [
    [
     "EquipmentCode"
    ]
   ],
   "checks": [
    "Status IN ('ACTIVE','RETURNED','DAMAGED','REPLACING')"
   ],
   "foreign_keys": [
    {
     "column": "ResponsibleUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Equipment_Status",
     "columns": [
      "Status"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_Equipment_Acquired",
     "columns": [
      "AcquiredAt"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "EquipmentOwnershipHistory",
   "group": "1.10 Equipment",
   "requirement": "REQ-PRC-005",
   "columns": [
    {
     "name": "Id",
     "type": "bigint",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "EquipmentId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Equipment",
      "ref_column": "EquipmentId"
     },
     "description": ""
    },
    {
     "name": "FromResponsible",
     "type": "nvarchar(200)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ผู้รับผิดชอบเดิม"
    },
    {
     "name": "ToResponsible",
     "type": "nvarchar(200)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ผู้รับผิดชอบใหม่"
    },
    {
     "name": "FromUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "ToUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "ChangedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "ChangedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "Note",
     "type": "nvarchar(500)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "Id"
   ],
   "unique": [],
   "checks": [],
   "foreign_keys": [
    {
     "column": "EquipmentId",
     "ref_table": "Equipment",
     "ref_column": "EquipmentId"
    },
    {
     "column": "FromUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "ToUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "ChangedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": []
  },
  {
   "name": "KnowledgeReport",
   "group": "1.11 Knowledge Dissemination",
   "requirement": "REQ-PRC-006",
   "columns": [
    {
     "name": "KnowledgeReportId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "KnowledgeTypeId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "KnowledgeType",
      "ref_column": "KnowledgeTypeId"
     },
     "description": "ประเภทสื่อ"
    },
    {
     "name": "Title",
     "type": "nvarchar(500)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อเรื่อง"
    },
    {
     "name": "ItemCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวนชิ้น"
    },
    {
     "name": "ByName",
     "type": "nvarchar(300)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ผู้จัดทำ"
    },
    {
     "name": "OrgUnitId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "OrgUnit",
      "ref_column": "OrgUnitId"
     },
     "description": "หน่วยงาน"
    },
    {
     "name": "OrgText",
     "type": "nvarchar(300)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "หน่วยงาน (free text)"
    },
    {
     "name": "ProvinceId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Province",
      "ref_column": "ProvinceId"
     },
     "description": "จังหวัด (อาจ '-')"
    },
    {
     "name": "ReportDate",
     "type": "date",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "วันที่"
    },
    {
     "name": "Link",
     "type": "nvarchar(1000)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ลิงก์"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "PENDING/APPROVED/NEEDS_FIX (รอแก้ไข/อนุมัติแล้ว)"
    },
    {
     "name": "FlagNote",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "หมายเหตุที่ ADMIN flag"
    },
    {
     "name": "FlaggedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ADMIN ผู้ flag"
    },
    {
     "name": "SubmittedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "OFFICER_OTHER (data-scoping: sees-own)"
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "KnowledgeReportId"
   ],
   "unique": [],
   "checks": [
    "Status IN ('PENDING','APPROVED','NEEDS_FIX')"
   ],
   "foreign_keys": [
    {
     "column": "KnowledgeTypeId",
     "ref_table": "KnowledgeType",
     "ref_column": "KnowledgeTypeId"
    },
    {
     "column": "OrgUnitId",
     "ref_table": "OrgUnit",
     "ref_column": "OrgUnitId"
    },
    {
     "column": "ProvinceId",
     "ref_table": "Province",
     "ref_column": "ProvinceId"
    },
    {
     "column": "SubmittedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "FlaggedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_KnowledgeReport_Status",
     "columns": [
      "Status",
      "ReportDate"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    },
    {
     "name": "IX_PRC_KnowledgeReport_Submitter",
     "columns": [
      "SubmittedBy"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  },
  {
   "name": "EmailNotification",
   "group": "1.12 Notification / Email",
   "requirement": "REQ-PRC-010",
   "columns": [
    {
     "name": "EmailNotificationId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "RegistrationId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "Registration",
      "ref_column": "RegistrationId"
     },
     "description": ""
    },
    {
     "name": "ToAddress",
     "type": "nvarchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ผู้รับ"
    },
    {
     "name": "Subject",
     "type": "nvarchar(500)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "หัวเรื่อง"
    },
    {
     "name": "Body",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "เนื้อหา"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "PENDING/SENT/FAILED/BOUNCED"
    },
    {
     "name": "RetryCount",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "จำนวน retry (0..MaxRetry)"
    },
    {
     "name": "MaxRetry",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "เพดาน retry (retry 3x)"
    },
    {
     "name": "LastAttemptAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "SentAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "เวลาส่งสำเร็จ (NULL ถ้ายังไม่สำเร็จ/bounced)"
    },
    {
     "name": "NextRetryAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "กำหนด retry ครั้งถัดไป (backoff)"
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "UpdatedAt",
     "type": "datetime2",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UpdatedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    }
   ],
   "primary_key": [
    "EmailNotificationId"
   ],
   "unique": [],
   "checks": [
    "Status IN ('PENDING','SENT','FAILED','BOUNCED')",
    "RetryCount >= 0 AND RetryCount <= MaxRetry"
   ],
   "foreign_keys": [
    {
     "column": "RegistrationId",
     "ref_table": "Registration",
     "ref_column": "RegistrationId"
    },
    {
     "column": "CreatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    },
    {
     "column": "UpdatedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_EmailNotification_Status",
     "columns": [
      "Status",
      "NextRetryAt"
     ],
     "filter": null,
     "unique": false
    }
   ]
  },
  {
   "name": "EmailAttempt",
   "group": "1.12 Notification / Email",
   "requirement": "REQ-PRC-010",
   "columns": [
    {
     "name": "Id",
     "type": "bigint",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "EmailNotificationId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "EmailNotification",
      "ref_column": "EmailNotificationId"
     },
     "description": ""
    },
    {
     "name": "AttemptNo",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ครั้งที่ 1..3"
    },
    {
     "name": "Status",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "SENT/FAILED/BOUNCED"
    },
    {
     "name": "ErrorMessage",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ข้อความ error จาก SMTP"
    },
    {
     "name": "AttemptedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "Id"
   ],
   "unique": [],
   "checks": [
    "Status IN ('SENT','FAILED','BOUNCED')"
   ],
   "foreign_keys": [
    {
     "column": "EmailNotificationId",
     "ref_table": "EmailNotification",
     "ref_column": "EmailNotificationId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_EmailAttempt_Notification",
     "columns": [
      "EmailNotificationId"
     ],
     "filter": null,
     "unique": false
    }
   ]
  },
  {
   "name": "AuditLog",
   "group": "1.13 Audit",
   "requirement": "REQ-PRC-014",
   "columns": [
    {
     "name": "Id",
     "type": "bigint",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "ActorUserId",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": "ผู้กระทำ (NULL = system)"
    },
    {
     "name": "ActorName",
     "type": "nvarchar(200)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "ชื่อผู้กระทำ (denormalized snapshot; 'system')"
    },
    {
     "name": "ActorRole",
     "type": "varchar(30)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "บทบาทขณะกระทำ (denormalized)"
    },
    {
     "name": "Action",
     "type": "nvarchar(300)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "การกระทำ (Thai free text)"
    },
    {
     "name": "EntityType",
     "type": "varchar(50)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "'TRAINER','PROJECT','CERTIFICATE','REGISTRATION','EQUIPMENT','EMAIL','DASHBOARD'"
    },
    {
     "name": "EntityId",
     "type": "varchar(50)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "id/code ของ target (รับได้ทั้ง int และ business code)"
    },
    {
     "name": "Detail",
     "type": "nvarchar(max)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "รายละเอียด/JSON"
    },
    {
     "name": "ClientIp",
     "type": "varchar(50)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "CreatedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "Id"
   ],
   "unique": [],
   "checks": [],
   "foreign_keys": [
    {
     "column": "ActorUserId",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_AuditLog_Entity",
     "columns": [
      "EntityType",
      "EntityId"
     ],
     "filter": null,
     "unique": false
    },
    {
     "name": "IX_PRC_AuditLog_Time",
     "columns": [
      "CreatedAt"
     ],
     "filter": null,
     "unique": false
    }
   ]
  },
  {
   "name": "Attachment",
   "group": "1.14 File Attachment (polymorphic)",
   "requirement": "REQ-PRC-003",
   "columns": [
    {
     "name": "AttachmentId",
     "type": "int",
     "nullable": false,
     "pk": true,
     "identity": true,
     "description": "รหัส (PK)"
    },
    {
     "name": "OwnerEntityType",
     "type": "varchar(50)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "COURSE/PROJECT/TRAINER/REGISTRATION/KNOWLEDGE_REPORT/MEMBER"
    },
    {
     "name": "OwnerEntityId",
     "type": "int",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "running id ของ entity เจ้าของ (polymorphic, ไม่มี DB-level FK)"
    },
    {
     "name": "FileName",
     "type": "nvarchar(255)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อไฟล์ที่จัดเก็บ"
    },
    {
     "name": "OriginalName",
     "type": "nvarchar(255)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชื่อไฟล์ต้นฉบับ"
    },
    {
     "name": "MimeType",
     "type": "varchar(150)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ชนิด MIME"
    },
    {
     "name": "Extension",
     "type": "varchar(20)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "doc/docx/xls/xlsx/ppt/pdf/jpeg"
    },
    {
     "name": "FileSize",
     "type": "bigint",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "ขนาด byte (<= 50MB)"
    },
    {
     "name": "Sha256",
     "type": "varchar(64)",
     "nullable": true,
     "pk": false,
     "identity": false,
     "description": "checksum สำหรับ dedupe/integrity"
    },
    {
     "name": "StoragePath",
     "type": "nvarchar(1000)",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": "path/key ที่เก็บไฟล์"
    },
    {
     "name": "UploadedAt",
     "type": "datetime2",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    },
    {
     "name": "UploadedBy",
     "type": "int",
     "nullable": true,
     "pk": false,
     "identity": false,
     "fk": {
      "ref_table": "AppUser",
      "ref_column": "AppUserId"
     },
     "description": ""
    },
    {
     "name": "IsDeleted",
     "type": "bit",
     "nullable": false,
     "pk": false,
     "identity": false,
     "description": ""
    }
   ],
   "primary_key": [
    "AttachmentId"
   ],
   "unique": [],
   "checks": [
    "OwnerEntityType IN ('COURSE','PROJECT','TRAINER','REGISTRATION','KNOWLEDGE_REPORT','MEMBER')",
    "Extension IN ('doc','docx','xls','xlsx','ppt','pdf','jpeg')",
    "FileSize <= 52428800"
   ],
   "foreign_keys": [
    {
     "column": "UploadedBy",
     "ref_table": "AppUser",
     "ref_column": "AppUserId"
    }
   ],
   "indexes": [
    {
     "name": "IX_PRC_Attachment_Owner",
     "columns": [
      "OwnerEntityType",
      "OwnerEntityId"
     ],
     "filter": "IsDeleted = 0",
     "unique": false
    }
   ]
  }
 ]
}
