ЦЗ Цахим Засаг
GitHub Нэвтрэх

Ваучерийн механизм

Эх сурвалж: FUELNET_PLAN.md §4 · Код: modules/voucher/ · API: /api/v1/fuelnet/voucher

Энэ хуудас нь fuelnet.dgov.mn-ий гурван модулийн нэг — ваучер — хэрхэн ажилладгийн дэлгэрэнгүй.

Нэг зарчим

Ваучер бол амлалт биш, нөөцлөгдсөн литр.

Ваучер зөвхөн ШТС-ын савд бодитоор орсон, баталгаажсан түлшнээс үүснэ. Үүнээс гурван зүйл шууд гарна:

  1. Систем биелүүлж чадахгүй амлалт хэзээ ч өгөхгүй — амлалт нөөцөөсөө давахгүй.
  2. Хангалтаа бүртгүүлээгүй ШТС-д ваучер үүсэхгүй → хэрэглэгч очихгүй → мэдээлэхээс өөр сонголтгүй. Дуулгавартай байдал нь шалгагчаар биш, дизайнаараа албадагдана.
  3. Дараалал алга болно: хүн ирэхээсээ өмнө литр нь нөөцлөгдсөн байна.

Код дээр энэ нь чиглэлээр илэрхийлэгддэг: forecourt нь ваучерын тухай юу ч мэдэхгүй, харин хангалт баталгаажих агшинд main.go-д залгагдсан callback ваучерийн хөдөлгүүрийг дуудна. Ваучергүй байрлуулалт — хямрал өнгөрсний дараах бүх байрлуулалт — тэр callback нь nil байна.

Автомат үүсэлтийн гинж

Ваучер үүсэх гинж Тээврийн даалгавар хаагдаж, ATG савны түвшний өсөлтийг мэдээлснээр хангалт баталгаажиж, хуваарилах хөдөлгүүр боломжит литрийг тооцоолж, слот болгон хувааж, эрхтэй хэрэглэгчдэд эрэмбэлж санал болгоно. 1 · Тээвэр хаагдана ATG түвшний өсөлт ±0.3% 2 · Хангалт баталгаажив deliveries/{id}/confirm 3 · Хуваарилах хөдөлгүүр боломжит литрийг тооцно 4 · Слот болгон хуваана лимит ÷ үнэ = литр/слот 5 · Эрэмбэлж санал болгоно жинлэсэн оноо, шатлан 6 · 15 мин баталгаажуулалт үгүй бол пул руу буцна 7 · ШТС дээр redeem хошуу литрийг буцаана 8 · Ашиглагдаагүй нь хугацаа дуусмагц пул руу
Гинжний эхлэл нь хүний хүсэлт биш, савны түвшин. Тиймээс ваучерийн тоо нь бодлогын шийдвэр биш, хэмжилтийн үр дүн.

Гурав дахь алхмын тооцоо:

боломжит_литр = хүлээн_авсан
              − аль_хэдийн_нөөцлөгдсөн_ваучерийн_литр
              − техникийн_үлдэгдэл (dead stock)
              − тэргүүлэх_ангиллын_нөөц (%)

ваучерийн_литр = лимит_дүн (₮50,000) ÷ тухайн_үеийн_үнэ
слотын_тоо     = боломжит_литр ÷ ваучерийн_литр

Эрхийн дүрэм

Хэмжигдэхүүн Анхны утга Тохируулга
Нэгж эрх 1 иргэн (РД) × 1 тээврийн хэрэгсэл (улсын дугаар) Бодлого
Нэг удаагийн лимит ₮50,000 Дүн эсвэл литрээр
Давтамж 24 цагт 1 удаа Цаг/өдөр/7 хоног
7 хоногийн дээд хязгаар ₮150,000 Бодлого
Хүчинтэй хугацаа 6 цаг 1–48 цаг
Бүс Аймаг/дүүрэг Геозайгаар

Тэргүүлэх ангилал нь тусдаа квоттой, дарааллаас гадуур: түргэн тусламж, гал команд, цагдаа, онцгой байдал; нийтийн тээвэр, сургуулийн автобус; хүнс, эм, түлшний ачаа тээвэр; улирлын ХАА-н ургац хураалт, отор, өвөлжилт; уул уурхайн гэрээт хэрэглэгч (тусдаа B2B суваг).

Тээврийн хэрэгслийн ангиллаар литрийн коэффициент — суудлын 1.0×, микроавтобус 1.5×, ачааны 2.5×, автобус 4.0× — нь ₮50,000 гэдэг дүн Prius болон 20 тонны ачааны машинд ижил утгагүй байх асуудлыг шийднэ.

Хуваарилалтын оноо

оноо = w1 · ойролцоо_байдал(хэрэглэгч, ШТС)
     + w2 · хүлээсэн_хугацаа (сүүлд ваучер авснаас хойш)
     + w3 · тэргүүлэх_ангилал
     + w4 · бүсийн_хангамжийн_дутагдал
     − w5 · сүүлийн_үеийн_хэрэглээ (7 хоногт хэт олон авсан бол)

