Tova
გამოფენის სტენდს ერთი პრობლემა აქვს: არავის სურს, თავისი მონაცემები უსასყიდლოდ დატოვოს. Tova მიზეზს აძლევს. ვიზიტორი რეგისტრირდება, სამოცწამიან canvas რაუნდში იჭერს სპონსორის მონეტებს და გაურბის საფრთხეებს, დროში შეზღუდული ვიქტორინის კითხვებს ბონუს ქულებისთვის პასუხობს და ცოცხალ რეიტინგს უყურებს. ამ ყველაფრის უკან ორგანიზატორის კონსოლი დგას, რომელიც მთელ ღონისძიებას მართავს: განრიგს, სამართლიანობის ლიმიტებს, ჩამოვარდნილ ნივთებს, ვიქტორინას, პრიზებს, ადამიანებს და ლიდების სიას Excel ფაილის სახით, რომელიც CRM-ში პირდაპირ იტვირთება. ოთხი როლიდან თითოეული მის განსხვავებულ ნაწილს ხედავს, ქართულად და ინგლისურად. ჩვენ ის თავიდან ბოლომდე ავაგეთ — Next.js აპლიკაცია, ხელით დაწერილი canvas ძრავა და ორივეს უკან მდგარი route handler-ები.
წელი: 2026 · კატეგორია: ივენთ ტექნოლოგიები
ჩვენი როლი
Full-stack. თამაშის ძრავა და მისი სამართლიანობის გეგმა, ქულებისა და რეიტინგის წესები, ორგანიზატორის კონსოლი, მონაცემთა მოდელი, ავტორიზაცია და ორენოვანი ინტერფეისი.
პრობლემა
გამოფენაზე სტენდი ძვირი ჯდება, საუბარი კი მასთან მოკლეა. ვიზიტორები გვერდით ჩაუვლიან, ბანერს გადახედავენ და გზას გააგრძელებენ, ხოლო ვინც გაჩერდება, იმას აშკარა ჯილდოს გარეშე სთხოვენ ფორმაში სახელის, კომპანიისა და ნომრის ჩაწერას. დღის ბოლოს ორგანიზატორს ხელში რჩება ბარათების დასტა, რომლის ნახევარი ვერ იკითხება, და იმის დადგენის საშუალებაც არ აქვს, რომელმა სპონსორმა მართლა მიიპყრო ვინმეს ყურადღება.
ორგანიზატორის მხარეც უკეთესი არ არის: განრიგი, პრიზები, კითხვები და მოსულთა სია სხვადასხვა ადგილას ინახება, გამარჯვებულის გამოსავლენად კი ერთადერთი სამართლიანი გზა ისაა, რომელზეც არავინ დაობს. თამაში პირველ პრობლემას მხოლოდ მაშინ წყვეტს, თუ სამართლიანია, რადგან როგორც კი ვიზიტორს ეჭვი შეეპარება, რომ ქულა იღბალი ან ხრიკი იყო, პრიზიც და ლიდიც ნაკლებ ღირს.
მიდგომა
თამაში რეგისტრაციის მიზეზად ვაქციეთ, სამართლიანობა კი დაპირების ნაცვლად ძრავის თვისებად ვაქციეთ.
ვიზიტორი რეგისტრირდება, ერთ სამოცწამიან canvas რაუნდს თამაშობს და რეიტინგში ხვდება. რაუნდი დაწყებამდე იგეგმება, ამიტომ ყველა მოთამაშეს წილად ერთი და იგივე ჯამური რაოდენობის დასაჭერი მონეტები და ერთი და იგივე ჯამური ჯარიმები ხვდება, უბრალოდ სხვადასხვაგვარად განლაგებული. ვიქტორინა ბონუს ქულებს უმატებს, თითო კითხვაზე ერთხელ, ხოლო საბოლოო შედეგი საუკეთესო რაუნდისა და ამ ქულების ჯამია, ამიტომ გამეორება არაფერს ცვლის. რეიტინგი ხალხის თვალწინ ახლდება.
ყველაფერი, რასაც ორგანიზატორი ეხება, ოთხროლიან კონსოლშია, ასე რომ, თანამშრომელს შეუძლია ნახოს და ვერაფერი გააფუჭოს. ღონისძიებები, ჩამოვარდნილი ნივთები, ვიქტორინა და პრიზები ორგანიზატორის რედაქტირებადი მონაცემებია, ადამიანების გვერდი ანგარიშებს მართავს, მონაწილეთა გვერდი კი ლიდების სიას ერთი დაწკაპუნებით Excel ფაილად აქცევს. სპონსორის ნივთები იმ ბრენდების სახელებს ატარებს, რომელთა გამოც თამაშს სპონსორობა ღირს.
მთავარი მომენტები
- სამართლიანობა კონსტრუქციაშივე: რაუნდი წინასწარ იგეგმება, ამიტომ ყველა მოთამაშე ზუსტად ღონისძიების დასაჭერ ბიუჯეტს და ზუსტად მის ჯარიმის ბიუჯეტს იღებს ოთხსაფეხურიან ზრდაზე. შემთხვევითია მხოლოდ განლაგება, ხოლო სერვერი გაგზავნილ ქულას ბიუჯეტამდე ზღუდავს.
- რეიტინგის წესია საუკეთესო ერთი რაუნდი პლუს ვიქტორინის სწორი პასუხების ქულები, არასოდეს რაუნდების ჯამი, ამიტომ სტენდთან გატარებული დრო ადგილს ვერ ყიდულობს. ორგანიზატორს შეუძლია რეიტინგის დამალვა, ხოლო მოთამაშის ბარათზე ადგილის ნაცვლად ღონისძიების დასრულებამდე უკუთვლა ჩანს.
- ვიქტორინის კითხვას პასუხი ერთხელ ეძლევა და სწორი პასუხი ბრაუზერს არასოდეს ეგზავნება. ტაიმერი ნულზე პასუხს ავტომატურად აგზავნის, დარჩენილი წამების მრიცხველი კი ხუთზე წითლდება.
- ოთხი როლი ერთ კონსოლზე: სუპერვაიზერი კითხულობს, ადმინი ღონისძიებებს, ნივთებს, ვიქტორინასა და პრიზებს ცვლის, სუპერადმინი დამატებით ადამიანებსაც მართავს, საკუთარი თავის შეცვლა, დაბლოკვა ან წაშლა კი არავის შეუძლია.
- ყველაფერი, რაც ორგანიზატორს სამართლიანი დღის ჩასატარებლად სჭირდება: განრიგი, რაუნდის ხანგრძლივობა, სამართლიანობის ლიმიტები, სირთულე, სიჩქარის დონე, რეიტინგის ზომა და სამი ხილვადობის გადამრთველი თითოეულ ღონისძიებაზე.
- ლიდების სია ნამდვილი Excel ფაილის სახით გადმოიწერება და ისეა აგებული, რომ მავნე უჯრის მნიშვნელობა ფორმულად ვერ იქცევა.
- ქართული და ინგლისური მონაცემთა მოდელიდან დაწყებული: ორივე ენაზე 760 სტრიქონი ერთსა და იმავე გასაღებებით და ქართულის მხარდამჭერი შრიფტები ყველგან.
არქიტექტურა
- აპლიკაცია: Next.js App Router-ით და React 19. სერვერული კომპონენტები კონსოლისა და რეიტინგის მონაცემებს კითხულობენ; კლიენტის კომპონენტები ყველაფრისთვის, რაც მონაცემებს ცვლის, `/api/*` route handler-ების მცირე ნაკრებს მიმართავენ. Tailwind CSS 4, ქართულის მხარდამჭერი შრიფტები და ფიქსირებული სიგანის შრიფტი ქულებისთვის.
- თამაშის ძრავა: საკუთარი HTML5 Canvas 2D ძრავა თამაშის ბიბლიოთეკის გარეშე: წინასწარ დაგეგმილი გამოჩენის განრიგი, შეზღუდული ფიქსირებული ბიჯის ციკლი, პლატფორმის მართვა კურსორით, შეხებით და ისრებით, და ეფექტები, რომლებიც ნელ მოწყობილობაზე ითიშება.
- ვალიდაცია და თაღლითობისგან დაცვა: zod სქემები ყველა route handler-ზე. სერვერი ყოველ გაგზავნილ ქულას ღონისძიების ქულების ბიუჯეტამდე ზღუდავს, რაუნდის გეგმა კი ყველა მოთამაშეს ერთსა და იმავე ბიუჯეტს ანიჭებს.
- ავტორიზაცია: ხელმოწერილი JWT სესიები `httpOnly` ქუქიში, პაროლის გარეშე შესვლა ერთჯერადი კოდით და route-ის ბარიერი, რომელიც არაავტორიზებულ ვიზიტორს `/play`, `/me` და `/admin` გვერდებიდან აბრუნებს. ოთხი როლი: მოთამაშე, სუპერვაიზერი, ადმინი და სუპერადმინი.
- მონაცემები: რელაციური მონაცემთა ბაზა ORM-ით: მომხმარებლები, ღონისძიებები, ნივთები, თამაშები, ვიქტორინის კითხვები, პასუხები და პრიზები. უნიკალური შეზღუდვა (user, question) წყვილზე ნიშნავს, რომ კითხვაზე მხოლოდ ერთხელ შეიძლება პასუხის გაცემა.
- ელფოსტა და საცავი: ტრანზაქციული წერილები შესვლის კოდებისა და პრიზის გამარჯვებულთა შესატყობინებლად და ობიექტების საცავი ორგანიზატორის ატვირთული სპონსორის გრაფიკისთვის.
- ექსპორტი: მონაწილეთა სიის სერვერზე აგებული Excel ფაილი, რომელიც CRM-ში იტვირთება.
- ჰოსტინგი: Serverless, route handler-ები და გვერდები ერთად ჩაიშვება. ნივთების გრაფიკისთვის AI გენერაცია დაგეგმილია: ღილაკი არსებობს და „მალე იქნება“ პასუხობს.
ციფრებში
როლი: · ეკრანი: · სიმულირებული API მარშრუტი: · ენა: · თამაშის ძრავის კოდის ხაზი: · დემოს საწყისი კოდის ხაზი:
შედეგები
- სტენდს ეძლევა მიზეზი, რომ ხალხი გაჩერდეს და მონაცემები დატოვოს, ორგანიზატორი კი ბარათების დასტის ნაცვლად სუფთა ლიდების სიას იღებს Excel ფაილის სახით.
- გამარჯვებულს ისეთი წესი ადგენს, რომელზეც არავის უწევს დავა: ყველა მოთამაშეს ერთი და იგივე ბიუჯეტი, საუკეთესო ერთი რაუნდი და სერვერზე შეზღუდვა.
- მთელ ღონისძიებას — მის განრიგს, ლიმიტებს, ნივთებს, ვიქტორინასა და პრიზებს — ორგანიზატორი კონსოლში თავად არედაქტირებს და ამისთვის ახალი ვერსიის გამოშვება არ გვიწევს.
- თანამშრომელს შეუძლია რეიტინგის თვალყურის დევნება, ერთი მოთამაშის თამაშებში ჩაღრმავება და ანალიტიკის ციფრების წაკითხვა ისე, რომ ღონისძიების შეცვლა არ შეეძლოს.
რა გამოვიყენეთ
- აპლიკაცია: Next.js 16 (App Router, სერვერული კომპონენტები), React 19, TypeScript, Tailwind CSS 4, Noto Sans და Noto Serif Georgian, ფიქსირებული სიგანის შრიფტი ქულებისთვის
- თამაში: HTML5 Canvas 2D, საკუთარი ძრავა თამაშის ბიბლიოთეკის გარეშე, წინასწარ დაგეგმილი გამოჩენის განრიგი, შეზღუდული ფიქსირებული ბიჯის ციკლი, ადაპტიური ეფექტები
- მონაცემები და ავტორიზაცია: რელაციური მონაცემთა ბაზა ORM-ის მეშვეობით, უნიკალური შეზღუდვა (user, question) წყვილზე, zod ვალიდაცია ყველა route handler-ზე, ხელმოწერილი JWT სესიები httpOnly ქუქიში, შესვლა ერთჯერადი კოდით, route-ის ბარიერი /play, /me და /admin გვერდებისთვის
- სერვისები: ტრანზაქციული ელფოსტა (შესვლის კოდები, პრიზის გამარჯვებულები), ობიექტების საცავი სპონსორის გრაფიკისთვის, ExcelJS (მონაწილეთა Excel ფაილი), Serverless ჰოსტინგი
- დემოს აწყობა: Vite 6, React 18, React Router 6, TanStack Query 5, i18next 24 (KA/EN), Recharts 2, Radix UI, Tailwind CSS 4, framer-motion, @portfolio/demo-kit: სიმულირებული API და საცავი, ხელით დაწერილი OOXML და ZIP ჩამწერები
დემო
ჩვენს მიერ აგებული რეალური პროდუქტის გამოგონილი რესკინი გამოგონილი ბრენდით Tova, სადაც ყველა სახელი, სპონსორი და ადამიანი ჩანაცვლებულია. Next.js სერვერი მოხსნილია: ბრაუზერში მომუშავე სიმულირებული API ყველა 41 API მარშრუტს პასუხობს ბანდლში ჩაშენებული საწყისი მონაცემებიდან, ამიტომ ქსელური მოთხოვნა არ სრულდება. მონაცემები მეხსიერებაში ინახება და გვერდის გადატვირთვისას ბრუნდება საწყისზე, რეალური ავტორიზაცია, ელფოსტა და საცავი არ არსებობს, Excel ექსპორტი კი ჩანართშივე იგება. დემო ავტორიზაციის გარეშე, საჯარო მთავარ გვერდზე იხსნება, ხოლო დემო-ზოლით ოთხიდან ნებისმიერ როლში შეგიძლიათ შეხვიდეთ.