[{"data":1,"prerenderedAt":258},["ShallowReactive",2],{"portfolio-orchard-saas":3,"all-portfolio":238},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":7,"category":9,"client":10,"timeline":11,"role":12,"date":13,"tags":14,"body":23,"_type":232,"_id":233,"_source":234,"_file":235,"_stem":236,"_extension":237},"\u002Fportfolio\u002Forchard-saas","portfolio",false,"","Orchard — HR & Payroll SaaS สำหรับ SME ไทย","SaaS","Orchard HR Tech","20 สัปดาห์","Full-stack Architecture, Frontend, Backend API","2023-11-15",[15,16,17,18,19,20,21,22],"React","Next.js","TypeScript","Node.js","PostgreSQL","Redis","Docker","AWS ECS",{"type":24,"children":25,"toc":220},"root",[26,34,40,46,53,66,86,92,104,110,115,139,144,156,168,173],{"type":27,"tag":28,"props":29,"children":31},"element","h2",{"id":30},"ภาพรวม",[32],{"type":33,"value":30},"text",{"type":27,"tag":35,"props":36,"children":37},"p",{},[38],{"type":33,"value":39},"Orchard เป็นโปรเจกต์ที่ใหญ่และซับซ้อนที่สุดที่เราเคยทำ — HR SaaS สำหรับบริษัทขนาด 20-500 คน ที่ต้องรองรับทั้ง time attendance, leave management, payroll calculation และ compliance กับกฎหมายแรงงานไทย",{"type":27,"tag":28,"props":41,"children":43},{"id":42},"ความท้าทายด้าน-architecture",[44],{"type":33,"value":45},"ความท้าทายด้าน Architecture",{"type":27,"tag":47,"props":48,"children":50},"h3",{"id":49},"multi-tenant-data-isolation",[51],{"type":33,"value":52},"Multi-tenant Data Isolation",{"type":27,"tag":35,"props":54,"children":55},{},[56,58,64],{"type":33,"value":57},"เราออกแบบ ",{"type":27,"tag":59,"props":60,"children":61},"strong",{},[62],{"type":33,"value":63},"schema-per-tenant",{"type":33,"value":65}," บน PostgreSQL แทน row-level isolation เพราะ:",{"type":27,"tag":67,"props":68,"children":69},"ul",{},[70,76,81],{"type":27,"tag":71,"props":72,"children":73},"li",{},[74],{"type":33,"value":75},"Query performance ดีกว่าเมื่อ dataset ใหญ่ขึ้น",{"type":27,"tag":71,"props":77,"children":78},{},[79],{"type":33,"value":80},"Database maintenance ทำได้ง่ายกว่า",{"type":27,"tag":71,"props":82,"children":83},{},[84],{"type":33,"value":85},"สามารถ provision ทรัพยากรแยกกันได้สำหรับ enterprise tier",{"type":27,"tag":47,"props":87,"children":89},{"id":88},"payroll-calculation-engine",[90],{"type":33,"value":91},"Payroll Calculation Engine",{"type":27,"tag":35,"props":93,"children":94},{},[95,97,102],{"type":33,"value":96},"กฎหมายแรงงานไทยมีความซับซ้อนสูง ทั้งการคำนวณ OT, วันหยุดชดเชย, ประกันสังคม, ภาษี ณ ที่จ่าย เราออกแบบเป็น ",{"type":27,"tag":59,"props":98,"children":99},{},[100],{"type":33,"value":101},"rule engine",{"type":33,"value":103}," ที่อ่าน business rules จาก configuration แทนการ hardcode เพื่อรองรับการเปลี่ยนแปลงกฎหมายในอนาคต",{"type":27,"tag":47,"props":105,"children":107},{"id":106},"performance-ของ-report-generation",[108],{"type":33,"value":109},"Performance ของ Report Generation",{"type":27,"tag":35,"props":111,"children":112},{},[113],{"type":33,"value":114},"รายงาน payroll บริษัท 300 คนต้องสร้างใน \u003C 3 วินาที เราแก้ด้วยการ:",{"type":27,"tag":116,"props":117,"children":118},"ol",{},[119,129,134],{"type":27,"tag":71,"props":120,"children":121},{},[122,124],{"type":33,"value":123},"Pre-compute ข้อมูลสรุปทุกสิ้นเดือนเก็บไว้ใน ",{"type":27,"tag":59,"props":125,"children":126},{},[127],{"type":33,"value":128},"Redis cache",{"type":27,"tag":71,"props":130,"children":131},{},[132],{"type":33,"value":133},"Generate PDF แบบ async บน background job",{"type":27,"tag":71,"props":135,"children":136},{},[137],{"type":33,"value":138},"ส่ง email + notification เมื่อ PDF พร้อม",{"type":27,"tag":28,"props":140,"children":142},{"id":141},"สิ่งที่ทำให้โปรเจกต์นี้พิเศษ",[143],{"type":33,"value":141},{"type":27,"tag":35,"props":145,"children":146},{},[147,149,154],{"type":33,"value":148},"การทำ ",{"type":27,"tag":59,"props":150,"children":151},{},[152],{"type":33,"value":153},"audit trail",{"type":33,"value":155}," ที่สมบูรณ์สำหรับทุก payroll transaction — ทุกการเปลี่ยนแปลงต้องบันทึกว่าใคร เปลี่ยนอะไร เมื่อไหร่ และทำไม เพราะ HR data มี legal implication ที่สูงมาก",{"type":27,"tag":35,"props":157,"children":158},{},[159,161,166],{"type":33,"value":160},"เราใช้ ",{"type":27,"tag":59,"props":162,"children":163},{},[164],{"type":33,"value":165},"event sourcing pattern",{"type":33,"value":167}," บน PostgreSQL (ไม่ใช่ event database พิเศษ) ซึ่งง่ายกว่าแต่ให้ auditability ที่เพียงพอ",{"type":27,"tag":28,"props":169,"children":171},{"id":170},"ผลลัพธ์",[172],{"type":33,"value":170},{"type":27,"tag":67,"props":174,"children":175},{},[176,186,198,210],{"type":27,"tag":71,"props":177,"children":178},{},[179,181],{"type":33,"value":180},"ลูกค้า pilot 8 บริษัท เวลาทำ payroll เฉลี่ยลดจาก ",{"type":27,"tag":59,"props":182,"children":183},{},[184],{"type":33,"value":185},"6 ชั่วโมง → 45 นาที",{"type":27,"tag":71,"props":187,"children":188},{},[189,191,196],{"type":33,"value":190},"Error ใน payroll calculation ลดลง ",{"type":27,"tag":59,"props":192,"children":193},{},[194],{"type":33,"value":195},"100%",{"type":33,"value":197}," (จาก manual Excel)",{"type":27,"tag":71,"props":199,"children":200},{},[201,203,208],{"type":33,"value":202},"Net Promoter Score: ",{"type":27,"tag":59,"props":204,"children":205},{},[206],{"type":33,"value":207},"72",{"type":33,"value":209}," (ระดับ excellent)",{"type":27,"tag":71,"props":211,"children":212},{},[213,215],{"type":33,"value":214},"Uptime 12 เดือนหลัง launch: ",{"type":27,"tag":59,"props":216,"children":217},{},[218],{"type":33,"value":219},"99.94%",{"title":7,"searchDepth":221,"depth":221,"links":222},2,[223,224,230,231],{"id":30,"depth":221,"text":30},{"id":42,"depth":221,"text":45,"children":225},[226,228,229],{"id":49,"depth":227,"text":52},3,{"id":88,"depth":227,"text":91},{"id":106,"depth":227,"text":109},{"id":141,"depth":221,"text":141},{"id":170,"depth":221,"text":170},"markdown","content:portfolio:orchard-saas.md","content","portfolio\u002Forchard-saas.md","portfolio\u002Forchard-saas","md",[239,243,246,250,254,255],{"_path":240,"title":241,"category":242},"\u002Fportfolio\u002Ffreshmarket-platform","FreshMarket — แพลตฟอร์มตลาดสดออนไลน์","E-commerce",{"_path":244,"title":245,"category":9},"\u002Fportfolio\u002Fmedsync-dashboard","MedSync — ระบบจัดการคลินิกและนัดหมายผู้ป่วย",{"_path":247,"title":248,"category":249},"\u002Fportfolio\u002Frunclub-app","RunClub — แอปสำหรับชมรมวิ่งและ community นักวิ่งไทย","Mobile",{"_path":251,"title":252,"category":253},"\u002Fportfolio\u002Fbaan-design-studio","Baan Design Studio — Portfolio Website สำหรับสตูดิโอออกแบบ","Web",{"_path":4,"title":8,"category":9},{"_path":256,"title":257,"category":249},"\u002Fportfolio\u002Fbitebuddy-food-app","BiteBuddy — แอปค้นหาร้านอาหารและรีวิวเพื่อชุมชน",1779878303310]