Төлөвийн машин

Ваучерийн төлөвүүд DRAFT, OFFERED, RESERVED, PRESENTED, DISPENSED, SETTLED гэсэн гол зам; LAPSED, EXPIRED, VOIDED нь пул руу буцаана. DRAFT OFFERED RESERVED PRESENTED DISPENSED SETTLED 15 мин LAPSED EXPIRED VOIDED пул руу буцна
Бүх шилжилт идемпотент (idempotency key-тэй): давхар дарсан товч, сүлжээ тасарсны дараах retry хоёр ваучер үүсгэхгүй.

QR ба офлайн баталгаажуулалт

QR дотор задлагдсан агуулга нь JSON биш — компакт CBOR + Ed25519 гарын үсэг, ~180 байт:

{
  v:  1,                      // хувилбар
  id: <ULID>,                 // ваучерийн ID
  s:  <станцын ID>,           // зөвхөн энэ ШТС-д
  p:  92,                     // бүтээгдэхүүн
  l:  2380,                   // дээд литр (centi-litre)
  a:  50000,                  // дээд дүн (₮)
  nb: <эхлэх unix ts>,
  na: <дуусах unix ts>,
  h:  <улсын дугаарын хэш, 6 байт>,
  n:  <nonce>
} + sig(Ed25519, 64 байт)

Сүлжээгүй үед ШТС-ын терминал гарын үсгийг локал шалгана: нийтийн түлхүүр нь /api/v1/fuelnet/voucher/public-key дээр байдаг ба терминал түүнийг хадгална. Ашигласан ваучерийн ID локал bloom filter + жагсаалтад үлдэж, холбогдмогц sync хийгдэнэ.

Энэ шалтгаанаар гарын үсгийн түлхүүр нь байрлуулалтын тохиргоо (FUELNET_VOUCHER_KEY), процессын үүсгэсэн зүйл биш: дахин асахдаа шинэ түлхүүр үүсгэвэл хүмүүсийн утсан дахь бүх ваучер хүчингүй болно — яг тэр үед, яг тэр шалтгаанаар процесс дахин асдаг.

Офлайн үед хоёр өөр ШТС дээр нэг ваучер ашиглах онолын боломжийг QR өөрөө хаадаг: s талбар нь ваучерыг тодорхой нэг станцад уяна.

Аппгүй хэрэглэгчид: SMS-ээр 8 оронтой богино код (HMAC, Луны шалгах цифртэй), USSD цэс, эсвэл ШТС-ын оператор улсын дугаар + РД-ээр гар аргаар хайх (аудит бүртгэлтэй).

Залилангийн эсрэг

Эрсдэл Илрүүлэлт Хариу арга хэмжээ
Савтай/канистртай худалдан авалт Урсгалын профиль (бак 30–40 л/мин, канистр богино тасалдалтай) Дохиолол, камерын шалгалт
Нэг машин олон РД-ээр Улсын дугаарын хэш давтамж 24 цагт 1 машин 1 удаа — хатуу
Нэг хүн олон машин ХУР-аас эзэмшлийн шалгалт Эзэмшигчээр 1 идэвхтэй эрх
Хуурамч тээврийн хэрэгсэл ХУР-ын бүртгэл, техникийн үзлэгийн төлөв Идэвхгүй ТХ-д эрх олгохгүй
ШТС-ын ажилтны залилан Redeem хийсэн vs хошууны бодит заалт Ажилтны скор, ээлжийн тулгалт
Хилээр гарах контрабанд Хилийн бүсийн хэвийн бус хэрэглээ Хилийн 50 км бүсэд тусдаа лимит
Тээвэрлэлтийн хулгай GPS зөрсөн зогсолт, ачсан/хүлээн авсан зөрүү Автомат тасалбар үүснэ
SIM/данс шилжүүлэлт Дугаар солигдох давтамж 24 цагийн хөргөлт

Sri Lanka-гийн гол сургамж: үндсэн танигчаар утасны дугаарыг сонгож болохгүй — дугаар дахин ашиглагддаг. Танигч нь тээврийн хэрэгслийн VIN/арлын дугаар + эзэмшигчийн РД.

Одоо кодод юу байгаа вэ

modules/voucher нь эрх, хуваарилалт, ваучерийн төлөв, офлайн шалгагдах пассыг хариуцна. API:

/api/v1/fuelnet/voucher   entitlements · vouchers/{id}/reserve · vouchers/redeem
                          public-key · policy

Хэрэглэгчийн апп, SMS/USSD нөөц суваг, ХУР-ын эзэмшлийн шалгалт, H3-д суурилсан ойролцоо байдлын эрэмбэ — эдгээр нь Фаз 2-т төлөвлөгдсөн бөгөөд одоогоор энд байхгүй.