Bulgan Trip

Хөгжүүлэгчийн заавар

Булган аймгийн үйлчилгээний газруудын мэдээллийг нээлттэй API-аас авч, өөрийн аппдаа харуулах, дарахад Bulgan Trip аппыг нээх заавар.

1. Хурдан эхлэх

Нэвтрэх шаардлагагүйТүлхүүр хэрэггүй Бүх endpoint нээлттэй, HTTPS. Үндсэн хаяг:

https://api.bulgan-trip.mn/api/v1

Гурван дуудлагаар бүх зүйл гарна:

# 1. Аймгийн id авна (одоогоор зөвхөн Булган)
curl -s "https://api.bulgan-trip.mn/api/v1/provinces"

# 2. Тэр id-гаар бүх өгөгдлийг нэг дор татна
curl -s "https://api.bulgan-trip.mn/api/v1/sync/snapshot?province=<province_id>&locale=mn"

# 3. Дараа нь өөрчлөгдсөн эсэхийг л шалгана (хөнгөн)
curl -s "https://api.bulgan-trip.mn/api/v1/sync/manifest?province=<province_id>"

2. Өгөгдөл татах

Аймаг — GET /provinces

[
  {
    "id": "4e3af807-59c2-40dc-8bcc-7d613f2bacdd",
    "code": "bulgan",
    "name_mn": "Булган",
    "name_en": "Bulgan",
    "status": "active"
  }
]

Одоогоор зөвхөн Булган идэвхтэй. Энэ id-г доорх дуудлагуудад хэрэглэнэ.

Бүх өгөгдөл — GET /sync/snapshot?province=<id>&locale=mn

Жагсаалт барихад энэ нэг дуудлага хангалттай.

Ойролцоогоор 500 КБ, бүх идэвхтэй газар, ангилал, сум, маршрут, арга хэмжээг агуулна. Хариу:

{
  "synced_at":   "2026-09-29T11:57:38Z",
  "province_id": "4e3af807-…",
  "categories":  [ … 15 ],
  "districts":   [ … 16 ],
  "places":      [ … 163 ],
  "routes":      [ … ],
  "events":      [ … ]
}

places дотор зөвхөн нийтлэгдсэн, идэвхтэй газрууд ирнэ. Нуусан эсвэл устгасан газар огт орохгүй тул тусад нь шүүх шаардлагагүй.

Өөрчлөлт шалгах — GET /sync/manifest?province=<id>

{
  "province_id": "4e3af807-…",
  "updated_at":  "2026-09-29T09:14:45Z",
  "counts": { "places": 163, "categories": 15, "routes": 2, "events": 3 }
}

Хэдхэн байт. updated_at өөрчлөгдсөн үед л snapshot-ыг дахин татна. Өдөрт нэг удаа шалгахад хангалттай.

Шүүлттэй жагсаалт — GET /places

Сервер талаас шүүх, хайх, хуудаслах шаардлагатай бол:

GET /places?locale=mn&page=1&page_size=50
GET /places?locale=mn&q=рашаан
GET /places?locale=mn&category=<category_id>
GET /places?locale=mn&lat=48.8125&lng=103.5347          # зайгаар эрэмбэлнэ
GET /places?locale=mn&lat=…&lng=…&radius_km=10          # ойролцоох

Хариу нь { "items": [...], "page": 1, "page_size": 50 }. lat/lng өгвөл газар бүрт distance_m нэмэгдэнэ — энэ нь замаар явах бодит зай (шулуун шугамын зай биш), метрээр. page-ийг үргэлж тодорхой бичиж өгнө үү.

3. Газрын бүтэц

Хамгийн их хэрэглэгддэг талбарууд:

ТалбарУтга
idUUID. Хэзээ ч өөрчлөгдөхгүй. Өөрийн талдаа энэ id-гаар холбоно.
deeplinkАппыг нээх холбоос. Доорх 4-р хэсгийг үзнэ үү.
translationsmn, en, ko, zh, ru түлхүүртэй. Тус бүрд name, short_desc, description.
location{ "lat": 49.169, "lng": 102.351 }
cover_image_urlҮндсэн зургийн бүтэн URL. Байхгүй бол null.
imagesБүх зураг: { id, url, is_cover, sort_order }
category_idSnapshot-ийн categories жагсаалттай тааруулна.
district_idСум. districts жагсаалттай тааруулна.
contacts[{ "type": "phone", "value": "95826063" }] — дугаар бүр тусдаа мөр.
price_statusfree | paid | unknown
price_min, price_maxҮнийн хязгаар. price_currency ихэвчлэн MNT. Байхгүй бол null.
is_24h, open_time, close_timeАжиллах цаг. Цаг нь "09:00" хэлбэртэй, Улаанбаатарын цагаар.
slugБитгий хадгалаарай. Админаас гараар засагддаг тул хожим өөрчлөгдөж болно. Танигчаар зөвхөн id хэрэглэнэ.

