ข้ามไปที่เนื้อหา

S3 - Activity Report & Course Registration (PRC) - Data Dictionary (Target Design)

TARGET DESIGN — ไม่ใช่ schema ปัจจุบัน

ทุกตาราง/ทุกคอลัมน์ (สร้างจาก schema.sql ซึ่งเป็น single source of truth) · ภาพรวม + Traceability · Schema JSON

มาตรฐานทุกตาราง: PK = int IDENTITY(1,1) เว้นแต่ตาราง log = bigint IDENTITY(1,1) · ข้อความไทย = nvarchar / โค้ด/enum = varchar · audit CreatedAt/CreatedBy/UpdatedAt/UpdatedBy (CreatedBy/UpdatedBy เป็น int FK → PRC.AppUser) · soft delete IsDeleted เฉพาะตาราง business · append-only log ไม่มี Updated*/IsDeleted

Authorization รวมศูนย์

Auth = thin mirror — ไม่มีคอลัมน์ password · identity มาจาก SSO กลางผ่าน JWT · PRC.AppUser/PRC.RoleAssignment/PRC.Role เก็บแค่ mirror ของผู้ใช้/บทบาท/การมอบสิทธิ์

1.1 Lookups (master/reference)

Province

Column Data Type Constraints Description
ProvinceId int PK, IDENTITY, NOT NULL
Code varchar(10) NOT NULL, UNIQUE รหัสย่อจังหวัด ('BKK','CMI')
NameTh nvarchar(150) NOT NULL ชื่อจังหวัดภาษาไทย
NameEn nvarchar(150) ชื่อจังหวัดภาษาอังกฤษ
Region nvarchar(50) ภูมิภาค (เหนือ/อีสาน/กลาง/ใต้)
MapX decimal(6,2) พิกัด X บน SVG silhouette (heatmap)
MapY decimal(6,2) พิกัด Y บน SVG silhouette (heatmap)
Sequence int DEFAULT 0, NOT NULL ลำดับแสดง
IsActive bit DEFAULT 1, NOT NULL สถานะใช้งาน

MemberType

Column Data Type Constraints Description
MemberTypeId int PK, IDENTITY, NOT NULL
Code varchar(30) NOT NULL, UNIQUE GOV/BUSINESS/YOUTH/TEACHER/CITIZEN
NameTh nvarchar(150) NOT NULL 'เจ้าหน้าที่รัฐ','ภาคธุรกิจ','เยาวชน','ครู/บุคลากรการศึกษา','ประชาชน'
Sequence int DEFAULT 0, NOT NULL
IsActive bit DEFAULT 1, NOT NULL

KnowledgeType

Column Data Type Constraints Description
KnowledgeTypeId int PK, IDENTITY, NOT NULL
Code varchar(30) NOT NULL, UNIQUE ARTICLE/VIDEO/INFOGRAPHIC/SOCIAL/SEMINAR
NameTh nvarchar(150) NOT NULL 'บทความ','วิดีโอ','Infographic','สื่อสังคมออนไลน์','การอบรม/สัมมนา'
Sequence int DEFAULT 0, NOT NULL
IsActive bit DEFAULT 1, NOT NULL

OrgUnit

Column Data Type Constraints Description
OrgUnitId int PK, IDENTITY, NOT NULL
Code varchar(50) UNIQUE รหัสกอง ('KSS','KPS')
NameTh nvarchar(300) NOT NULL ชื่อหน่วยงาน
ParentOrgUnitId int กองแม่ (self-ref)
IsInternal bit DEFAULT 1, NOT NULL ภายในกรมฯ vs ภายนอก
IsActive bit DEFAULT 1, NOT NULL

Foreign Keys: ParentOrgUnitIdPRC.OrgUnit(OrgUnitId)

Role

