Rigi
კონტაქტ-ცენტრის პროგრამული უზრუნველყოფის მომწოდებლის ოპერაციული ცენტრი, ქართულად და ინგლისურად. კლიენტ კომპანიებს აქვთ ლიცენზიის ადგილების პულები, რომლებიც მათივე სატელეფონო სისტემებიდან სინქრონიზდება; მათი მხარდაჭერის მოთხოვნები ელფოსტით შემოდის, ხდება დავალებად, ფასდება ქულებით ყოველთვიური უფასო ლიმიტის გათვალისწინებით და ერთ ყოველთვიურ ინვოისში აისახება ადგილებთან და ფიქსირებული ფასის პროექტებთან ერთად. პროდუქტს ხუთი როლი იყენებს: სუპერადმინისტრატორი, ბუღალტერი, მხარდაჭერის სამსახური, ტექნიკოსები და ცალკე პორტალი, სადაც კლიენტები აგზავნიან დავალებებს, ადასტურებენ მათ შესრულებას, მიმოწერენ, ინვოისს ასაჩივრებენ და თავიანთ ლიმიტს აკვირდებიან. ჩვენ ის თავიდან ბოლომდე ავაგეთ — NestJS API Postgres-ზე ფონური ამოცანების რიგით და Next.js ფრონტენდი — ეს დემო კი სწორედ ის ფრონტენდია, რომელიც ბრაუზერშივე მომუშავე სიმულაციასთან მუშაობს და გამოგონილი Rigi-ის სახითაა გადაფორმებული.
წელი: 2026 · კატეგორია: ბიზნეს ოპერაციები
ჩვენი როლი
Full-stack. მონაცემთა მოდელი და ბილინგის წესები, ფონური ამოცანებისა და ელფოსტის კონვეიერი, როლებისა და კლიენტ კომპანიების მოდელი, ინვოისის შაბლონების რენდერერი და ვებ-აპლიკაცია ხუთივე როლის სივრცით.
პრობლემა
მომწოდებელი, რომელიც კონტაქტ-ცენტრის პროგრამას ათეულ კლიენტ კომპანიას ყიდდა, ბიზნესს ცხრილებით, საერთო ელფოსტის ყუთითა და PDF-ების საქაღალდით მართავდა. ლიცენზიებს ხელით ითვლიდნენ იმასთან შედარებით, რაც რეალურად ჰქონდა კლიენტის სატელეფონო სისტემას. მხარდაჭერის სამუშაოზე ელფოსტით თანხმდებოდნენ და ანგარიშს ზეპირად ადგენდნენ. ინვოისი თვის ბოლოს სამი ისეთი წყაროდან გროვდებოდა, რომლებიც ერთმანეთს არ ემთხვეოდა.
ეს ციფრები ერთმანეთზეა დამოკიდებული. ადგილი იმ დღეების მიხედვით ფასდება, რამდენ ხანსაც მომხმარებელი ფლობდა მას; მხარდაჭერის დავალება ქულებით იზომება, თვეში პირველი რამდენიმე ქულა უფასოა, დანარჩენი კი კლიენტის საკუთარი ტარიფით და საკუთარ ვალუტაში ირიცხება; ფიქსირებული ფასის პროექტი თავისი დავალებების ქულებს ანაცვლებს. თუ ინვოისი, კლიენტის ქულების გვერდი და ფინანსური ანგარიშგება მათ ცალ-ცალკე ითვლის, ციფრები ერთმანეთს დაშორდება — და პირველივე კლიენტი, რომელიც ჯამს არ დაეთანხმება, საუბარს დაასრულებს.
მიდგომა
ფულის წესები ერთ წმინდა მოდულად გავიტანეთ და ყველაფერი დანარჩენი მის გარშემო ავაგეთ. პარტნიორები, ადგილები, მომხმარებლები, დავალებები, ქულები და პროექტები ჩანაწერებია; ინვოისი მათგან გამოითვლება ფუნქციებით, რომლებსაც ინვოისის ეკრანი, ქულების გვერდი, ანგარიშგებები და საწყისი მონაცემები ერთნაირად იყენებს. მის გარშემო დგას დავალებების მდგომარეობათა მანქანა, IMAP-ით შევსებული შემოსულების ყუთი, რომელიც ელფოსტას მიმოწერებად აჯგუფებს და პასუხს იმ დავალებას უკავშირებს, რომელსაც ეკუთვნის, და აუდიტის ჟურნალი, რომელიც ყველა ცვლილებას აფიქსირებს მფლობელის ცვლილებების გარდა.
ფრონტენდი როლზეა აგებული: ოთხი პერსონალის სივრცე და ცალკე პარტნიორთა რეალმი, თითოეული საკუთარი გარსით და როლით დაცული, ერთი დიზაინ-სისტემითა და ერთი ორენოვანი ლექსიკონით. დემოსთვის ფრონტენდი დავტოვეთ, სერვერი კი ისეთი სიმულაციით ჩავანაცვლეთ, რომელიც იგივე ენდფოინთებს მეხსიერებაში მყოფ საცავზე ახორციელებს — ამიტომ ყველა ეს წესი ვიზიტორის ბრაუზერში მუშაობს.
მთავარი მომენტები
- ფულს ერთი წმინდა მოდული განაგებს: ინვოისის ხაზებს, ქულებს, ადგილების ფასებსა და ჯამებს ეკრანიც, ანგარიშგებებიც და საწყისი მონაცემებიც ერთსა და იმავე ფუნქციებით ითვლის.
- ადგილები იმ დღეების მიხედვით ფასდება, რამდენ ხანსაც ისინი დაკავებული იყო, პული კი პარტიების ისტორიაა, ამიტომ ადგილების რაოდენობის შეცვლა წარსულს არასოდეს გადაწერს.
- ქულები ჩამოიწერება მაშინ, როცა კლიენტი დავალებას ადასტურებს, ყოველთვიური უფასო ლიმიტი კი თავად ჩამოწერის შიგნით გამოიყენება.
- დავალების მდგომარეობათა მანქანა წყვეტს როგორც იმას, რას იღებს სერვერი, ისე იმასაც, რომელ ღილაკებს ხედავს თითოეული როლი.
- ელფოსტა ჯერ პასუხის სათაურებით, შემდეგ კი ნორმალიზებული თემით ჯგუფდება, მიბმულ მიმოწერაზე პასუხი კი დავალებას აღნიშნავს.
- ინვოისის შაბლონების დიზაინერი ბლოკების კონსტრუქტორს, ნედლ HTML-სა და CSS-ს და ხელმოწერის პანელს აერთიანებს; მას საკუთარი შაბლონის ძრავი ხატავს და ქართულს ქსელის გარეშე ბეჭდავს.
- კლიენტები ცალკე რეალმში არიან: პორტალის ყოველი წაკითხვა ერთ კომპანიაზეა შეზღუდული, პარტნიორის გამორთვა კი მის ადმინისტრატორებს შემდეგივე მოთხოვნისას წვდომას წაართმევს.
არქიტექტურა
- რეპოზიტორია: pnpm სამუშაო სივრცე სამი ნაწილით: API, ვებ-აპლიკაცია და zod კონტრაქტების პაკეტი, რომელსაც ორივე მხარე იმპორტირებს — ამიტომ მოთხოვნა გაგზავნისას და მიღებისას ერთსა და იმავე სტრუქტურასთან მოწმდება.
- API: NestJS REST ვერსიულ პრეფიქსზე, OpenAPI დოკუმენტაციით და გენერირებული TypeScript კლიენტით. როლების guard-ი წვდომას ნაგულისხმევად უკრძალავს; მოთხოვნის იდენტიფიკატორი ჟურნალის ყოველ სტრიქონს კონკრეტულ გამოძახებასთან აკავშირებს; გლობალური აუდიტის ინტერცეპტორი JSON-patch სხვაობებს წერს და სუპერადმინისტრატორისთვის ამას განზრახ არ აკეთებს.
- მონაცემთა ბაზა: PostgreSQL 16 Prisma-ს გავლით, დაახლოებით ორმოცი მოდელი. ფული ფიქსირებული სიზუსტის ათწილადია, კლიენტების გამიჯვნა კი კლიენტის მონაცემების შემცველ ყოველ ცხრილში პარტნიორის იდენტიფიკატორის სვეტით ხდება; შეზღუდვები, რომლებსაც ORM ვერ გამოხატავს — ნაწილობრივი უნიკალური ინდექსები — ნედლ მიგრაციულ SQL-შია დაწერილი.
- ფონური ამოცანები: pg-boss იმავე ბაზაზე, მომწოდებლის საკუთარ დროის სარტყელში დაგეგმილი: ელფოსტის გამოკითხვა, თვის დახურვა, ყოველთვიური ინვოისების გენერაცია, ყოველდღიური ავტო-დრაფტი იმ პარტნიორებისთვის, ვისაც დღეს ინვოისის გენერაციის დღე აქვს, მომხმარებელთა რაოდენობის ყოველდღიური სნეპშოტი და ძველი ჩანაწერების გასუფთავება.
- ავტორიზაცია: argon2id ჰეშები; თხუთმეტწუთიანი შიდა ტოკენი და მბრუნავი გაუმჭვირვალე refresh ტოკენი httpOnly ქუქიში, ვებ-აპლიკაციის route handler-ებით გატარებული. პარტნიორთა ადმინისტრატორები ცალკე რეალმში არიან. პარტნიორთა სატელეფონო სისტემები მომხმარებელთა რაოდენობას მანქანური ავტორიზაციით აგზავნიან — გასაღების იდენტიფიკატორი და საიდუმლო ხანმოკლე, უფლებებით შეზღუდულ ტოკენად იცვლება, მოთხოვნების რაოდენობა კი წუთში შეზღუდულია.
- ვებ-აპლიკაცია: Next.js 15 App Router როლების მიხედვით დაჯგუფებული მარშრუტებით, edge middleware-ით, რომელიც როლის მიხედვით მიმართავს, სერვერული კომპონენტებით წაკითხვისთვის და route-handler პროქსებით ცვლილებებისთვის. shadcn/ui და Tailwind, ინგლისური და ქართული ლექსიკონებით.
- ელფოსტა: IMAP გამომკითხველი ყოველ წერილს და მის დანართებს ტომზე ინახავს და RFC 5322 სათაურებით მიმოწერებად აჯგუფებს; SMTP პაროლის აღდგენისა და ინვოისების წერილებს გზავნის.
- PDF: Headless Chromium Puppeteer-ის გავლით რედაქტირებად HTML და CSS ინვოისის შაბლონებს რენდერავს; კონტეინერის იმიჯში ქართული შრიფტია ჩაშენებული.
- ინფრასტრუქტურა: Docker Compose დეველოპმენტისა და პროდაქშენისთვის: nginx TLS-ით API და ვებ კონტეინერების წინ, კონტეინერი, რომელიც ბაზის სარეზერვო ასლებს ქმნის, ჯანმრთელობის ენდფოინთები სიცოცხლისუნარიანობისა და მზადყოფნისთვის, Ubuntu ჰოსტი.
- ეს დემო: ვებ-აპლიკაცია დარჩა; სერვერი `@portfolio/demo-kit`-მა ჩაანაცვლა. ბრაუზერში მომუშავე სიმულაცია 163 ენდფოინთს პასუხობს იმ საცავიდან, რომელიც ჩატვირთვისას გენერირებული საწყისი მონაცემებით აიგება, ელფოსტის, ჩატის პასუხებისა და სისტემის ჯანმრთელობის სიმულატორებით.
ციფრებში
როლი: 5 · ეკრანი: 59 · სიმულირებული ენდფოინთი: 163 · მონაცემთა კოლექცია: 34 · პარტნიორი კომპანიების მომხმარებელი საწყის მონაცემებში: 399 · თარგმანის გასაღები თითო ენაზე: 2,310 · TypeScript-ის კოდის ხაზი: 34k
შედეგები
- ერთი ბილინგის მოდული ინვოისს, კლიენტის ქულების გვერდსა და ორივე ფინანსურ ანგარიშგებას ამარაგებს, ამიტომ ციფრი ყველგან, სადაც კი ჩანს, ერთნაირია.
- მხარდაჭერის სამუშაო ფასდება მის დაწყებამდე და იწერება ერთხელ — როცა კლიენტი მას ადასტურებს; დადასტურებამდე კლიენტი ხედავს დარჩენილ ლიმიტს და იმასაც, გადააჭარბებს თუ არა მას ეს დავალება.
- თვის ბოლოს ინვოისი ერთი ღილაკია: ადგილები დაკავებული დღეების პროპორციით, ლიმიტს გადაჭარბებული ქულები, ფიქსირებული ფასის პროექტები, დღგ და PDF კლიენტის საკუთარ შაბლონში.
- ხუთი როლი ერთი კოდის ბაზიდან ხუთ განსხვავებულ პროდუქტს ხედავს, კლიენტი კომპანია კი მხოლოდ საკუთარ ჩანაწერებს წვდება.
- მთელი ინტერფეისი — დაახლოებით 2 300 სტრიქონი — ინგლისურადაც არსებობს და ქართულადაც.
რა გამოვიყენეთ
- ბექენდი: NestJS, Prisma, ვებ-აპლიკაციასთან გაზიარებული zod კონტრაქტები, OpenAPI და გენერირებული TypeScript კლიენტი, argon2id პაროლების ჰეშირება, JWT მბრუნავი refresh ტოკენებით
- მონაცემები, ელფოსტა და ფონური ამოცანები: PostgreSQL 16, pgcrypto და citext, pg-boss ამოცანების რიგი, ელფოსტის გამოკითხვა IMAP-ით, ელფოსტის გაგზავნა SMTP-ით, Puppeteer და headless Chromium
- ვებ-აპლიკაცია: Next.js 15 App Router, React, TypeScript, Tailwind CSS, shadcn/ui, ინგლისური და ქართული ლექსიკონები
- გაშვება და მიწოდება: pnpm workspaces, Docker Compose, nginx და TLS, მონაცემთა ბაზის დაგეგმილი დამპები, Ubuntu სერვერი
- დემოს აწყობა: React 18, Vite 6, TypeScript, Tailwind CSS 4, TanStack Query 5, React Router 6, i18next, Recharts, dnd-kit, React Hook Form + zod, Radix UI, cmdk, framer-motion, sonner, @portfolio/demo-kit (ბრაუზერში მომუშავე სიმულირებული API)
დემო
ჩვენ მიერ აწყობილი რეალური პროდუქტის გამოგონილი გადაფორმება: Rigi, მისი კლიენტი კომპანიები და ადამიანები გამოგონილია. ბექენდი არ არსებობს. ბრაუზერში მომუშავე სიმულაცია ყველა 163 ენდფოინთს პასუხობს იმ მონაცემებით, რომლებიც გვერდის ჩატვირთვისას, დღევანდელი დღის მიმართ გენერირდება, და ყველაფერი, რასაც შეცვლით, მეხსიერებაში რჩება — გადატვირთვისას დავალებები, ადგილები და ინვოისები ისევ პირვანდელ მდგომარეობაში დაგხვდებათ. პერსონა კუთხეში მდებარე პანელიდან გადართეთ; ელფოსტა ტაიმერით შემოდის; ელფოსტის, PDF-ისა და პარტნიორის სინქრონიზაციის ნაბიჯები სიმულირებულია.