package main import ( "net/url" "regexp" "strings" ) // Discovery tags, not an approved sitemap: a workflow may span several channels. type UCTab struct { Key, Label, Href string Count int } var ucExternalActors = actorSet("นักศึกษา|นักเรียน|ผู้สมัคร|ผู้ปกครอง|ศิษย์เก่า|อดีตนักศึกษาที่ไม่สำเร็จการศึกษา|บุคคลภายนอก|สมาคมกีฬา|สถานประกอบการ|บริษัทประกันภัยคู่สัญญา|ครูพี่เลี้ยง|ผู้บริหารสถานศึกษาที่รับนักศึกษาฝึกสอน|ผู้ตรวจสอบเอกสาร") var ucInternalActors = actorSet("นายทะเบียน|หัวหน้าภาค|การเงิน|คณบดี|งานรับสมัคร|โค้ช|อาจารย์ที่ปรึกษา|อาจารย์ผู้สอน|หอพัก|หัวหน้างานกีฬา|ผู้อำนวยการ|กรรมการสอบทักษะ|รองอธิการบดีประจำวิทยาเขต|กิจการนักศึกษา|พยาบาล|แพทย์|อธิการบดี|สภาวิชาการ|ผู้รับผิดชอบด้านคุ้มครองเด็ก|บัณฑิตวิทยาลัย|ผู้ตรวจสอบภายใน|DPO|ประชาสัมพันธ์|ครูประจำชั้น|อาจารย์ที่ปรึกษาวิทยานิพนธ์|นักวิทยาศาสตร์การกีฬา|บุคลากร|กองแผน|เจ้าหน้าที่ กยศ.|ศูนย์รับเรื่องร้องเรียน|นิติกร|หน่วยบริการนักศึกษาพิการ|งานสารบรรณ|นักจิตวิทยา|รองอธิการบดีฝ่าย|ผู้ดูแลความมั่นคงปลอดภัย|งานนักศึกษาต่างชาติ|กรรมการคุมสอบ|งานทุน|ศูนย์ฝึกประสบการณ์วิชาชีพ|งานอาคารสถานที่|นักกายภาพบำบัด|นักโภชนาการการกีฬา|ครูผู้สอนโรงเรียนกีฬา|ผู้ดูแลการตั้งค่าโมดูล|ผู้ดูแลแพลตฟอร์มส่วนกลาง|DBA|Helpdesk L1/L2|IT วิทยาเขต|อาจารย์นิเทศก์|นักจิตวิทยาการกีฬา|เจ้าหน้าที่ห้องปฏิบัติการวิทยาศาสตร์การกีฬา|Data steward|ผู้ดูแล IAM") func actorSet(s string) map[string]bool { m := map[string]bool{} for _, a := range strings.Split(s, "|") { m[a] = true } return m } var integrationSystems = []struct { name string pattern *regexp.Regexp }{ {"ThaID", regexp.MustCompile(`(?i)\bThaID\b`)}, {"ธนาคาร / Thai QR / PromptPay", regexp.MustCompile(`(?i)ธนาคาร|\bPromptPay\b|\bThai QR\b`)}, {"e-Receipt", regexp.MustCompile(`(?i)\be-Receipt\b`)}, {"TCAS / ทปอ.", regexp.MustCompile(`(?i)\b(?:myTCAS|TCAS)\b|ทปอ\.`)}, {"กยศ. DSL", regexp.MustCompile(`(?i)\bDSL\b`)}, {"สป.อว. / CHECO", regexp.MustCompile(`(?i)สป\.อว\.|\bCHECO\b`)}, {"GFMIS", regexp.MustCompile(`(?i)\bGFMIS\b`)}, {"ตม.30 / ทะเบียนราษฎร์", regexp.MustCompile(`ตม\.?\s*30|ทะเบียนราษฎร์`)}, {"LMS / SSO", regexp.MustCompile(`(?i)\b(?:LMS|SSO)\b`)}, {"LINE / e-mail / SMS", regexp.MustCompile(`(?i)\b(?:LINE|SMS|e-mail|email)\b|อีเมล`)}, {"Digital signature / LTV", regexp.MustCompile(`(?i)\bLTV\b|\bdigital signature\b`)}, {"Reporting Hub", regexp.MustCompile(`(?i)\bReporting Hub\b`)}, } func classifyUseCase(u UseCase) UseCase { u.Channels = nil u.ChannelReasons = nil external, internal := []string{}, []string{} for _, a := range u.Actors { if ucExternalActors[a] { external = append(external, a) } if ucInternalActors[a] { internal = append(internal, a) } if a == "เจ้าของข้อมูล" { external = append(external, a) internal = append(internal, a) } } if len(external) > 0 { u.Channels = append(u.Channels, "frontend") u.ChannelReasons = append(u.ChannelReasons, "Frontend: "+strings.Join(external, ", ")) } if len(internal) > 0 { u.Channels = append(u.Channels, "backoffice") u.ChannelReasons = append(u.ChannelReasons, "Backoffice: "+strings.Join(internal, ", ")) } parts := []string{u.Name, u.Start, u.Outcome} for _, f := range u.Flow { parts = append(parts, f[1]) } text := strings.Join(parts, " ") systems := []string{} for _, s := range integrationSystems { if s.pattern.MatchString(text) { systems = append(systems, s.name) } } if len(systems) > 0 { u.Channels = append(u.Channels, "integration") u.ChannelReasons = append(u.ChannelReasons, "Integration: "+strings.Join(systems, ", ")) } return u } func channelTabs(v UCView) []UCTab { tabs := []UCTab{{Key: "", Label: "ทั้งหมด"}, {Key: "frontend", Label: "Frontend · ผู้ใช้ภายนอก"}, {Key: "backoffice", Label: "Backoffice · ผู้ใช้ภายใน"}, {Key: "integration", Label: "Integration · ระหว่างระบบ"}} for i := range tabs { q := url.Values{} if v.Query != "" { q.Set("q", v.Query) } if v.Module != "" { q.Set("module", v.Module) } if v.Actor != "" { q.Set("actor", v.Actor) } if tabs[i].Key != "" { q.Set("channel", tabs[i].Key) } tabs[i].Href = "/use-cases" if len(q) > 0 { tabs[i].Href += "?" + q.Encode() } } return tabs }