Газар бүрийн deeplink талбарыг хэвээр нь хэрэглэнэ. Өөрөө URL угсрахгүй.

"deeplink": "https://bulgan-trip.mn/place/4a569305-c799-4529-9d9d-534e6c9e44d5"

Энэ бол энгийн HTTPS холбоос. Хэрэглэгч дээр нь дарахад:

Сонгох цонх гарахгүй, «апп олдсонгүй» алдаа гарахгүй. Та апп суусан эсэхийг шалгах шаардлагагүй — үүнийг үйлдлийн систем өөрөө хийнэ.

Нээх код

// Android (Kotlin)
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(place.deeplink)))
// iOS (Swift)
if let url = URL(string: place.deeplink) {
    UIApplication.shared.open(url)
}
// Flutter
import 'package:url_launcher/url_launcher.dart';
await launchUrl(Uri.parse(place.deeplink), mode: LaunchMode.externalApplication);
<!-- Вэб -->
<a href="https://bulgan-trip.mn/place/4a569305-…">Дэлгэрэнгүй</a>

Анхаарах: холбоосыг WebView дотор биш, гадаад байдлаар нээнэ үү (Flutter дээр LaunchMode.externalApplication). WebView дотор нээвэл апп руу шилжихгүй, зүгээр вэб хуудас болж харагдана.

Мөн bulgan-trip:// гэсэн схем байдаг ч түүнийг хэрэглэхгүй: апп суулгаагүй үед чимээгүй бүтэлгүйтдэг тул fallback байхгүй.

5. Хэл ба зураг

Хэл. Snapshot-д 5 хэлний орчуулга бүгд ирдэг тул хэл солиход дахин татах шаардлагагүй — translations дотроос сонгоод харуулна. Хэрэв тухайн хэлэнд орчуулга байхгүй бол mn-г хэрэглэнэ.

Зураг. Бүх зураг https://cdn.bulgan-trip.mn/… дээр байрлана, шууд ачаалж болно. Хэмжээ өөрчлөх параметр байхгүй тул өөрийн талдаа кэшлэх, багасгахыг зөвлөе. Зураггүй газар байж болох тул cover_image_url нь null байх тохиолдлыг заавал бодолцоорой.

6. Дүрэм, хязгаарлалт

ДүрэмУчир нь
GET /places/:id-г давтан бүү дуудДуудалт бүр тухайн газрын үзэлтийн тоог нэмдэг тул манай статистик гуйвна. Жагсаалтаа snapshot-оос ав.
Өгөгдлийг өөртөө кэшлэКонтент өдөр бүр өөрчлөгддөггүй. manifest-ээр шалгаад шаардлагатай үед л snapshot тат.
Танигчаар id хэрэглэslug өөрчлөгдөж болно, id өөрчлөгдөхгүй.
deeplink-ийг хэвээр нь хадгалФорматыг бид цаашид өөрчилж болно. Талбарыг нь хэрэглэвэл танд өөрчлөлт хэрэггүй.
Эх сурвалжаа дурдМэдээлэл Bulgan Trip-ээс гаралтай гэдгийг хэрэглэгчдэд ойлгомжтой байлгана уу.

Дуудлагын хязгаар. IP хаяг тус бүрээр:

EndpointХязгаар
/sync/snapshot, /routing/*минутад 30
бусад бүх нээлттэй endpointминутад 240

Хэвийн ашиглалтад хүрэхгүй тоо. Хэтэрвэл 429 Too Many Requests буцаах бөгөөд Retry-After толгойд хэдэн секунд хүлээхийг бичнэ. Жагсаалтаа snapshot-оос нэг удаа татаад кэшлэвэл энэ хязгаарт огт ойртохгүй. Илүү өндөр хязгаар хэрэгтэй бол урьдчилж бидэнтэй холбогдоно уу — таныг таних боломжтой болгож өгье.

Өөрийгөө танируулах. Хүсэлт бүрдээ X-Client толгойд аппынхаа нэр, хувилбарыг бичиж өгвөл баярлалаа (жишээ нь X-Client: tavan-bogd-app/2.1). Заавал биш, гэхдээ асуудал гарвал хэний трафик болохыг ялгаж, танд тусална.

CORS. Хөтчөөс шууд (browser fetch) дуудах бол таны домэйныг манай зөвшөөрөгдсөн жагсаалтад нэмэх шаардлагатай — бидэнд домэйноо илгээнэ үү. Гар утасны эсвэл серверийн талын дуудлагад энэ хамаарахгүй.

7. Холбоо барих

Асуулт, домэйн нэмүүлэх, алдаа мэдээлэх: info@bulgan-trip.mn

Апп: bulgan-trip.mn · Ашиглалтын заавар