* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
101 KiB
Radar Free-Model Catalog (Հայերեն)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Ճշմարտության աղբյուր՝
src/lib/radar/,src/lib/db/radar.ts,src/app/api/radar/Վերջին թարմացումը՝ 2026-09-01 — v3.8.51 Հոսթավորված ծառայության ապացույցների սահմանը՝ այստեղ նկարագրված սերվերային կանոնները ստուգվել են 2026-09-01-ին՝ միտումնավոր փակ Radar սերվերի նկատմամբ՝ ճշգրիտmain@dce70f004364912f3f144cdb69f4cbcde16093edվերանայմամբ։ Այդ իրականացումը չի տարածվում այս OSS շտեմարանում․ հոսթավորված հասանելիությունը մնում է առանձին գործառնական վիճակ։
Radar-ը ընտրովի հավելում է, որը թողարկման ելակետային կատալոգի
(FREE_MODEL_BUDGETS՝ open-sse/config/freeModelCatalog.data.ts-ում) վրա վերադրում է ստորագրված,
թարմ ընտրված անվճար մոդելների կատալոգ։ Այն գոյություն ունի, քանի որ անվճար մակարդակի դաշտն
ավելի արագ է փոփոխվում, քան թողարկումների հաճախականությունը․ մատակարարները թողարկումների
միջև ավելացնում, կրճատում կամ դադարեցնում են անվճար քվոտաները, իսկ ելակետային կատալոգը
կարող է թարմացվել միայն նոր տարբերակի թողարկման ժամանակ։
Հեռակա հոսքի պատճառով այսօր անվճար որևէ բան չի դադարում անվճար լինել։ Radar-ը երբեք վճարովի հասանելիության պատնեշ չի սահմանում ելակետային գրառման համար․ այն միայն ընթերցման ժամանակ թարմացնում է սահմանաչափերի/կարգավիճակի դաշտերը և կարող է թողարկումների միջև ավելացնել նոր հայտնաբերված անվճար մոդելներ։ Օպերատորը նախկինի պես կարող է տեղային կերպով թաքցնել մոդելը և վերականգնել այն նույն կառավարման վահանակից։ Ելակետային կատալոգն ինքնին երբեք չի փոփոխվում սկավառակի վրա․ ստորև տե՛ս Ընթերցման ժամանակ վերադրման միաձուլման կանոնները։
Մատակարարման կարգավիճակը v3.8.51-ում
Հետևյալ կարգավիճակը տարբերակում է այն, ինչ իրականացնում է այս OSS թողարկումը, Radar-ի հետագա աշխատանքային ուղղություններից։ Սա կոդի մակարդակի կարգավիճակ է, այլ ոչ թե խոստում, որ տվյալ հոսթավորված տեղակայումը կամ արտաքին ինտեգրումը ներկայումս հասանելի է։
| Ոլորտ | Կարգավիճակն այս թողարկման մեջ |
|---|---|
| Ստորագրված կատալոգի հաճախորդ | Իրականացված է RADAR_ENABLED-ի ներքո՝ առանձին համաձայնությամբ, Ed25519 ստուգմամբ, տեղային գաղտնագրված կարգավորումներով/քեշով, ցուցադրման/միացման մշտական վերագրումներով, հետադարձելի տապանաքարերով, ժամանակացույցիչով և կառավարման վահանակով։ |
| Մասնակցի ակտիվացում | Կառավարման վահանակը հղվում է սերվերում հոսթավորված GitHub պահանջի հոսքին և ընդունում առկա omr_… բանալի։ Մասնակցի իրավասությունը որոշվում է փակ ծառայության կողմից․ OSS հաճախորդը չի պարունակում GitHub թոքեն կամ տրամադրման տրամաբանություն։ |
| Աջակցողի բանալիով ակտիվացում | Իրականացված է։ Չմշակված բանալին վավերացվում է, գաղտնագրվում է պահպանման ժամանակ, ընթերցման ժամանակ դիմակավորվում է և ուղարկվում է միայն սերվերային համաժամացման միջոցով։ Բանալին փոխելը կամ մաքրելը անվավեր է դարձնում իրավասություններից կախված հոսքերի բոլոր չորս քեշերը։ |
| Ուղղորդման հղումներ | Իրականացված է որպես առանձին ստորագրված, ամեն ժամ թարմացվող հոսք։ Ամրագրված հղումները համայնքային մակարդակին հասանելի են անմիջապես․ սահմանափակ արշավները մնում են ուղիղ մակարդակի տվյալներ։ |
| Աջակցողների առաջարկներ | Իրականացված է որպես առանձին ստորագրված, միայն ուղիղ ռեժիմով հասանելի հոսք և կառավարման վահանակի էջ։ Հաճախորդը կրկին վավերացնում է նպաստների փակ սխեման, պահպանում վերջին վավեր քեշը, զտում ժամկետանց գրառումները և հստակ նշում գործընկերների առաջարկները։ |
| Տեղեկատվություն և աջակցողների ճանաչում | Իրականացված է որպես խիստ ստորագրված, միայն ուղիղ ռեժիմով հասանելի հոսք՝ Radar-ին պատկանող ELO-ով, կատալոգի թարմության/միտումների փաստացի տվյալներով, ստուգված տեղային աջակցողի կրծքանշանով, կառավարման վահանակի էջով և միայն տեղային CLI կարգավիճակի/համաժամացման հրամաններով։ |
| Վճարումներ և գործարքային էլփոստ | OSS հաճախորդում իրականացված չէ։ Գնումը, նվիրատվությունը, անդորրագրի ստուգումը, վերականգնումը և նամակների առաքումը պատկանում են փակ ծառայությանը․ հոսթավորված հասանելիությունը դեռևս կախված է դրա վերահսկվող տեղակայումից և մատակարարի կազմաձևումից։ |
| Հետազոտական գործակալի աշխատանքային ուղղություն | Այս հաճախորդի թողարկման մաս չէ։ Ընտրված հոսքի բովանդակությունը մնում է սերվերային տվյալ․ OmniRoute-ի տեղադրման մեջ ինքնավար հետազոտական գործակալ չի աշխատում։ |
Հանրային հայտարարությունների ընթերցիչ
Հայտարարությունների ընդհանուր ընթերցիչն առանձին է Radar գործառույթի դրոշակից։ Վահանակի Home և
Changelog դիտիչները պահոցից վերցնում են հանրային news.json-ը՝ սովորական GET հարցում կատարելով դեպի
NEWS_JSON_URL (src/shared/utils/releaseNotes.ts)։ Դրանք չեն ուղարկում Radar-ի որևէ կարգավորում, հուշում, մատակարարի
կազմաձևում, օգտագործման գրառում կամ տեղային մերժման վիճակ։
news.json-ն օգտագործում է parseNewsPayload()-ում իրականացված փակ v2 սխեման՝
schemaVersion: 2և սահմանափակitems[]հավաքածու,- հայտարարությունների կայուն և եզակի
idարժեքներ, - բացահայտ
activeև ISO ձևաչափովpublishedAtդաշտեր, - պարտադիր անգլերեն տեքստ՝ ընտրովի տեղայնացված տարբերակներով,
- ընտրովի՝ հավատարմագրեր չպահանջող HTTPS հղումներ և թույլատրված ցանկում ներառված պատկերակ,
- սկզբում ամենանոր ակտիվ տարրի ընտրություն, լեզվային կարգավորումների դեպքում անցում անգլերենի և յուրաքանչյուր ID-ի համար տեղային մերժում։
Վերլուծիչը ժամանակավորապես ընդունում է նաև նախկին եզակի { active, title, message, ... } կառուցվածքը, որպեսզի
ավելի հին ֆորքերը կարողանան տեղափոխվել՝ առանց Changelog դիտիչը խափանելու։ Անվավեր հոսքերն անգործուն են։ Radar-ի գործարկման
գրառումը մատակարարվում է active: false արժեքով․ այն true դարձնելն առանձին՝ միավորումից և տեղակայումից հետո կատարվող
թողարկման գործողություն է և չի փոխում RADAR_ENABLED-ը կամ հոսքի համաժամացման անկախ մասնակցության կարգավորումը։
Դրոշակ՝ RADAR_ENABLED (լռելյայն անջատված)
Radar-ը սկզբից մինչև վերջ սահմանափակվում է RADAR_ENABLED գործառույթի դրոշակով
(src/shared/constants/featureFlagDefinitions.ts, կատեգորիա՝ policies,
defaultValue: "false")։
Երբ դրոշակն անջատված է, այս գործառութային մակերեսը գոյություն չունի․
- Բոլոր
/api/radar/*վերջնակետերը, ներառյալ մոդելի տեղային վիճակի ընթերցումներն ու գրառումները, վերադարձնում են404՝ նախքան Radar-ի որևէ մոդուլ օգտագործելը։ - Վահանակի էկրանները (
/dashboard/radar,/dashboard/radar/setup,/dashboard/radar/combos,/dashboard/radar/offers,/dashboard/radar/intel) արտապատկերում ենnotFound()։ getRadarCatalog()-ը (src/lib/radar/index.ts) վերադարձնում է չփոփոխված ելակետային տարբերակը՝ գրառումների նույն քանակով, նույն արժեքներով և յուրաքանչյուր գրառման վրաorigin: "baseline"նշումով, ու երբեք չի կարդում հոսքի քեշը։- Radar-ի ցանցային որևէ հարցում երբեք չի կատարվում․ համաժամացման յուրաքանչյուր մոդուլ վերադարձնում է
{ status: "disabled" }նախքանfetch-ին դիմելը։
Սա խիստ վերադաս սահմանափակիչ է․ դրոշակը միացնելը հասանելի է դարձնում միայն էկրանները և ոչինչ ավելին։ Այն տվյալներ չի վերբեռնում, ֆոնային համաժամացում չի սկսում և չի փոխում երթուղավորումը կամ մոդելի ընտրությունը․ տե՛ս ստորև նկարագրված առանձին մասնակցության կարգավորումը։
Տվյալների համաժամացումն ԱՌԱՆՁԻՆ մասնակցության կարգավորում է՝ գաղտնիության խոստումը
RADAR_ENABLED-ը միացնելը միայն հասանելի է դարձնում միջերեսը։ Հոսքի համաժամացումը պահանջում է երկրորդ՝
անկախ մասնակցության կարգավորում, որը պահվում է radar_settings.opt_in-ում (src/lib/db/radar.ts,
միգրացիա՝ 136_radar_cache_settings.sql)։ syncRadar()-ը ստուգում է դրոշակը և մասնակցության
կարգավորումը՝ նախքան որևէ ցանցային հարցում կատարելը․
Դրոշակն անջատված է → { status: "disabled" } — ցանցային հարցում չկա
Մասնակցությունն անջատված է → { status: "opt_out" } — ցանցային հարցում չկա
Երբ երկուսն էլ միացված են, համաժամացման ընթացքը հետևյալն է․
GET <feed base URL>/v1/catalog/latest՝x-omniroute-radar-schema: 2-ով և ընտրովիAuthorization: Bearer <supporter key>վերնագրով (տե՛ս ստորև)։ Երբ սխեմայի վերնագիրը բացակայում է, սերվերները լռելյայն տրամադրում են առանձին ստորագրված v1 անցումային արտեֆակտը, որպեսզի ավելի հին տեղադրված հաճախորդները շարունակեն թարմացումներ ստանալ։- Սա միայն ներբեռնման համար նախատեսված հավելվածային հոսք է, սակայն այն, միևնույն է, HTTPS հարցում է։ Հոսթինգ իրականացնող ենթակառուցվածքը ստանում է կապի սովորական մետատվյալներ, օրինակ՝ սկզբնաղբյուր IP-ն։ Երբ աջակիցների բանալի է կազմաձևված, համաժամացումը նաև այդ բանալին ուղարկում է Bearer վերնագրում, որպեսզի ծառայությունը կարողանա որոշել հասանելիության իրավունքը։ Վերևում նշված ապացույցների սահմանի մեջ նույնականացված մասնավոր սերվերի ճշգրիտ վերանայման տարբերակում հոսքի հարցումների հաշվառումն օգտագործում է բանալիների հեշեր, համախմբված օգտագործման տվյալներ և IP-ի՝ օրական փոփոխվող կրճատված HMAC՝ չարաշահումների ձեռքով ստուգման համար․ այդ աղյուսակներում ո՛չ բանալին, ո՛չ IP-ն չմշակված ձևով չեն պահպանվում։ Ենթակառուցվածքի հասանելիության մատյաններն ու առաքման կոդավորված ելքային հերթն առանձին գործառնական սահմաններ են։
- OmniRoute-ը երբեք Radar ծառայությանը չի ուղարկում հուշումներ, պատասխաններ, խոսակցություններ, մատակարարի հավատարմագրեր, մոդելի թրաֆիկ, հասանելիության ժամանակ, ուշացում կամ մատակարարի տեղային կազմաձևումը։
- Պատասխանը ստուգվում, վավերացվում և տեղային կերպով քեշավորվում է (տե՛ս
Անվտանգության մոդել)։ Radar-ն ունի սերվերային կողմի ուղիղ չորս ցանցային ուղի՝
syncRadar()՝ կատալոգի համար,syncRadarReferrals()՝ ուղղորդումների համար, ևsyncRadarOffers()/syncRadarIntel()՝ միայն աջակիցների համար նախատեսված առաջարկների ու Intel-ի համար։
Աջակցի բանալին ընտրովի Bearer նշան է (radar_settings.supporter_key),
որը հոսքի ծառայությանը թույլ է տալիս որոշել, թե որ մակարդակը տրամադրել (տե՛ս
Մակարդակներ)։ Այն՝
- Պահվում է կոդավորված վիճակում՝ օգտագործելով նույն AES-256-GCM
encrypt()/decrypt()օգնականները (src/lib/db/encryption.ts), որոնք կիրառվում են մատակարարների հավատարմագրերի համար։ - Սահմանվում է
POST /api/radar/settings-ի միջոցով ({ supporterKey: "omr_" + 40 hex chars }) և երբեք հետ չի վերադարձվում․ պատասխանը վերադարձնում է քողարկված ձև (omr_****abcd)։ - Դրա փոփոխումը կամ մաքրումը ատոմային կերպով անվավեր է դարձնում կատալոգի, ուղղորդումների, առաջարկների և Intel-ի քեշերը։ Հաջորդ համաժամացումը կամ ընթերցումը սերվերային կողմում որոշում է հասանելիության նոր իրավունքը․ բանալի պահելն ինքնին ցանցային հարցում չի կատարում և չի սպառում մեկանգամյա ակտիվացման բանալի։
- Համաժամացման GET հարցման ժամանակ ուղարկվում է հոսքի ծառայությանը որպես Bearer նշան․ բանալիին վերաբերող որևէ այլ բան երբեք չի լքում հաճախորդը։
Միացումից առաջ ցուցադրվող հասանելիության և անվտանգության կանոնները
Ոչ ակտիվ կառավարման վահանակը ցուցադրում է այս կանոնները
src/app/(dashboard)/dashboard/radar/RadarAccessExplainer.tsx-ից՝ նախքան ակտիվացման գործողություններից որևէ մեկը։
Հասանելիության կանոնական սանդղակն է՝
| Մակարդակ | Իրավասության պայման | Հասանելիություն | Կրկնման/ժամկետի ավարտի կանոն |
|---|---|---|---|
| Համայնք | Ցանկացած անձ․ բանալի չի պահանջվում | Ամբողջական կատալոգը հասանելի է մոտ 30 օր ուշացումով | Միշտ հասանելի է․ տրամադրում չի կատարվում |
| Աստղ + հետևում | GitHub OAuth-ը հաստատում է և՛ պահոցին տրված աստղը, և՛ դրա սեփականատիրոջը հետևելը | Կատալոգի մեկ ընթացիկ ընթերցում, այնուհետև՝ Համայնք | Մեկ տրամադրում՝ յուրաքանչյուր մուտքի համար․ երբեք չի վերատրամադրվում |
| Ներդրող՝ լավագույն 10 | Վերջին ամբողջական շաբաթական վարկանիշում 1–10-րդ տեղերը | 365 օր ընթացիկ հասանելիություն | Ստացվում է ըստ պահանջի․ վարկանիշից դուրս մնալը չի կրճատում արդեն շնորհված ժամանակահատվածը |
| Ներդրող՝ լավագույն 100 | Այդ վարկանիշում 11–100-րդ տեղերը | 90 օր ընթացիկ հասանելիություն | Նույն՝ ըստ պահանջի/իդեմպոտենտ ստացման կանոնը |
| Աջակցողի գնում | 6 ամսվա, 1 տարվա կամ ցմահ հասանելիության մեկանգամյա գնում | Ընթացիկ կատալոգ, ստորագրված ընթացիկ առաջարկներ և Intel | Ինքնաշխատ երկարաձգում չկա |
| Նվիրատվություն/ձեռքով տրամադրում | Սեփականատիրոջ կողմից ստուգված նվիրատվություն կամ սեփականատիրոջ տրամադրում՝ հստակ օրերի քանակով/ցմահ | Նույն ընթացիկ իրավունքը՝ տրամադրված ժամանակահատվածի համար | Աուդիտավորված, իդեմպոտենտ տրամադրում |
Միավորված PR-երը, commit-ները և փոփոխված տողերը միայն վարկանիշի մուտքային տվյալներ են։ Լավագույն 100-ից դուրս գտնվող մուտքը ներդրողի տրամադրում չի ստանում՝ անկախ PR-երի քանակից։ Սահմանափակ ժամկետով գնումները, նվիրատվությունները, ներդրողի ժամանակահատվածները և ձեռքով տրամադրումները գումարվում են ընթացիկ ժամկետի ավարտից սկսած․ ցմահ հասանելիությունը գերակայում է։ Վարկանիշի փոփոխությունը երբեք հետադարձ ուժով չի չեղարկում կամ կրճատում արդեն շնորհված ժամանակը։
Հոսթինգով տրամադրվող արտոնագիրը անձնական է, իսկ օգտատիրոջը ցուցադրվող կանոնը՝ միաժամանակ մեկ ակտիվ տեղադրում։ Այս թողարկումը չի պնդում, որ առկա է սարքաշարային արգելափակում․ OSS համաժամացումը չի նույնականացնում սարքաշարը և չի պահպանում կրիպտոգրաֆիկ սարքային վարձակալություն։ Վերը նշված՝ մասնավոր սերվերի հաստատված վերանայման տարբերակում իրականացված վերահսկումը իրավունքի վավերացումն է՝ գումարած ձեռքով ստուգման ազդանշանը, երբ նույն ընթացիկ բանալին 24 ժամվա ընթացքում նկատվում է չորրորդ տարբեր IP հասցեից։ Այդ ազդանշանը երբեք ինքնաշխատ չի արգելափակում կամ չեղարկում բանալին։ Վերականգնումը չեղարկում և փոխարինում է կորցրած բանալին՝ պահպանելով առկա ժամկետի ավարտը․ այն չի վերագործարկում գնված կամ տրամադրված ժամանակահատվածը։
Ընթացիկ առաջարկները ձեռքով են ընտրվում և կարող են փոխվել կամ ժամկետանց դառնալ։ Միացման էկրանը նաև նշում է գաղտնիության ճշգրիտ սահմանը․ ստորագրված կատալոգի/ուղղորդման մետատվյալները ներբեռնվում են․ վավեր բանալին լրացուցիչ ապակողպում է ստորագրված առաջարկներն ու Intel-ը․ Bearer բանալին և կապի սովորական մետատվյալները հասնում են հոսթինգով տրամադրվող ծառայությանը․ հարցումները, պատասխանները, խոսակցությունները, մատակարարի հավատարմագրերը, մոդելի թրաֆիկը, անխափան աշխատանքի ժամանակը, ուշացումը և տեղական մատակարարի կազմաձևումը՝ ոչ։
Աջակցողի բանալի ստանալը
Ակտիվացման էկրանը (/dashboard/radar) հղումներ է տրամադրում աջակցության բանալի ստանալու երկու գործընթացների համար։
OSS ռեպոզիտորիան ինքը երբեք բանալի չի տրամադրում, վճարման կոդ չի գործարկում և
երբեք գին չի նշում. գները որոշվում և ամբողջությամբ ցուցադրվում են նպատակային
էջերում, այլ ոչ թե այս ռեպոզիտորիայում (ճշգրտման որոշում D14)։
- «Ես ներդրող եմ» — բացում է
RADAR_CONTRIBUTOR_CLAIM_URL-ը (լռելյայն՝https://radar.omniroute.online/auth/github)՝ GitHub OAuth-ի միջոցով պահանջ ներկայացնելու գործընթաց, որը հոսթինգ է արվում մասնավոր Radar սերվերում։ Այն ստուգում է վերջին ամբողջական շաբաթական վարկանիշը. լավագույն 10-ը ստանում են 365 օր, իսկ 11–100-րդ տեղերը՝ 90 օր։ Լավագույն 100-ից դուրս PR-ների քանակը երբեք հասանելիություն չի տրամադրում. գործընթացը դրա փոխարեն ստուգում է առանձին՝ աստղ + հետևում մեկանգամյա մակարդակը։ - «Աջակցել նախագծին» — բացում է
RADAR_SUPPORTER_PLANS_URL-ը (լռելյայն՝https://radar.omniroute.online/planos)՝ մեկանգամյա 6-ամսյա, 1-ամյա և ցմահ տարբերակների հոսթինգով էջը։ OSS էջը նախկինի պես որևէ դրամական արժեք չի ցուցադրում։
Երկու URL-ներն էլ որոշվում են սերվերի կողմում (src/lib/radar/links.ts, միջավայրի միջոցով
վերասահմանման նույն ձևանմուշը, ինչ RADAR_FEED_URL-ի դեպքում) և փոխանցվում են կառավարման վահանակին՝ գոյություն ունեցող
GET /api/radar/settings պատասխանի միջոցով (contributorClaimUrl, supporterPlansUrl) —
հաճախորդային բաղադրիչն ինքը երբեք չի կարդում process.env-ը։
| Փոփոխական | Նպատակ |
|---|---|
RADAR_CONTRIBUTOR_CLAIM_URL |
Վերասահմանում է ներդրողի պահանջի URL-ը (լռելյայն՝ https://radar.omniroute.online/auth/github)։ |
RADAR_SUPPORTER_PLANS_URL |
Վերասահմանում է աջակցողի պլանների URL-ը (լռելյայն՝ https://radar.omniroute.online/planos)։ |
Կորցրած աջակցողի բանալու վերականգնումը
Հոսթինգով ծառայության վերականգնման մուտքի կետն է https://radar.omniroute.online/recover-ը. դրա հղումը
նաև առկա է պլանների էջում։ Վերականգնումն ամբողջությամբ մնում է OSS հաճախորդից դուրս, քանի որ տեղական
տեղադրումը երբեք չի ստանում գնորդի/ներդրողի էլեկտրոնային փոստի հասցեն և չի կարող իր
գաղտնագրված կարգավորումներից վերականգնել չմշակված բանալին։
- Ներկայացրեք բանալու հետ կապված էլեկտրոնային փոստի հասցեն։ Ծառայությունը վերադարձնում է նույն ընդունման էջը՝ անկախ նրանից՝ վերականգնվող արտոնագիր գոյություն ունի, թե ոչ, ուստի ձևը չի թվարկում հաշիվները։
- Համապատասխանության դեպքում առաքման աշխատակարգը ուղարկում է կարճաժամկետ, մեկանգամյա օգտագործման հղում։ Այն բացելուց անմիջապես հետո
նշանը տեղափոխվում է անցողիկ, գաղտնագրված
HttpOnly/Securecookie-ի մեջ, ապա կատարվում է վերահղում դեպի մաքուր/recoverURL-ը. էջը չի պարունակում նշան, էլեկտրոնային փոստի հասցե, հին բանալի կամ փոխարինող բանալի։ - Հաստատեք չեղարկումը։ Մասնավոր ծառայությունը չեղարկում է նախորդ բանալին, ստեղծում նույն պլանով/վավերականության ժամկետով փոխարինողը և մեկ գործարքի շրջանակում այն հերթագրում է էլեկտրոնային փոստով ուղարկելու համար։ Փոխարինողը երբեք չի վերադարձվում դիտարկիչին։
- Տեղադրեք փոխարինողը
/dashboard/radar-ում։ Հին բանալին այժմ պետք է իջեցվի մինչևcommunity, իսկ փոխարինողը պետք է ապահովի ստուգվածliveհամաժամացում։ Վերականգնման նույն հղումը կրկին բացելը պետք է ձախողվի՝ ցուցադրելով անվավեր/ժամկետանց լինելու ընդհանուր պատասխան։
Հոսթինգով վերականգնման երթուղին և փոստային աշխատակարգը կարող են առկա լինել կոդում, բայց միևնույն ժամանակ հասանելի չլինել տվյալ տեղակայման մեջ։ Գործընթացը պատրաստ մի համարեք արտադրական օգտագործման համար, քանի դեռ սերվերը չի տեղակայվել, առաքման մատակարարը չի կազմաձևվել վերահսկվող ստացողի միջոցով, և ամբողջական մեկանգամյա օգտագործման հղումը չի փորձարկվել։
Երբ այցելուն ունի բանալի (omr_ + 40 տասնվեցական նիշ), ակտիվացման էկրանի
(src/app/(dashboard)/dashboard/radar/page.tsx) հիմնական ուղին բանալին տեղադրելու մուտքագրման դաշտն է.
բանալին տեղադրելուց և ներկայացնելուց հետո մեկ հարցմամբ ուղարկվում է POST /api/radar/settings
({ optIn: true, supporterKey }) — բանալին տեղադրելը միաժամանակ և՛ սահմանում է այն, և՛ միացնում մասնակցությունը՝
ապակողպելով էկրանը։ Ձևաչափը (omr_ + 40 տասնվեցական նիշ) նախ ստուգվում է հաճախորդի կողմում՝
UX-ը բարելավելու նպատակով, համօգտագործվող isValidSupporterKeyFormat() օգնականի միջոցով (src/lib/radar/supporterKey.ts).
ամեն դեպքում սերվերի Zod սխեման հեղինակավոր ստուգումն է։ Բանալին
սահմանելուց հետո ակտիվացման էկրանը դատարկ մուտքագրման դաշտի փոխարեն ցուցադրում է քողարկված ձևը (supporterKeyMasked՝
GET /api/radar/settings-ից)՝ նոր բանալի տեղադրելու համար նախատեսված «փոխել բանալին» կառավարման տարրով.
չմշակված բանալին երբեք կրկին չի ցուցադրվում։ Վերևում գտնվող պահանջի/պլանների երկու կոճակները
շարունակում են մնալ բանալի ստանալու սկզբնական միջոցը. այս մուտքագրման դաշտն այն վայրն է, որտեղ արդեն
բանալի ունեցող օպերատորն ակտիվացնում է այն։
Ծայրից ծայր ակտիվացում և ուղղորդվող կարգավորում
Մասնավոր հոսքի ծառայության և այս OSS հաճախորդի միջև սահմանը միտումնավոր նեղ է. ծառայությունը տրամադրում և վավերացնում է աջակցողի բանալին, իսկ տեղական OmniRoute տեղադրումը գաղտնագրում է բանալին, սերվերի կողմում համաժամացնում ստորագրված արտեֆակտները և ուղղորդում մատակարարի կարգավորումը։ Աջակցվող վավերացման հերթականությունն է.
- Ստացեք նոր թողարկված կամ վերականգնված բանալի մասնակցի հայտից, plans/checkout-ից, վերականգնման գործընթացից կամ լիազորված մասնավոր սերվերի օպերատորից։ Չմշակված բանալին մի տեղադրեք մատյաններում, սքրինշոթներում, խնդրի մեկնաբանություններում կամ հրամանի տողի արգումենտներում։
- Տեղական OmniRoute տեղադրման մեջ միացրեք
RADAR_ENABLEDհնարավորության դրոշակը։ Սա հասանելի է դարձնում միջերեսը, սակայն ցանցային առումով մնում է անգործուն, մինչև առանձին մասնակցության համաձայնությունը պահպանվի։ - Բացեք
/dashboard/radar-ը, տեղադրեք բանալին և ակտիվացրեք։ Դիտարկիչը տեղային կերպով ուղարկում է մեկPOST /api/radar/settingsհարցում՝{ optIn: true, supporterKey }բովանդակությամբ․ բանալին տեղային կերպով գաղտնագրվում է, իսկ պատասխանը պարունակում է միայնomr_****<last4>։ - Թույլ տվեք, որ ակտիվացման էկրանը կատարի կատալոգի համաժամացումը, կամ ընտրեք Համաժամացնել հիմա։ Համոզվեք, որ էջը
ցուցադրում է
live, հոսքի տարբերակը և ստացման ժամանակը։ Նույնականացված տեղային ախտորոշման համարGET /api/radar/status-ը հաղորդում է մասնակցության համաձայնության/բանալու առկայության և քեշի չորս վիճակների մասին՝ առանց բանալին վերադարձնելու։POST /api/radar/sync-all-ը կարող է բացահայտորեն թարմացնել կատալոգը, ուղղորդումները, առաջարկները և Intel-ը։ - Բացեք
/dashboard/radar/setup?provider=<provider>-ը։ Անցեք մատակարարին պատկանող հավատարմագրերի URL-ով, ընտրեք Ավելացնել API բանալի, պահպանեք իրական մատակարարի ձևի միջոցով, վերադարձեք ուղեցույց և գործարկեք Փորձարկել կապը։ Ուղեցույցն օգտագործում է սովորական/api/providersև/api/providers/<connection-id>/testերթուղիները․ այն չի ստեղծում առանձին Radar հավատարմագիր։ - Բացեք
/dashboard/radar/combos-ը՝ առնվազն երկու համատեղելի մատակարարի կապ ակտիվացնելուց հետո։ Դիտարկեք առաջարկվող ընտանիքը և ստեղծեք համակցությունը գոյություն ունեցող համակցությունների API-ի միջոցով։ Առաջարկներն ու Intel-ը մնում են առանձին՝ միայն ուղիղ ռեժիմում հասանելի ստորագրված քեշեր, և կարող են ստուգվել իրենց հատուկ Radar էջերում։ - Վերբեռնեք
/dashboard/radar-ը և կարգավորման էջը։ Մասնակցության համաձայնությունը, քողարկված բանալու վիճակը, ստուգված քեշը, պահպանված մատակարարի կապը և փորձարկման գործողությունը պետք է պահպանվեն վերաբեռնումից հետո։ Ապացույցները գրանցեք միայն այն բանից հետո, երբ չմշակված բանալին և մատակարարի հավատարմագիրն այլևս տեսանելի չեն։
Բանալու պահպանումն ինքնին ուղիղ հասանելիության իրավունքի ապացույց չէ։ Ապացույցը մասնավոր
ծառայության GET /v1/license/check արդյունքի, OSS կատալոգի տրամադրած live մակարդակի, ստուգված ստորագրված
քեշի և իրական մատակարարի կապի/փորձարկման գործընթացի համադրությունն է։ Անվավեր, ժամկետանց կամ հետ կանչված բանալու դեպքում
կատալոգը անվտանգ կերպով անցնում է community մակարդակի․ դա չպետք է ներկայացվի որպես ուղիղ բանալու հաջող վավերացում։
Մասնավոր ադմինիստրատորի վահանակի հղում
RADAR_ADMIN_URL-ը, ըստ ցանկության, ավելացնում է Radar Admin ↗՝ Costs կողագոտու բաժնում օգտատերերին հասանելի
Radar տարրից անմիջապես հետո։ Այն միտումնավոր չունի լռելյայն արժեք․ երբ փոփոխականը
սահմանված չէ կամ անվավեր է, ստատիկ կողագոտին, հրամանների ներկապնակը և կողագոտու անհատականացման էկրանը չեն պարունակում
ադմինիստրատորի տարր կամ մասնավոր URL։
Արժեքը որոշվում է սերվերի կողմում և կառավարմամբ նույնականացված
GET /api/settings պատասխանի միջոցով փոխանցվում է միայն նույնականացված կառավարման վահանակի աշխատաշրջանին կամ վստահելի
հետադարձ կապի սեփականատիրոջը՝ առանց մուտքի տեղային սկզբնաբեռնման ժամանակ։ CLI, ներքին ծառայության և manage-scope API բանալիով
նույնականացումը չեն ստանում այն։ Դիտարկիչը կրկին վավերացնում է պատասխանը՝ նախքան արտաքին հղումը ցուցադրելը,
որը բացվում է noopener noreferrer-ով։
Օգտագործեք հավատարմագրեր չպարունակող HTTPS թունելի/tailnet-ի URL։ Սովորական HTTP-ն ընդունվում է միայն հետադարձ SSH
փոխանցման համար, օրինակ՝ http://127.0.0.1:9351․ այլ սխեմաները, ներկառուցված հավատարմագրերը, սխալ ձևաչափված URL-ները և
հեռակա HTTP հասցեները մերժվում են անվտանգ ռեժիմով, իսկ նավարկումը մնում է անգործուն։
Անվտանգության մոդել
Ed25519 ստորագրություն՝ ճշգրիտ բայթերի համար
Հոսքի օգտակար բեռնվածքը ստորագրված է Ed25519-ով։ verifyFeedBytes()
(src/lib/radar/verify.ts) ստորագրությունը ստուգում է ցանցով ստացված պատասխանի ճշգրիտ բայթերի
նկատմամբ․ օգտակար բեռնվածքը ստուգումից առաջ երբեք կրկին չի սերիականացվում, ուստի
բայթ առ բայթ վերակոդավորումը չի կարող աննկատ անվավեր դարձնել կամ շրջանցել ստորագրության ստուգումը։
Ստուգման ձախողումը (invalid_signature) ընդհատում է համաժամացումը՝ նախքան օգտակար բեռնվածքի
վերլուծումը կամ քեշավորումը։
Ամրագրված հանրային բանալի + փոխարինում
Ստուգման հանրային բանալին ամրագրված է src/lib/radar/pinnedKeys.ts-ում
(PINNED_FEED_PUBLIC_KEYS)՝ զանգվածի տեսքով, որպեսզի նոր բանալին հնարավոր լինի ավելացնել
սկզբում՝ փոխարինումից առաջ, մինչդեռ նախորդ բանալիով ստորագրված հին քեշավորված հոսքերը վավեր
կմնան մինչև կրկին համաժամացվելը։
Ճյուղավորումներին հարմար միջավայրի վերասահմանումներ
Միջավայրի երկու փոփոխական ճյուղերին և ինքնուրույն հոսթինգ իրականացնողներին թույլ են տալիս հաճախորդը կանխադրված OmniRoute ծառայության փոխարեն ուղղել իրենց սեփական հոսքին․ տե՛ս ստորև Ինչպես ինքնուրույն հոսթինգ անել հոսքը։
| Փոփոխական | Նպատակ |
|---|---|
RADAR_FEED_URL |
Վերասահմանում է հոսքի բազային URL-ը (կանխադրվածը՝ https://radar.omniroute.online)։ |
RADAR_FEED_PUBKEY |
Վերասահմանում է ամրագրված հանրային բանալին (base64-DER SPKI կամ PEM)՝ ներկառուցված զանգվածը փոխարինելով այս մեկ բանալիով։ |
Տարբերակի ստորին սահման
syncRadar()-ը մերժում է ներբեռնված հոսքը, եթե դրա version-ը խստորեն ավելի նոր չէ, քան
ներկայում քեշավորված տարբերակը (compareVersions(), կետերով բաժանված YYYY.MM.DD.n համեմատություն)՝
{ status: "stale" }։ Սա թույլ չի տալիս, որ վտանգված կամ սխալ կազմաձևված հոսքի վերջնակետը
հաճախորդին հետ վերադարձնի դեպի ավելի հին, այլ կերպ ստորագրված օգտակար բեռնվածք։
Երկու ամսաթիվ, և ինչու են երկուսն էլ պահպանվում
Քեշավորված հոսքը պարունակում է երկու տարբեր ամսաթիվ, և դրանց շփոթելը հենց երկուսն էլ պահպանելու պատճառն է։
| Դաշտ | Աղբյուր | Ինչ հարցի է պատասխանում |
|---|---|---|
generatedAt |
ստորագրված հոսքի մարմինը | որքան հին են տվյալները |
fetchedAt |
այս տեղադրման ժամացույցը | երբ է այս տեղադրումը դրանք ներբեռնել |
Րոպեներ առաջ ներբեռնված հոսքը կարող է պարունակել շաբաթներ առաջվա ցուցանիշներ, ուստի միայն
fetchedAt-ը չի կարող օպերատորին հայտնել՝ արդյոք վերադրվող շերտն ավելի թարմ է, քան դրա հիմքում
գտնվող բազային տվյալները։ Երկուսն էլ պահպանվում են radar_feed_cache-ում, վերադարձվում են
getRadarCatalog().meta-ի միջոցով և առանձին հաղորդվում են GET /api/radar/status-ի կողմից։
Նախքան generated_at սյունակի ստեղծումը (միգրացիա 163) քեշավորված տողը հետ է կարդացվում որպես
null․ անհայտը մնում է անհայտ՝ ներբեռնման ժամանակը փոխառելու փոխարեն։ radar_referrals_cache-ը
միգրացիա 142-ից ի վեր պահպանում է իր սեփական generated_at-ը։
Վերը նշված տարբերակի ստորին սահմանը համեմատում է version-ը, ոչ թե ամսաթվերից որևէ մեկը։
Մնում է երկու բաց, և երկուսն էլ միտումնավոր են․ կառավարման վահանակը դեռ ցուցադրում է միայն
Վերջին ներբեռնումը, ուստի այնտեղ կառուցման ամսաթիվը ցուցադրելու համար անհրաժեշտ է նոր պիտակ
(և դրա 41 տեղայնացված տարբերակները), իսկ առաջարկների և վերլուծական տվյալների քեշերն ընդհանրապես
չեն պահպանում կառուցման ամսաթիվը, թեև դրանց հոսքերի սխեմաները պարունակում են այդպիսի դաշտ․ ուստի GET /api/radar/status-ն այդ երկու տեսակի համար բաց է թողնում դաշտը՝ null հաղորդելու փոխարեն,
ինչը կընկալվեր որպես «անհայտ»։
Սխեմայի վավերացում
Ներբեռնված բայթերը վերլուծվում և վավերացվում են RadarFeedSchema-ի նկատմամբ
(src/lib/radar/feedSchema.ts, Zod սխեմա)՝ ստորագրության ստուգումից հետո։ Սխեմայի
անհամապատասխանության դեպքում վերադարձվում է { status: "invalid_schema" }, իսկ քեշը մնում է
անփոփոխ։ Քեշավորված օգտակար բեռնվածքը պաշտպանական նպատակով կրկին վավերացվում է յուրաքանչյուր
ընթերցման ժամանակ (getRadarCatalog())․ վնասված կամ ձեռքով խմբագրված քեշի տողի դեպքում
օգտագործվում են բազային տվյալները՝ այն մատուցելու փոխարեն։
Պատասխանի չափի սահմանաչափ (10 MB)
syncRadar()-ը հոսքի պատասխանի մարմնի համար կիրառում է 10 MB կոշտ սահմանաչափ․ ստորագրված
հոսքը KB-ների կարգի JSON փաստաթուղթ է, ուստի դրանից մեծ ցանկացած բան վկայում է սխալ կազմաձևված
կամ վնասաբեր RADAR_FEED_URL-ի (կամ անպիտան տվյալներ մատուցող վերին հոսքի), այլ ոչ թե օրինական
կատալոգի մասին։ Սահմանաչափը կիրառվում է երկու շերտով։
Content-Length-ի նախնական ստուգումն ամբողջությամբ բաց է թողնում մարմնի ընթերցումը, երբ վերնագիրն արդեն հայտարարում է սահմանաչափը գերազանցող արժեք։- Մարմնի ընթերցման ընթացքում ընթացիկ ընդհանուր չափի ստուգումը կիրառում է սահմանաչափը նույնիսկ այն
դեպքում, երբ
Content-Length-ը բացակայում է կամ իրական չափից փոքր արժեք է նշում․ վերնագիրը երբեք ինքնին վստահելի չի համարվում։ Կուտակված հատվածների միավորումը պահպանում է ճշգրիտ բայթերը, որոնք հետագայում անհրաժեշտ են Ed25519 ստորագրության ստուգման համար։
Սահմանաչափը գերազանցելու դեպքում վերադարձվում է { status: "too_large" }, իսկ քեշը մնում է
անփոփոխ՝ պահպանելով նույն ոչ կործանարար մոտեցումը, ինչ համաժամացման մյուս բոլոր ձախողումների
դեպքում (invalid_signature, invalid_schema, stale)։
Մակարդակներ՝ community և live
Հոսքի սխեման պարունակում է tier: "community" | "live" դաշտ, որը որոշվում է սերվերի կողմից
հոսքի ծառայության միջոցով՝ հարցման հիման վրա (աջակցողի բանալու առկայությունն ու վավերականությունը)
— հաճախորդը երբեք ինքնուրույն չի որոշում իր մակարդակը։
community— անվճար կատալոգը, որի տվյալները նորագույններից հետ են մնում մոտավորապես 30 օրով։ Սա է ստանում չնույնականացված կամ անվավեր բանալիով հարցումը։live— ամենաթարմ կատալոգը, որը տրամադրվում է աջակցողի վավեր բանալի պարունակող հարցումներին։
Աջակցողի անվավեր կամ ժամկետանց բանալու դեպքում մակարդակն իջեցվում է մինչև community — դա երբեք
սխալ չէ։ Համաժամացման ուղին տարբերակում է միայն ստորագրության/սխեմայի/տարբերակի ձախողումները (բոլորն
էլ վերականգնելի են և քեշավորված վիճակի համար ոչ ճակատագրական) հաջողված { status: "updated", version, tier } արդյունքից։ Հաճախորդը կարիք չունի մշակելու մակարդակին հատուկ
սխալի ուղի։
Սպասարկվող մակարդակը ստացվում է պատասխանի վերնագրից, ոչ թե ստորագրված մարմնից
Ստորագրված հոսքի մարմնի tier դաշտը միշտ "live" է — հոսքի ծառայությունն առաքում է
երկու ստորագրված արտեֆակտ յուրաքանչյուր տարբերակի համար. live-ը ներառում է ընթացիկ արշավները, իսկ community-ն
բաց է թողնում դրանք։ Յուրաքանչյուր արտեֆակտ ստորագրված է իր ճշգրիտ բայթերի հիման վրա։ Մարմինը, այնուամենայնիվ,
չի ծառայում որպես հասանելիության իրավունքի որոշում. հարցման համար փաստացի ընտրված մակարդակը փոխանցվում է
x-omniroute-feed-tier պատասխանի վերնագրում, որը որոշվում է սերվերի կողմից՝ հարցման
Authorization բանալու հիման վրա։
syncRadar()-ը (src/lib/radar/sync.ts::parseServedTierHeader()) միակ տեղն է,
որը որոշում է այն մակարդակը, որին հաճախորդը պետք է վստահի.
- Վերլուծել
x-omniroute-feed-tier-ըRadarTierSchema-ով (Zod) — բացակայող վերնագիրը կամ արժեքը, որը ճշգրտորեն"community"կամ"live"չէ, համարվում է չներկայացված (այն երբեք անվերապահորեն չի փոխանցվում քեշ/UI-ին. սա ներառում է նաև հոսքի հին սերվերները, որոնք ստեղծվել են վերնագրից առաջ)։ - Հետադարձորեն օգտագործել ստորագրված մարմնի
tierդաշտը (միշտ"live") միայն այն դեպքում, երբ 1-ին քայլը ոչինչ չի վերադարձնում։ - Որոշված մակարդակն է քեշավորվում և վերադարձվում որպես
{ status: "updated", version, tier }— կառավարման վահանակը ցուցադրում է հենց այս արժեքը, ոչ թե մարմնի չմշակված դաշտը։
Ընթերցման պահին վերադրման միաձուլման կանոններ
applyFeed()-ը (src/lib/radar/applyFeed.ts) քեշավորված հոսքը միաձուլում է ստատիկ
հիմնական տարբերակի վրա՝ ընթերցման պահին, getRadarCatalog()-ի ներսում։ Հիմնական զանգվածը
(FREE_MODEL_BUDGETS) երբեք չի փոփոխվում — յուրաքանչյուր կանչի ժամանակ նորից հաշվարկվում է MergedEntry[]։
Չորս կանոն՝ ըստ գերակայության հերթականության.
- Հոսքը երբեք չի վերագրում տեղային վերասահմանումը։ Ըստ դաշտի՝ եթե օպերատորը
անհատականացրել է գրառման որևէ դաշտ (
localOverridesքարտեզում՝provider:modelIdբանալիով), տվյալ դաշտի համար հոսքի արժեքը բաց է թողնվում — գերակայում է օպերատորի արժեքը։ enabled: false-ն անջատում է գրառումը՝ պահպանելով ծագման տեղեկությունը։ Գրառումն անջատող հոսքի գրառումը միաձուլված արդյունքի վրա սահմանում էenabled: falseևdisabledBy: "radar", որպեսզի UI-ը կարողանա բացատրել, թե ինչու գրառումը հասանելի վիճակից դարձավ անջատված։- Հոսքում չգտնվող՝ օգտատիրոջ ավելացրած գրառումը պահպանվում է անփոփոխ։ Գրառումները, որոնք գոյություն ունեն միայն հիմնական տարբերակում (կամ ավելացվել են տեղային եղանակով) և չունեն համապատասխան հոսքի գրառում, փոխանցվում են անփոփոխ։
- Տապանաքարով նշված գրառումը երբեք չի վերականգնվում։ Եթե օպերատորը բացահայտորեն ջնջել է որևէ
գրառում (
tombstonesբազմությունում), ապա հետագա տարբերակում հոսքի կողմից այդprovider:modelId-ի կրկին ավելացումը չի վերադարձնում այն։
Խմբագրվող դաշտերն ու տապանաքարերը պահպանվում են
radar_local_model_state-ում (153_radar_local_model_state.sql միգրացիա)։ Հանրային DB
ադապտերը (src/lib/db/radar.ts) այդ տողերը փոխակերպում է applyFeed()-ի կողմից օգտագործվող
localOverrides քարտեզի և tombstones բազմության. արտադրական getRadarCatalog()-ը բեռնում է այդ վիճակը
դրոշակի, քեշի և սխեմայի ստուգումներն անցնելուց հետո։ Օպերատորը կարող է խմբագրել միայն displayName-ը և enabled-ը։
Մատակարարի/մոդելի ինքնությունը, հոսքի ծագումը, քվոտան, հնարավորությունները, ToS-ը
և կարգավորման տվյալները չեն կարող գրվել այս միջերեսի միջոցով։
Կառավարման վահանակը տրամադրում է չորս տեղային գործողություն.
- Խմբագրել՝ փոխում է տեղային ցուցադրվող անունը և միացված լինելու վիճակը։
- Վերակայել տեղային փոփոխությունները՝ մաքրում է երկու խմբագրվող դաշտերը՝ առանց տապանաքարը փոխելու։
- Թաքցնել՝ ստեղծում է տապանաքար, որպեսզի հոսքի հետագա թարմացումները չկարողանան վերստեղծել տողը։
- Վերականգնել՝ հեռացնում է տապանաքարը. առանձին պահպանված ցանկացած վերասահմանում շարունակում է գործել։
Հոսքի enabled: false-ը մնում է անվտանգության բացառություն. այն գերակայում է հնացած տեղային
enabled: true-ի նկատմամբ, պահում է միաձուլված գրառումն անջատված և գրանցում է disabledBy: "radar"։
Կատալոգի հրապարակումներն օգտագործում են schemaVersion: 2։ contextWindow-ն ու tools, vision և
thinking դաշտերից յուրաքանչյուրը անկախորեն number | null / boolean | null են. null-ը նշանակում է անհայտ, մինչդեռ
false-ը նշանակում է, որ D16-ով հաստատված պաշտոնական մատակարարի աղբյուրը բացահայտորեն նշում է հնարավորության բացակայությունը։
OmniRoute-ի ներքին ռեեստրի/մոդելի բնութագրերի դրոշակները երբեք անմիջապես չեն վերածվում հոսքի փաստերի։ Հաճախորդը
դեռ ընդունում է v1 ակնթարթային պատկերները. քանի որ հին կառուցիչն օգտագործում էր false-ը որպես բացակայության տեղապահ, v1-ի false-ը
նորմալացվում է որպես անհայտ, մինչդեռ v1-ի true-ը մնում է փաստացի արժեք։ Սխեմայի անհայտ տարբերակները փակ եղանակով մերժվում են, իսկ
վերջին վավեր քեշը մնում է հասանելի։ Ոչ null համատեքստ/հնարավորություն ունեցող յուրաքանչյուր v2 մոդել պետք է պարունակի
հավատարմագրեր չպահանջող HTTPS metadataEvidenceUrls[]. հակառակ դեպքում սխեմայի վավերացումը ձախողվում է, և քեշը
չի փոխարինվում։ Կատալոգի աղյուսակը բոլոր երեք վիճակները ցուցադրում է որպես ✓, ✕ և ?։
Ուղղորդվող համակցություններ և MCP հասանելիություն
Հաստատված familyId արժեքները պահպանվում են ընթերցման պահին վերադրման ընթացքում և աշխատեցնում են մաքուր
buildRadarComboSuggestions() մոդուլը (src/lib/radar/comboSuggestions.ts)։ Ընտանիքն առաջարկվում է
միայն այն դեպքում, երբ առնվազն երկու տարբեր մատակարար ունեն ակտիվ կապեր և տրամադրում են ճշգրիտ ընտրված մոդելի
ID-ն։ Անջատված մոդելները, ոչ ակտիվ մատակարարները, բացակայող մոդելի ID-ները, մեկ տարրով ընտանիքները և երկիմաստ
այլանունների/նախածանցների համընկնումները փակ եղանակով մերժվում են։ Առաջարկներն օգտագործում են առկա priority ռազմավարությունը՝
առաջինը դասավորելով ամենամեծ պարբերական ամսական բյուջեն. UI-ը դրանք ստեղծում է միայն POST /api/combos-ի միջոցով։
Ուղղորդվող UI-ը գտնվում է /dashboard/radar/combos հասցեում։ Այն կարդում է միայն տեղային
GET /api/radar/catalog և GET /api/combos/builder/options վերջնակետերը։ Այն երբեք չի գործարկում Radar-ի համաժամացումը,
չի կարդում մատակարարի հավատարմագրերը և անմիջապես չի գրում կոմբինացիաների տվյալների բազայում։
MCP հաճախորդները կարող են կարդալ նույն տեղային պրոյեկցիան omniroute_radar_catalog-ի (read:radar) միջոցով։ Ընտրովի
provider, familyId և enabledOnly զտիչները կիրառվում են մեկ տեղային
GET /api/radar/catalog ընթերցումից հետո։ Դրա փակ ելքային տվյալները ներառում են կատալոգի մետատվյալները, ինչպես նաև մատակարարին/մոդելին վերաբերող տվյալները,
ցուցադրվող անունը, familyId-ն, քվոտան, հնարավորությունները, միացված լինելու վիճակը, ծագումը և disabledBy-ը․ կարգավորման URL-ները,
քայլերը, կապերը, էլփոստի հասցեները, բանալիները և ուղղորդման տվյալները երբեք չեն վերադարձվում։ Այս գործիքը
միայն ընթերցման համար է և երբեք չի կանչում /api/radar/sync-ը։
Ծագման նշիչներ
Յուրաքանչյուր միավորված գրառում պարունակում է origin դաշտ, որը UI-ը ցուցադրում է որպես նշան։
"baseline"— անփոփոխ է մնացել թողարկման ստատիկ կատալոգից։"radar"— մեկ կամ մի քանի դաշտ թարմացվել է հոսքից։"local"— օպերատորն այս գրառման համար ունի առնվազն մեկ տեղային վերասահմանում (տեղային վերասահմանումները միշտ գերակայում են հոսքի նկատմամբ՝ համաձայն կանոն 1-ի, անկախ հոսքի պարունակությունից)։
Տեղային մակերեսներ — երբեք feed-ի proxy չեն
Ստորև նշված տեղային Radar route-ների ընտանիքներն ապահովում են src/app/api/radar/-ի ներքո գտնվող UI-ի աշխատանքը.
| Route | Մեթոդ | Նպատակ |
|---|---|---|
/api/radar/catalog |
GET | Տեղային cache-ից վերադարձնում է միավորված catalog-ը (getRadarCatalog())։ |
/api/radar/sync |
POST | Server-ի կողմից գործարկում է syncRadar()-ը և վերադարձնում ստացված կարգավիճակը։ |
/api/radar/settings |
GET | Վերադարձնում է { optIn, hasSupporterKey, supporterKeyMasked }՝ երբեք չվերադարձնելով չմշակված key-ը։ |
/api/radar/settings |
POST | Սահմանում է մասնակցության համաձայնությունը և/կամ (գաղտնագրված) supporter key-ը։ |
/api/radar/referrals |
GET | Տեղային cache-ից վերադարձնում է { fixed, campaigns, tier } — տե՛ս ստորև՝ Ուղղորդման հղումներ։ |
/api/radar/offers |
GET | Ստուգված տեղային live cache-ից վերադարձնում է ակտիվ առաջարկները և երբեք չի վերադարձնում supporter key-ը։ |
/api/radar/offers/sync |
POST | Գործարկում է server-ի կողմից կատարվող, միայն live key օգտագործող syncRadarOffers() pipeline-ը։ |
/api/radar/intel |
GET | Վերադարձնում է ստուգված տեղային live Intel-ը և supporter-ի ճանաչման boolean-ը, բայց երբեք՝ ինքնություն կամ key։ |
/api/radar/intel/sync |
POST | Գործարկում է server-ի կողմից կատարվող, միայն live key օգտագործող syncRadarIntel() pipeline-ը։ |
/api/radar/status |
GET | Առանց գաղտնիքների վերադարձնում է catalog-ի, referrals-ի, offers-ի և Intel-ի՝ միայն ընթերցման համար նախատեսված տեղային կարգավորումների/cache-ի կարգավիճակը։ |
/api/radar/sync-all |
POST | Գործարկում է server-ի կողմում աշխատող բոլոր չորս sync module-ները և յուրաքանչյուր feed-ի համար վերադարձնում է առանձին կարգավիճակ։ |
/api/radar/local-model-state |
GET | Խմբագրման/վերականգնման կառավարիչների համար ցուցակագրում է պահպանված override-ները և tombstone-ները։ |
/api/radar/local-model-state |
PATCH | Սահմանում կամ մաքրում է վավերացված displayName/enabled override field-երը։ |
/api/radar/local-model-state |
PUT | { provider, modelId, tombstoned }-ի միջոցով ստեղծում կամ հեռացնում է tombstone։ |
/api/radar/local-model-state |
DELETE | Մաքրում է խմբագրվող override field-երը՝ պահպանելով առկա tombstone-ը։ |
Խիստ կանոն. այս route-ները երբեք չեն գործում որպես feed service-ի proxy։ Browser-ը հաղորդակցվում է
միայն տեղային OmniRoute server-ի հետ։ Radar service-ի հետ հաղորդակցվող չորս module-ներն են՝
src/lib/radar/sync.ts (catalog), src/lib/radar/referralsSync.ts (referrals), ինչպես նաև
src/lib/radar/offersSync.ts (offers) և src/lib/radar/intelSync.ts (Intel)։ Դրանք բոլորն աշխատում են
server-ի կողմում և երբեք՝ client-ի կողմում։ Սա թույլ է տալիս
feed URL-ը և ցանկացած supporter key ամբողջությամբ հեռու պահել client-ին տեսանելի network traffic-ից։
Radar-ի բոլոր endpoint-ները վերադարձնում են 404, երբ RADAR_ENABLED-ն անջատված է (տե՛ս
վերևում՝ Flag), իսկ route-ի error response-ներն անցկացնում են
buildErrorBody()/sanitizeErrorMessage()-ի միջով՝ համաձայն repository-ի ամբողջ տարածքում գործող error sanitization-ի կանոնի
(docs/security/ERROR_SANITIZATION.md)։
Նույնականացում
Radar-ի բոլոր endpoint-ները պահանջում են նույնականացում isAuthenticated()-ի միջոցով
(src/shared/utils/apiAuth.ts)՝ dashboard session cookie կամ management scope ունեցող
API key, այսինքն՝ նույն gate-ը, որը պաշտպանում է /api/settings/*-ի մնացած մասը։ Անջատված flag-ի
404 ստուգումը միշտ կատարվում է մինչև նույնականացման ստուգումը, որպեսզի RADAR_ENABLED-ն
անջատված installation-ը մնա byte-identical (չառաջանա նույնականացման prompt միայն պարզելու համար, որ մակերեսը գոյություն չունի)։
Երբ flag-ը միացված է, չնույնականացված request-ը ստանում է 401՝ նախքան DB-ում որևէ ընթերցում կամ
գրում։ GET /api/radar/settings-ը երբեք չի վերադարձնում չմշակված supporter key-ը՝ անկախ
նույնականացման վիճակից. վերադարձվում են միայն քողարկված ձևը և hasSupporterKey boolean-ը։
Աջակցողների առաջարկներ
Առաջարկներն օգտագործում են իրենց սեփական ստորագրված արտեֆակտը՝ GET /v1/offers/latest, և երբեք չեն համօգտագործում կատալոգի կամ ուղղորդումների քեշը։ Սերվերի վերջնակետը պահանջում է աջակցողի վավեր, գործող Bearer բանալի․ համայնքային պահուստային տարբերակ չկա։ Հետևաբար, syncRadarOffers()-ը կանգ է առնում մինչև ցանցին դիմելը, եթե գործառույթի դրոշակն անջատված է, օպերատորը չի համաձայնել մասնակցել, կամ աջակցողի որևէ բանալի կազմաձևված չէ։
Հաջող GET հարցումից հետո հաճախորդը ստուգում է Ed25519 ստորագրությունը պատասխանի ճշգրիտ բայթերի նկատմամբ, վավերացնում է RadarOffersFeedSchema-ն, պահանջում է, որ թե՛ ստորագրված մարմինը, թե՛ x-omniroute-feed-tier վերնագիրը նշեն live, պարտադրում է խիստ ավելի նոր՝ կետերով բաժանված տարբերակ և միայն դրանից հետո ատոմար կերպով փոխարինում է radar_offers_cache-ը (144_radar_offers_cache.sql միգրացիա)։ Կիրառվում է վերնագրի և հոսքի համար նույն՝ 10 ՄԲ սահմանաչափը, որն օգտագործվում է մյուս հոսքերի համար։ Ստորագրության, սխեմայի, մակարդակի, կրկնակի ուղարկման, չափի, HTTP-ի և ցանցի հետ կապված բոլոր ձախողումների դեպքում պահպանվում է վերջին վավերացված քեշը։
Փակ առաջարկի կառուցվածքն աջակցում է համեմատելի առավելությունների երեք տեսակի՝ տոկոս՝ բազիսային կետերով, վարկային գումար՝ արժույթի փոքր միավորներով, կամ փորձաշրջանային օրեր։ Գործընկերոջ առաջարկը պետք է ներառի նույն տեսակի հանրային ելակետ, և դրա առավելությունը պետք է խիստ ավելի մեծ լինի․ պաշտոնական առաջարկները չունեն գործընկերային ելակետ։ URL-ները պետք է լինեն առանց հավատարմագրերի HTTPS հասցեներ։ getRadarOffers()-ը պաշտպանական նպատակով կրկին վավերացնում է քեշավորված օգտակար բեռը և յուրաքանչյուր տեղային ընթերցման ժամանակ զտում է ժամկետանց գրառումները․ /dashboard/radar/offers-ը ցուցադրումից առաջ կրկին զտում է ժամկետանց գրառումները, հասանելիության դեպքում օգտագործում է պորտուգալերեն տեքստ՝ անգլերենի պահուստային տարբերակով, և գործընկերների առաջարկները հստակ պիտակավորում է։
Զննարկիչը դիմում է միայն տեղային երթուղիներին․ այն կարդում է քողարկված կարգավորումների պատկերը, սերվերի կողմում թարմացում կատարելու համար հարցում է ուղարկում POST /api/radar/offers/sync-ին, այնուհետև կարդում է GET /api/radar/offers-ը։ Բանալու բացակայության դեպքում այն, հոսքի հարցում փորձելու փոխարեն, ցուցադրում է ներդրողների/աջակցության առկա հղումները։ Արտաքին առաջարկների հղումները բացվում են նոր ներդիրում՝ noopener noreferrer-ով։ Այս թողարկման մեջ radar_offers MCP գործիք հասանելի չէ։
Radar Intel, աջակցողի կրծքանշանը և CLI-ն
Intel-ը ստորագրված արտեֆակտ է՝ հասանելի GET /v1/intel/latest հասցեով։ Փակ RadarIntelFeedSchema-ն ընդունում է միայն Radar-ին պատկանող ELO վարկանիշները, որոնք մասնավոր համակարգողի կողմից ստացվել են հաստատված համեմատություններից, ինչպես նաև կատալոգի տարիքի/քանակի փաստական տարբերությունները, որոնք ստացվել են կատալոգի ստորագրված պատկերներից։ Մեթոդաբանությունը հաստատագրված է՝ սկզբնական վարկանիշը 1000, իսկ K=32։ Դատարկ վարկանիշը վավեր է, երբ որևէ համեմատություն չի հաստատվել․ հաճախորդը երբեք արհեստականորեն չի ստեղծում այն։
syncRadarIntel()-ը կիրառում է նույն սերվերային Bearer-ը, 30 վայրկյանանոց ժամանակային սահմանափակումը, հոսքի 10 ՄիԲ սահմանաչափը, ճշգրիտ բայթերի Ed25519 վավերացումը, խիստ սխեման, մարմնում/վերնագրում live արժեքի պահանջը, տարբերակի նվազագույն շեմը և վերջին վավեր քեշի պահպանումը, ինչ առաջարկների դեպքում։ Վավերացված գործող պատկերի պահպանումից հետո հաճախորդը հաշվարկում է radar:<sha256(supporter key)>, պահում է միայն այդ միակողմանի նույնականացուցիչը և արձակում է հատուկ radar_supporter ճանաչման իրադարձությունը։ Դրան համապատասխան radar-supporter կրծքանշանը իդեմպոտենտ է և տալիս է զրո XP․ այն երբեք չի թարմացնում առաջատարների աղյուսակները և կրկին չի օգտագործում token_share-ը։ /dashboard/radar/intel-ը կրծքանշանը ցուցադրում է միայն վավերացված տեղային քեշի մետատվյալների հիման վրա։
CLI-ն հասանելի է դարձնում omniroute radar status և omniroute radar sync հրամանները։ Երկուսն էլ հաղորդակցվում են միայն տեղային OmniRoute API-ի հետ։ status-ը կատարում է միայն ընթերցման համար նախատեսված GET /api/radar/status հարցում, իսկ sync-ը ուղարկում է մեկ POST /api/radar/sync-all հարցում և յուրաքանչյուր հոսքի համար տպում է արդյունք։ Հրամաններից ոչ մեկը չի կարդում, ընդունում կամ տպում աջակցողի բանալին, և ոչ մեկն անմիջապես չի կապվում Radar ծառայությանը։
Ուղղորդման հղումներ (անվճար կրեդիտներ)
Ուղղորդման հղումները տրամադրվում են ինքնուրույն, միշտ արդիական հոսքից՝
GET /v1/referrals/latest, որը կատալոգի հոսքից առանձին է։ Սա միտումնավոր է․
համայնքային մակարդակի կատալոգի հոսքը պահապատկեր է, որը կարող է մինչև 30 օր հնացած լինել, ուստի
դրանից վերցված ուղղորդման հղումը նախկինում նույնքան ժամանակով հետ էր մնում սերվերի իրական հղումների ցանկից
(նոր ավելացված ուղղորդման հղումը կարող էր մինչև մեկ ամիս հասանելի չդառնալ անվճար/համայնքային օգտատիրոջը)։
Ուղղորդումների հոսքը վերացնում է այդ ուշացումը՝ համաժամեցվելով իր սեփական, շատ ավելի կարճ պարբերականությամբ։
// GET /v1/referrals/latest պատասխանի մարմինը (ստորագրված է Ed25519-ով՝ նույն ամրագրված բանալիով, ինչ
// կատալոգի հոսքը).
{
feed: "omniroute-radar-referrals",
schemaVersion: 1,
generatedAt: string, // ISO — դետերմինիստական՝ max(updatedAt) բոլոր ուղղորդման
// հղումների միջև, որպեսզի երկու նույնական հարցումներ ստեղծեն ճշգրիտ
// նույն ստորագրված բայթերը/ստորագրությունը
referrals: {
fixed: RadarReferral[], // առկա է ՅՈՒՐԱՔԱՆՉՅՈՒՐ մակարդակում՝ ներառյալ առանց նույնականացման/համայնքային
campaigns: RadarReferral[], // լրացվում է միայն վավեր ակտիվ (աջակից) Bearer
// բանալու դեպքում․ առանց նույնականացման/ժամկետանց բանալիով հարցումները ստանում են []
},
}
// RadarReferral = { provider, url, kind: "fixo" | "campanha", validUntil,
// requiredAction, isDefault }
Ի տարբերություն կատալոգի հոսքի՝ այս մարմինն ընդհանրապես չունի tier դաշտ․ սերվերը
յուրաքանչյուր հարցման համար որոշում է, թե ինչ ներառել՝ հիմնվելով Authorization բանալու վրա, ուստի
x-omniroute-feed-tier պատասխանի վերնագիրը տրամադրված մակարդակի ՄԻԱԿ աղբյուրն է
(referralsSync.ts::syncRadarReferrals)․ բացակայող/չճանաչված վերնագրի դեպքում մակարդակը իջեցվում է մինչև
"community"՝ նվազագույն արտոնություններով ենթադրությունը։ RadarReferralsFeedSchema
(src/lib/radar/referralsFeedSchema.ts) վավերացնում է ամբողջ մարմինը՝ կրկին օգտագործելով նույն
feedSchema.ts-ից արտահանված՝ յուրաքանչյուր ուղղորդման համար նախատեսված RadarReferralSchema-ն, որպեսզի երկու հոսքերն էլ
առանձին ուղղորդումները նույն կերպ վավերացնեն։ Յուրաքանչյուր RadarReferral.url պետք է լինի https://․
http:// url-ը չի անցնում սխեմայի վավերացումը։
RadarFeedSchema-ի (feedSchema.ts) ՀԻՆ՝ կատալոգում ներդրված referrals դաշտը
պահպանվում է արդեն պահված կատալոգի հոսքերի հետ հետադարձ համատեղելիության համար, սակայն getRadarReferrals()-ն
այլևս այն չի կարդում․ տե՛ս ստորև՝ Հասանելիության գործառույթ։
Համաժամեցում
syncRadarReferrals()-ը (src/lib/radar/referralsSync.ts) ՄԻԱԿ մոդուլն է, որը
ուղղորդումների համար դիմում է ցանցին՝ ճշգրտորեն կրկնելով syncRadar()-ի պայմանագիրը․ դրոշակն անջատված է
→ disabled, մասնակցության համաձայնությունը false է → opt_out, ներբեռնում է ${RADAR_FEED_URL}/v1/referrals/latest
(նույն RADAR_FEED_URL/RADAR_FEED_PUBKEY ճյուղավորման վերասահմանումներով, ինչ կատալոգը), ստուգում է
Ed25519 ստորագրությունը պատասխանի ճշգրիտ բայթերի նկատմամբ (verifyFeedBytes), վավերացնում է
RadarReferralsFeedSchema-ով և պահում radar_referrals_cache աղյուսակում
(միգրացիա՝ 142_radar_referrals_cache.sql)․ սա կատալոգի
radar_feed_cache-ից ամբողջովին առանձին աղյուսակ է։ Պատասխանի 10 MB սահմանաչափը և generatedAt-ի ստորին շեմը մերժում են
պահված տարբերակից ավելի հին մուտքային հոսքը՝ պաշտպանելով ավելի հին ստորագրված
արտեֆակտի կրկնակի վերարտադրումից։ Հավասար ժամանակային նշիչն ընդունվում է․ սերվերը միտումնավոր համայնքային
և ակտիվ ուղղորդումների տարբերակներին տալիս է նույն դետերմինիստական generatedAt-ը, որպեսզի ստորագրված օգտակար բեռը
և տրամադրված մակարդակը կարողանան փոխվել աջակիցի բանալին փոխելուց հետո՝ առանց հիմքում ընկած հղումների հավաքածուի
փոփոխության։ Երբեք բացառություն չի նետում․ միշտ վերադարձնում է կարգավիճակի օբյեկտ, իսկ սխալների reason-ը երբեք չի պարունակում stack trace։
Երկու գործարկիչ ուղղորդումների քեշը պահում են արդիական, և երկուսն էլ անկախ են կատալոգի սեփական 24-ժամյա պարբերականությունից․
- Համաժամեցում ընթերցելիս —
GET /api/radar/referrals-ն ինքն է կանչումsyncRadarReferrals()-ը նույն հոսքում, երբ քեշը բացակայում է կամREFERRALS_STALE_MS-ից հին է (1h,shouldSyncReferralsOnRead()), նախքան պատասխանը տրամադրելը։ Հենց սա է ֆիքսված հղումները «միշտ արդիական» դարձնում կառավարման վահանակի հենց հաջորդ բեռնման համար՝ առանց որևէ ֆոնային ժամաչափի սպասելու։ - Պլանավորիչի կողմնակի համաժամեցում —
radarSchedulerTick()-ը (scheduler.ts) ինքնուրույն գնահատում է ուղղորդումների հնացած լինելը կատալոգի համար օգտագործվող նույն ամենժամյա տիկի ընթացքում՝ կանչելովsyncRadarReferrals()-ը, երբ ժամանակն է։ Սա կատարվում է անկախ նրանից՝ այդ տիկի ընթացքում կատալոգը համաժամեցման ենթակա էր, թե ոչ, և երբեք չի ազդումRadarTickResult-ի կառուցվածքի վրա (միայն հնարավորության սահմաններում կատարվող կողմնակի ազդեցություն, որը սխալի դեպքում կլանվում է)։
Հասանելիության գործառույթ
src/lib/radar/index.ts-ն արտահանում է միայն ընթերցման համար նախատեսված երկու հասանելիության գործառույթ, և երկուսն էլ երբեք բացառություն չեն նետում (նույն
պաշտպանական պայմանագիրը, ինչ getRadarCatalog()-ի դեպքում․ անջատված դրոշակը, քեշի բացակայությունը կամ վնասված պահված
օգտակար բեռը սխալի փոխարեն վերադարձնում են դատարկ կառուցվածքը)․
getRadarReferrals()→{ fixed: RadarReferral[], campaigns: RadarReferral[] }, կարդում էradar_referrals_cache-ից (getRadarReferralsCache()-ի միջոցով) և վավերացնումRadarReferralsFeedSchema-ով՝ ոչ թե կատալոգի քեշից։getDefaultReferralFor(provider)→ տվյալ մատակարարիfixedուղղորդումը, որի համարisDefault: trueէ, կամnull։ Դիտարկում է միայնfixed-ը․ արշավը երբեք չի օգտագործվում որպես մատակարարի «լռելյայն» հղում։
«Որ ուղղորդումն է լռելյայն տվյալ մատակարարի համար» իրական կանոնը գտնվում է
findDefaultReferral()-ում (src/lib/radar/referrals.ts)՝ փոքր, մաքուր գործառույթում, որը DB ներմուծում չունի․
այն կարելի է անվտանգ ներմուծել "use client" բաղադրիչի մեջ։ getRadarReferrals/
getDefaultReferralFor-ը (index.ts-ում) ներմուծում են @/lib/db/radar-ը և, հետևաբար, մնում են
միայն սերվերի համար․ մատակարարների կառավարման վահանակը index.ts-ի փոխարեն ուղղակիորեն ներմուծում է
referrals.ts-ը (տե՛ս ստորև), որպեսզի better-sqlite3-ը չներառվի դիտարկիչի փաթեթում։
GET /api/radar/referrals
Հետևում է gate-երի ճիշտ նույն հերթականությանը, ինչ Radar-ի յուրաքանչյուր այլ route՝ RADAR_ENABLED-ն անջատված է →
404 (ստուգվում է առաջինը, բայթ առ բայթ նույնական իներցիա)․ չնույնականացված օգտատեր → 401․ հակառակ դեպքում,
եթե տվյալները հնացած են, գործարկում է ընթերցման պահին համաժամացում (տե՛ս վերևում), ապա վերադարձնում է 200
և { fixed, campaigns, tier } — tier-ը վերցվում է անմիջապես cache-ի տողից
(որը հնարավոր է հենց նոր թարմացված լինի) և զուտ տեղեկատվական է (կառավարում է ստորև ներկայացված UI-ի մեղմ upsell տեքստը)։
Երբեք ուղղակիորեն չի proxy-ացնում feed server-ը․ route-ի սեփական source-ը չի պարունակում
fetch( կանչ․ ցանցային հարցումը կատարվում է միայն syncRadarReferrals()-ի ներսում՝
նույն՝ միայն տեղական cache-ի վրա հիմնված սկզբունքով, ինչ /api/radar/catalog-ի դեպքում։
Dashboard UI — «Անվճար կրեդիտներ» ներդիրը /dashboard/radar-ում
Նոր route-ի փոխարեն վերօգտագործում է գոյություն ունեցող Radar էջը
(src/app/(dashboard)/dashboard/radar/page.tsx)՝ որպես երկրորդ ներդիր․ սա նվազեցնում է routing/i18n-ի
մակերեսը մի գործառույթի համար, որը պարզապես էջի կողմից արդեն ստացվող տվյալների տարբերակ է։
Միանալուց հետո ներդիրների գոտին առաջարկում է Կատալոգ (գոյություն ունեցող աղյուսակը) և
Անվճար կրեդիտներ․
- Մշտական հղումները խմբավորվում են ըստ մատակարարի․ յուրաքանչյուրի համար ցուցադրվում է
requiredAction-ը (եթե առկա է) և referral URL-ին տանողtarget="_blank" rel="noopener noreferrer"կոճակ։ - Արշավների համար ցուցադրվում է նույնը՝ հավելյալ
validUntil-ով, եթե այն առկա է։ - Երբ
campaigns-ը դատարկ է, և սպասարկվող tier-ըcommunityէ, UI-ը ցուցադրում է կարճ upsell նշում («սահմանափակ ժամանակով արշավները աջակիցների համար նախատեսված հավելում են»)․ սա երբեք չի թաքցնում կամ սահմանափակում մշտական հղումների ցանկը, որը բոլոր tier-երի համար մնում է ամբողջությամբ համալրված։ Upsell-ը միայն մեղմ հաղորդագրություն է, ոչ երբեք արգելափակում։
Referral հղում մատակարարի անվան վրա (մատակարարների dashboard)
ProviderPageHeader-ը (src/app/(dashboard)/dashboard/providers/[id]/components/)
մատակարարի անունն արդեն կապում էր providerInfo.website-ին, երբ այն առկա էր, և ուներ
մոնետիզացված հղման մեկ նախադեպ՝ Kimi-ի (Moonshot AI) գործընկերային հղման նշումը
(providers.kimiPartnerLinkNote i18n key)։ D28-ը Radar-ի լռելյայն referral-ների համար
վերօգտագործում է հենց նույն զուսպ նշման ձևանմուշը՝ նոր key ավելացնելու փոխարեն։
Թույլ կապակցվածություն՝ նախագծված այդպես․
resolveProviderHeaderLink()-ը (src/app/(dashboard)/dashboard/providers/providerPageUtils.ts) մաքուր function է՝(staticWebsite, referralUrl) => { website, isReferralLink }— առանց@/lib/radar-ից կամ@/lib/db/*-ից կախվածության։providerPageUtils.ts-ն ամբողջությամբ զերծ է մնում այդ import-ներից (ինչը ստուգվում էtests/unit/provider-header-referral-link.test.ts-ով)։ProviderDetailPageClient.tsx-ը ("use client"component) միակ տեղն է, որտեղ թույլատրվում է ստանալ Radar-ի տվյալները՝fetch("/api/radar/referrals")-ի միջոցով՝ օգտագործելով նույն տեղական route-ի ձևանմուշը, որը կիրառում է հենց Radar dashboard-ի էջը, և այն client-ի կողմում հաշվարկում է լռելյայն referral-ը՝ օգտագործելով DB-ից անկախsrc/lib/radar/referrals.ts-իfindDefaultReferral()-ը։- Երբ
RADAR_ENABLED-ն անջատված է, fetch-ը վերադարձնում է 404,referralUrl-ը մնում էnull, իսկresolveProviderHeaderLink()-ը վերադարձնում է ստատիկ կատալոգիwebsite-ը առանց փոփոխության․ մատակարարի էջը բայթ առ բայթ նույնական է այն վիճակին, որը կար մինչ այս գործառույթի ավելացումը։ Նույն արդյունքն է ստացվում, երբ cache-ը դեռ չկա կամ տվյալ մատակարարի համար լռելյայն referral չկա։ - Երբ լռելյայն referral-ը կիրառելի է,
ProviderPageHeader-ը ստանում էisReferralLinkև ցուցադրում է նույն զուսպ նշումը/tooltip-ը, ինչ Kimi-ի գործընկերային հղման դեպքում (providers.kimiPartnerLinkNotekey-ի վերօգտագործմամբ)՝ երբեք չներկայացնելով նոր, առանձին տեսողական ձևավորում։
Ինչպես ինքնուրույն հոսթավորել feed-ը
Fork-ը կամ ինքնուրույն հոսթավորողը, որը ցանկանում է լիակատար վերահսկողություն ունենալ կատալոգի նկատմամբ, կարող է գործարկել իր սեփական feed ծառայությունը՝ առանց հաճախորդի կոդը փոփոխելու.
- Սպասարկեք
GET /v1/catalog/latestendpoint, որը վերադարձնում էRadarFeedSchema-ին (src/lib/radar/feedSchema.ts) համապատասխանող JSON body՝ վերին մակարդակիfeed: "omniroute-radar",schemaVersion: 2,version,tier,providers,models,quirksևtotalsդաշտերով։ Հաշվի առեքx-omniroute-radar-schema: 2-ը. անցումային համատեղելիություն ապահովող սերվերը պետք է առանց դրա հարցումները լռելյայն ուղղի առանձին ստորագրված v1 արտեֆակտին։ - Ստորագրեք պատասխանի ճշգրիտ բայթերը Ed25519 բանալիների զույգով և վերադարձրեք base64
ստորագրությունը
x-omniroute-feed-signatureպատասխանի header-ում։ - Սահմանեք
RADAR_FEED_URL-ը նոր հիմնական URL-ի, իսկRADAR_FEED_PUBKEY-ը՝ համապատասխան հանրային բանալու արժեքով (base64-DER SPKI կամ PEM) — տե՛ս միջավայրի փոփոխականների տեղեկատուն։ - Միացրեք
RADAR_ENABLED-ը և մասնակցության համաձայնություն տվեքPOST /api/radar/settings-ի միջոցով ({ optIn: true })։
Կոդի այլ փոփոխություններ չեն պահանջվում. verifyFeedBytes()-ն ավտոմատ կերպով օգտագործում է վերասահմանումը
(getFeedPublicKeys()՝ src/lib/radar/pinnedKeys.ts-ում), իսկ տարբերակների
համեմատությունը, սխեմայի վավերացումը և միաձուլման կանոնները նույնությամբ կիրառվում են ինքնուրույն հոսթավորվող
feed-ի նկատմամբ։
Ուղղորդման հղումները (տե՛ս վերևի Ուղղորդման հղումներ (անվճար կրեդիտներ)
բաժինը) առանձին, կամընտիր արտեֆակտ են. միայն /v1/catalog/latest սպասարկող fork-ը
շարունակում է լիարժեք աշխատել. /v1/referrals/latest-ից 404 ստանալու դեպքում
syncRadarReferrals()-ը սահմանափակվում է { status: "error" } արդյունքով,
իսկ cache-ը պարզապես դատարկ է մնում, ուստի GET /api/radar/referrals-ը շարունակում է վերադարձնել
{ fixed: [], campaigns: [], tier: null }՝ էջի մնացած մասի աշխատանքը խափանելու փոխարեն։
Ուղղորդման հղումներ նույնպես տրամադրելու համար սպասարկեք RadarReferralsFeedSchema-ին
(src/lib/radar/referralsFeedSchema.ts) համապատասխանող GET /v1/referrals/latest endpoint-ը և
ստորագրեք այն նույն Ed25519 բանալիների զույգով, որն օգտագործվում է կատալոգի feed-ի համար։
Աջակիցների առաջարկները ևս մեկ կամընտիր արտեֆակտ են։ Դրանք սպասարկելու համար ներդրեք
GET /v1/offers/latest-ը փակ RadarOffersFeedSchema-ով
(src/lib/radar/offersFeedSchema.ts), պահանջեք ակտիվ իրավասություն, վերադարձրեք
x-omniroute-feed-tier: live և ստորագրեք ճշգրիտ բայթերը նույն բանալիով։ Այս endpoint-ը բաց թողնող fork-ում
կատալոգի և ուղղորդումների վարքագիծը մնում է անփոփոխ. առաջարկների թարմացումը ձախողվում է առանց տվյալները վնասելու,
իսկ վերջին վավերացված տեղային առաջարկների cache-ը շարունակում է հասանելի մնալ։
Intel-ը նույն կերպ կամընտիր է։ Ինքնուրույն հոսթավորողը կարող է սպասարկել GET /v1/intel/latest-ը՝ օգտագործելով
RadarIntelFeedSchema-ն (src/lib/radar/intelFeedSchema.ts), պահանջել ակտիվ իրավասություն, վերադարձնել
x-omniroute-feed-tier: live և ստորագրել ճշգրիտ բայթերը ընդհանուր Ed25519 բանալիով։ Endpoint-ը
բաց թողնելու դեպքում կատալոգը, ուղղորդումները և առաջարկները մնում են անփոփոխ. Intel-ի թարմացումը պահպանում է
վերջին վավերացված տեղային snapshot-ը, եթե այն առկա է։
Առնչվող փաստաթղթեր
docs/security/ERROR_SANITIZATION.md— սխալների պատասխանների ձևանմուշը, որին հետևում են/api/radar/*route-երը։docs/reference/ENVIRONMENT.md—RADAR_FEED_URL/RADAR_FEED_PUBKEYտեղեկատու։