Column Data Type Constraints Description
RoleId int PK, IDENTITY, NOT NULL
Code varchar(30) NOT NULL, UNIQUE ADMIN/OFFICER_KSS/OFFICER_OTHER/TRAINER/VIEWER/CITIZEN
NameTh nvarchar(150) NOT NULL ป้ายชื่อบทบาท
Description nvarchar(500) คำอธิบายสิทธิ์
Sequence int DEFAULT 0, NOT NULL
IsActive bit DEFAULT 1, NOT NULL

1.2 Identity / Auth (thin mirror)

AppUser

Column Data Type Constraints Description
AppUserId int PK, IDENTITY, NOT NULL
ExternalSubject varchar(255) NOT NULL, UNIQUE OIDC 'sub' / Keycloak UUID / AD sAMAccountName / ThaiD pairwise
AuthSource varchar(20) DEFAULT 'AD', NOT NULL, CHECK IN ('AD','KEYCLOAK','THAID') AD / KEYCLOAK / THAID
Username nvarchar(255) mirrors SSO username (unique เมื่อ not null — ดู IX section)
DisplayName nvarchar(200) NOT NULL ชื่อ-สกุลแสดงผล
Email nvarchar(150) อีเมล (จาก token claim)
Phone varchar(30) เบอร์ติดต่อ
OrgUnitId int สังกัด (data-scoping default)
TrainerId int ถ้า user เป็นวิทยากร -> ผูก Trainer (TRAINER-sees-own)
MemberId int ถ้า user เป็น CITIZEN/ศิษย์เก่า -> ผูก Member
IsActive bit DEFAULT 1, NOT NULL active flag
LastLoginAt datetime2
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: OrgUnitIdPRC.OrgUnit(OrgUnitId); TrainerIdPRC.Trainer(TrainerId); MemberIdPRC.Member(MemberId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

RoleAssignment

Column Data Type Constraints Description
RoleAssignmentId int PK, IDENTITY, NOT NULL
AppUserId int NOT NULL, UNIQUE (AppUserId, RoleId)
RoleId int NOT NULL, UNIQUE (AppUserId, RoleId)
GrantedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
GrantedBy int ADMIN ผู้มอบสิทธิ์
IsActive bit DEFAULT 1, NOT NULL

Foreign Keys: AppUserIdPRC.AppUser(AppUserId); RoleIdPRC.Role(RoleId); GrantedByPRC.AppUser(AppUserId)

1.3 Course Catalog

Course

Column Data Type Constraints Description
CourseId int PK, IDENTITY, NOT NULL
CourseCode varchar(40) NOT NULL, UNIQUE รหัสหลักสูตร human-facing ('HR-LDR-2569')
Title nvarchar(500) NOT NULL ชื่อหลักสูตร
Category varchar(20) NOT NULL, CHECK IN ('EXECUTIVE','PROJECT') EXECUTIVE / PROJECT (REQ-009)
Level varchar(20) NOT NULL, CHECK IN ('BASIC','INTER','ADV') BASIC / INTER / ADV = ต้น/กลาง/สูง (REQ-013)
Hours int DEFAULT 0, NOT NULL จำนวนชั่วโมง
Mode varchar(20) NOT NULL, CHECK IN ('ONSITE','ONLINE','HYBRID') ONSITE / ONLINE / HYBRID (REQ-012)
ProvinceId int จังหวัดจัดอบรม (heatmap)
OnsiteVenue nvarchar(500) สถานที่จริง (ONSITE/HYBRID)
OnlineUrl nvarchar(1000) URL ห้องออนไลน์ (ONLINE/HYBRID; เก็บคู่ onsite ได้ — REQ-012)
Status varchar(20) DEFAULT 'DRAFT', NOT NULL, CHECK IN ('DRAFT','OPEN','NEAR_FULL','CLOSED','PUBLISHED') DRAFT/OPEN/NEAR_FULL/CLOSED/PUBLISHED
IsDraft bit DEFAULT 1, NOT NULL ฉบับร่าง (draft/publish — REQ-008)
TargetCount int DEFAULT 0, NOT NULL จำนวนเป้าหมาย
EnrolledCount int DEFAULT 0, NOT NULL จำนวนที่ลงทะเบียนแล้ว (denormalized counter)
OpenAt date วันเปิดรับสมัคร
CloseAt date วันปิดรับสมัคร
StartAt date วันเริ่มอบรม
CoverColor varchar(20) สีปก (#hex)
TrainerId int วิทยากรหลัก
Objective nvarchar(max) วัตถุประสงค์
HasCert bit DEFAULT 0, NOT NULL ออกประกาศนียบัตรหรือไม่
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: ProvinceIdPRC.Province(ProvinceId); TrainerIdPRC.Trainer(TrainerId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

ProjectCourse

Column Data Type Constraints Description
ProjectCourseId int PK, IDENTITY, NOT NULL
ProjectId int NOT NULL, UNIQUE (ProjectId, CourseId)
CourseId int NOT NULL, UNIQUE (ProjectId, CourseId)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int

Foreign Keys: ProjectIdPRC.Project(ProjectId); CourseIdPRC.Course(CourseId); CreatedByPRC.AppUser(AppUserId)

CoursePrerequisite

Column Data Type Constraints Description
CoursePrerequisiteId int PK, IDENTITY, NOT NULL
CourseId int NOT NULL, UNIQUE (CourseId, PrerequisiteCourseId) หลักสูตรที่มีเงื่อนไข
PrerequisiteCourseId int NOT NULL, UNIQUE (CourseId, PrerequisiteCourseId), CHECK (CourseId <> PrerequisiteCourseId) หลักสูตรที่ต้องผ่านก่อน
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int

Foreign Keys: CourseIdPRC.Course(CourseId); PrerequisiteCourseIdPRC.Course(CourseId); CreatedByPRC.AppUser(AppUserId)

1.4 Project / Budget

Project

Column Data Type Constraints Description
ProjectId int PK, IDENTITY, NOT NULL
ProjectCode varchar(40) NOT NULL, UNIQUE 'PJ-2569-01' (human-facing)
Name nvarchar(500) NOT NULL ชื่อโครงการ
Budget decimal(15,2) DEFAULT 0, NOT NULL งบประมาณตั้งต้น
Spent decimal(15,2) DEFAULT 0, NOT NULL ใช้จ่ายแล้ว (denormalized)
TargetCount int DEFAULT 0, NOT NULL เป้าหมายผู้เข้าอบรม
EnrolledCount int DEFAULT 0, NOT NULL ลงทะเบียนแล้ว (denormalized)
OwnerName nvarchar(200) ชื่อผู้รับผิดชอบ (demo free text)
OwnerUserId int ผู้รับผิดชอบ (ถ้า map ได้)
Status varchar(20) DEFAULT 'ACTIVE', NOT NULL, CHECK IN ('ACTIVE','CLOSED','SUSPENDED') ACTIVE/CLOSED/SUSPENDED
IsDeleted bit DEFAULT 0, NOT NULL 2-step delete (soft)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: OwnerUserIdPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

BudgetCalculation

Column Data Type Constraints Description
BudgetCalculationId int PK, IDENTITY, NOT NULL
ProjectId int NOT NULL
CourseCost decimal(15,2) DEFAULT 0, NOT NULL ค่าใช้จ่ายโครงการ
AdminCost decimal(15,2) DEFAULT 0, NOT NULL ค่าใช้จ่ายบริหาร
HeadCount int NOT NULL, CHECK (HeadCount > 0) จำนวนผู้เข้าอบรม (ต้อง > 0)
TotalCost decimal(15,2) NOT NULL = CourseCost + AdminCost
PerHeadCost decimal(15,2) NOT NULL = TotalCost / HeadCount (snapshot, คำนวณที่ app)
CalculatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL เวลาที่กดยืนยัน
ConfirmedBy int ผู้กดยืนยัน
Note nvarchar(500)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: ProjectIdPRC.Project(ProjectId); ConfirmedByPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.5 Trainer

Trainer

Column Data Type Constraints Description
TrainerId int PK, IDENTITY, NOT NULL
Name nvarchar(200) NOT NULL ชื่อ-สกุล
OrgUnitId int สังกัด
OrgText nvarchar(300) สังกัด (free text fallback)
Education nvarchar(500) วุฒิการศึกษา
Phone varchar(40)
LineId varchar(100) LINE
TotalHours int DEFAULT 0, NOT NULL ชั่วโมงสอนสะสม (denormalized)
CourseCount int DEFAULT 0, NOT NULL จำนวนหลักสูตร (denormalized)
BadgeColor varchar(20) สี avatar
SelfEditEnabled bit DEFAULT 0, NOT NULL อนุญาตให้แก้ไขข้อมูลตนเอง
HasPendingEdit bit DEFAULT 0, NOT NULL มีคำขอแก้ไขรออนุมัติ
AppUserId int บัญชีผู้ใช้ของวิทยากร (TRAINER-sees-own)
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: OrgUnitIdPRC.OrgUnit(OrgUnitId); AppUserIdPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

TrainerSpecialty

Column Data Type Constraints Description
TrainerSpecialtyId int PK, IDENTITY, NOT NULL
TrainerId int NOT NULL, UNIQUE (TrainerId, Specialty)
Specialty nvarchar(200) NOT NULL, UNIQUE (TrainerId, Specialty) สาขาเชี่ยวชาญ (free-form skill tag)

Foreign Keys: TrainerIdPRC.Trainer(TrainerId)

TrainerEditRequest

Column Data Type Constraints Description
TrainerEditRequestId int PK, IDENTITY, NOT NULL
TrainerId int NOT NULL
ProposedJson nvarchar(max) ข้อมูลที่ขอแก้ (JSON diff/snapshot)
Status varchar(20) DEFAULT 'PENDING', NOT NULL, CHECK IN ('PENDING','APPROVED','REJECTED') PENDING/APPROVED/REJECTED
RequestedBy int ผู้ยื่นคำขอ
RequestedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
ReviewedBy int ADMIN ผู้พิจารณา
ReviewedAt datetime2
ReviewNote nvarchar(max)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: TrainerIdPRC.Trainer(TrainerId); RequestedByPRC.AppUser(AppUserId); ReviewedByPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.6 Member / Alumni

Member

Column Data Type Constraints Description
MemberId int PK, IDENTITY, NOT NULL
Name nvarchar(200) NOT NULL ชื่อ-สกุล
MemberTypeId int NOT NULL ประเภท
OrgUnitId int สังกัด
OrgText nvarchar(300) สังกัด (free text)
ProvinceId int จังหวัด
Tel varchar(40)
Email nvarchar(150)
JoinedAt date วันที่เข้าร่วม
IsDeleted bit DEFAULT 0, NOT NULL soft-delete (REQ-PRC-002)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: MemberTypeIdPRC.MemberType(MemberTypeId); OrgUnitIdPRC.OrgUnit(OrgUnitId); ProvinceIdPRC.Province(ProvinceId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

Enrollment

Column Data Type Constraints Description
EnrollmentId int PK, IDENTITY, NOT NULL
MemberId int NOT NULL, UNIQUE (MemberId, CourseId, BatchId)
CourseId int NOT NULL, UNIQUE (MemberId, CourseId, BatchId)
BatchId int UNIQUE (MemberId, CourseId, BatchId) รุ่นที่เข้า (REQ-013)
EnrolledAt date
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: MemberIdPRC.Member(MemberId); CourseIdPRC.Course(CourseId); BatchIdPRC.Batch(BatchId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.7 Registration & Approval

Registration

Column Data Type Constraints Description
RegistrationId int PK, IDENTITY, NOT NULL
RegistrationNo varchar(40) NOT NULL, UNIQUE 'REG-2569-1801' (human-facing)
CourseId int NOT NULL
ApplicantName nvarchar(200) NOT NULL ชื่อผู้สมัคร (อาจยังไม่ใช่ Member)
MemberTypeId int ประเภทผู้สมัคร
MemberId int ผูก Member (หลังอนุมัติ/ถ้ามี)
Email nvarchar(150) อีเมลติดต่อ
Channel varchar(20) DEFAULT 'WEB_PORTAL', NOT NULL, CHECK IN ('WEB_PORTAL','WALKIN','EMAIL','PHONE') WEB_PORTAL/WALKIN/EMAIL/PHONE
Status varchar(20) DEFAULT 'PENDING', NOT NULL, CHECK IN ('PENDING','APPROVED','REJECTED','NEEDS_FIX') PENDING/APPROVED/REJECTED/NEEDS_FIX
HasDocs bit DEFAULT 0, NOT NULL แนบเอกสารครบ
EmailSent bit DEFAULT 0, NOT NULL ส่งอีเมลแจ้งผลแล้ว (denormalized)
SubmittedAt date NOT NULL วันยื่น
ReviewedBy int OFFICER_KSS ผู้พิจารณา
ReviewedAt datetime2
ReviewNote nvarchar(max) เหตุผลปฏิเสธ/ขอแก้ไข
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: CourseIdPRC.Course(CourseId); MemberTypeIdPRC.MemberType(MemberTypeId); MemberIdPRC.Member(MemberId); ReviewedByPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.8 Batch

Batch

Column Data Type Constraints Description
BatchId int PK, IDENTITY, NOT NULL
CourseId int NOT NULL, UNIQUE (CourseId, BatchNo)
BatchNo int NOT NULL, UNIQUE (CourseId, BatchNo) เลขรุ่น
YearBE int NOT NULL ปี พ.ศ. (label ตาม demo — ดู cross-cutting)
StartAt date วันเริ่มรุ่น
EndAt date วันจบรุ่น
TargetCount int DEFAULT 0, NOT NULL เป้าหมาย
CompletedCount int DEFAULT 0, NOT NULL จำนวนผ่าน (denormalized)
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: CourseIdPRC.Course(CourseId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.9 Certificate

Certificate

Column Data Type Constraints Description
CertificateId int PK, IDENTITY, NOT NULL
CertificateNo varchar(40) NOT NULL, UNIQUE 'CT-2569-0001'
CourseId int NOT NULL
MemberId int NOT NULL
BatchId int รุ่น
RecipientName nvarchar(200) NOT NULL ชื่อบนใบ (snapshot)
Score int CHECK (Score IS NULL OR Score BETWEEN 0 AND 100) คะแนน 0-100
Result varchar(20) NOT NULL, CHECK IN ('PASS','FAIL') PASS/FAIL (ผ่านเกณฑ์/ไม่ผ่านเกณฑ์)
IssuedAt date วันออก (NULL ถ้ายังไม่ออก/FAIL)
IsOriginalIssued bit DEFAULT 0, NOT NULL ออกฉบับต้นฉบับแล้ว
ReprintCount int DEFAULT 0, NOT NULL จำนวนพิมพ์ซ้ำ (>0 => watermark 'สำเนา')
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: CourseIdPRC.Course(CourseId); MemberIdPRC.Member(MemberId); BatchIdPRC.Batch(BatchId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

CertificatePrintLog

Column Data Type Constraints Description
Id bigint PK, IDENTITY, NOT NULL
CertificateId int NOT NULL
PrintType varchar(20) NOT NULL, CHECK IN ('ORIGINAL','COPY') ORIGINAL/COPY (ต้นฉบับ/สำเนา)
HasWatermark bit DEFAULT 0, NOT NULL ประทับลายน้ำ 'สำเนา' (COPY => 1)
PrintedBy int
PrintedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL

Foreign Keys: CertificateIdPRC.Certificate(CertificateId); PrintedByPRC.AppUser(AppUserId)

1.10 Equipment

Equipment

Column Data Type Constraints Description
EquipmentId int PK, IDENTITY, NOT NULL
EquipmentCode varchar(40) NOT NULL, UNIQUE 'RLPD-PROJ-001'
Name nvarchar(500) NOT NULL ชื่อครุภัณฑ์
ResponsibleName nvarchar(200) ผู้รับผิดชอบ (demo free text)
ResponsibleUserId int ผู้รับผิดชอบ (ถ้า map)
Status varchar(20) DEFAULT 'ACTIVE', NOT NULL, CHECK IN ('ACTIVE','RETURNED','DAMAGED','REPLACING') ACTIVE/RETURNED/DAMAGED/REPLACING (ใช้งาน/ส่งคืน/ชำรุด/อยู่ระหว่างทดแทน)
AcquiredAt date NOT NULL วันได้มา (ใช้คำนวณอายุ 5 ปี)
Value decimal(15,2) มูลค่า
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: ResponsibleUserIdPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

EquipmentOwnershipHistory

Column Data Type Constraints Description
Id bigint PK, IDENTITY, NOT NULL
EquipmentId int NOT NULL
FromResponsible nvarchar(200) ผู้รับผิดชอบเดิม
ToResponsible nvarchar(200) ผู้รับผิดชอบใหม่
FromUserId int
ToUserId int
ChangedBy int
ChangedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
Note nvarchar(500)

Foreign Keys: EquipmentIdPRC.Equipment(EquipmentId); FromUserIdPRC.AppUser(AppUserId); ToUserIdPRC.AppUser(AppUserId); ChangedByPRC.AppUser(AppUserId)

1.11 Knowledge Dissemination

KnowledgeReport

Column Data Type Constraints Description
KnowledgeReportId int PK, IDENTITY, NOT NULL
KnowledgeTypeId int NOT NULL ประเภทสื่อ
Title nvarchar(500) NOT NULL ชื่อเรื่อง
ItemCount int DEFAULT 1, NOT NULL จำนวนชิ้น
ByName nvarchar(300) ผู้จัดทำ
OrgUnitId int หน่วยงาน
OrgText nvarchar(300) หน่วยงาน (free text)
ProvinceId int จังหวัด (อาจ '-')
ReportDate date วันที่
Link nvarchar(1000) ลิงก์
Status varchar(20) DEFAULT 'PENDING', NOT NULL, CHECK IN ('PENDING','APPROVED','NEEDS_FIX') PENDING/APPROVED/NEEDS_FIX (รอแก้ไข/อนุมัติแล้ว)
FlagNote nvarchar(max) หมายเหตุที่ ADMIN flag
FlaggedBy int ADMIN ผู้ flag
SubmittedBy int OFFICER_OTHER (data-scoping: sees-own)
IsDeleted bit DEFAULT 0, NOT NULL
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: KnowledgeTypeIdPRC.KnowledgeType(KnowledgeTypeId); OrgUnitIdPRC.OrgUnit(OrgUnitId); ProvinceIdPRC.Province(ProvinceId); SubmittedByPRC.AppUser(AppUserId); FlaggedByPRC.AppUser(AppUserId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

1.12 Notification / Email

EmailNotification

Column Data Type Constraints Description
EmailNotificationId int PK, IDENTITY, NOT NULL
RegistrationId int NOT NULL
ToAddress nvarchar(150) NOT NULL ผู้รับ
Subject nvarchar(500) NOT NULL หัวเรื่อง
Body nvarchar(max) เนื้อหา
Status varchar(20) DEFAULT 'PENDING', NOT NULL, CHECK IN ('PENDING','SENT','FAILED','BOUNCED') PENDING/SENT/FAILED/BOUNCED
RetryCount int DEFAULT 0, NOT NULL, CHECK (RetryCount >= 0 AND RetryCount <= MaxRetry) จำนวน retry (0..MaxRetry)
MaxRetry int DEFAULT 3, NOT NULL เพดาน retry (retry 3x)
LastAttemptAt datetime2
SentAt datetime2 เวลาส่งสำเร็จ (NULL ถ้ายังไม่สำเร็จ/bounced)
NextRetryAt datetime2 กำหนด retry ครั้งถัดไป (backoff)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
CreatedBy int
UpdatedAt datetime2
UpdatedBy int

Foreign Keys: RegistrationIdPRC.Registration(RegistrationId); CreatedByPRC.AppUser(AppUserId); UpdatedByPRC.AppUser(AppUserId)

EmailAttempt

Column Data Type Constraints Description
Id bigint PK, IDENTITY, NOT NULL
EmailNotificationId int NOT NULL
AttemptNo int NOT NULL ครั้งที่ 1..3
Status varchar(20) NOT NULL, CHECK IN ('SENT','FAILED','BOUNCED') SENT/FAILED/BOUNCED
ErrorMessage nvarchar(max) ข้อความ error จาก SMTP
AttemptedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL

Foreign Keys: EmailNotificationIdPRC.EmailNotification(EmailNotificationId)

1.13 Audit

AuditLog

Column Data Type Constraints Description
Id bigint PK, IDENTITY, NOT NULL
ActorUserId int ผู้กระทำ (NULL = system)
ActorName nvarchar(200) ชื่อผู้กระทำ (denormalized snapshot; 'system')
ActorRole varchar(30) บทบาทขณะกระทำ (denormalized)
Action nvarchar(300) NOT NULL การกระทำ (Thai free text)
EntityType varchar(50) 'TRAINER','PROJECT','CERTIFICATE','REGISTRATION','EQUIPMENT','EMAIL','DASHBOARD'
EntityId varchar(50) id/code ของ target (รับได้ทั้ง int และ business code)
Detail nvarchar(max) รายละเอียด/JSON
ClientIp varchar(50)
CreatedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL

Foreign Keys: ActorUserIdPRC.AppUser(AppUserId)

1.14 File Attachment (polymorphic)

Attachment

Column Data Type Constraints Description
AttachmentId int PK, IDENTITY, NOT NULL
OwnerEntityType varchar(50) NOT NULL, CHECK IN ('COURSE','PROJECT','TRAINER','REGISTRATION','KNOWLEDGE_REPORT','MEMBER') COURSE/PROJECT/TRAINER/REGISTRATION/KNOWLEDGE_REPORT/MEMBER
OwnerEntityId int NOT NULL running id ของ entity เจ้าของ (polymorphic, ไม่มี DB-level FK)
FileName nvarchar(255) NOT NULL ชื่อไฟล์ที่จัดเก็บ
OriginalName nvarchar(255) NOT NULL ชื่อไฟล์ต้นฉบับ
MimeType varchar(150) NOT NULL ชนิด MIME
Extension varchar(20) NOT NULL, CHECK IN ('doc','docx','xls','xlsx','ppt','pdf','jpeg') doc/docx/xls/xlsx/ppt/pdf/jpeg
FileSize bigint NOT NULL, CHECK (FileSize <= 52428800) ขนาด byte (<= 50MB)
Sha256 varchar(64) checksum สำหรับ dedupe/integrity
StoragePath nvarchar(1000) NOT NULL path/key ที่เก็บไฟล์
UploadedAt datetime2 DEFAULT SYSUTCDATETIME(), NOT NULL
UploadedBy int
IsDeleted bit DEFAULT 0, NOT NULL

Foreign Keys: UploadedByPRC.AppUser(AppUserId)