IlmHamroh
JavaScript Full-stack/32-qism. Professional Git va jamoada ishlash12/19-dars21 daqiqa
Mundarija (39)

README va loyiha hujjatlari: texnik yozish, Diátaxis va SECURITY.md

Qisqacha: README — loyihaning kirish eshigi: u nima, qanday ishga tushadi, qayerdan batafsil o'qish mumkin. Hamma narsani README'ga yozmang: aniq vazifa bo'yicha qo'llanmalar docs/ ga, ma'lumotnoma — API hujjatiga, tushuntirish — arxitektura hujjatiga. Bu bo'linish Diátaxis deb ataladi: o'rganish, qanday qilish, ma'lumotnoma, tushuntirish. CONTRIBUTING.md hissa qo'shish qoidalarini, SECURITY.md zaiflik haqida qanday xabar berishni aytadi. Kurs loyihasida README 86 qatordan 57 qatorga qisqardi, tafsilot docs/qanday/ ga ko'chdi va hamma nisbiy havolalar skript bilan tekshirildi — 0 buzuq.

Bu darsda

  • Yaxshi README tuzilmasini va har bo'limning vazifasini bilasiz.
  • Hujjatlarni Diátaxis bo'yicha to'rt turga ajratasiz.
  • .env.example, badge va skrinshot README'da qanday ishlashini tushuntirasiz.
  • CONTRIBUTING.md ni yakunlab, SECURITY.md yozasiz.
  • Nisbiy havolalarni dastur bilan tekshirasiz va ishni ikki PR bilan yuborasiz.

Oldin bilishingiz kerak: GitHub asoslari: repo, README, LICENSE, sozlamalar, Hujjat o'qish: MDN, README va changelog, Jamoadagi yangi loyihaga kirish, Code review berish va olish.

1. Nega bu kerak?

Olti oy o'tdi. Siz vazifalar-api ga qaytdingiz — yangi xususiyat qo'shish kerak. Loyihani qanday ishga tushirgan edingiz? Qaysi port? Qaysi Docker image? .env da nima bo'lishi kerak? Hammasi boshingizda edi. Endi yo'q.

Yoki boshqa vaziyat: jamoaga Malika keldi. U README'ni ochdi va 86 qatorni o'qidi. "Qanday ishga tushiraman?" savoliga javob uch joyda: "Ishga tushirish", "PostgreSQL bilan (26-qism)" va "Prisma 7 … (27-qism)". Qaysi biri hozirgisi? Malika bir kunini shunga sarfladi.

Kurs loyihasining README'si aynan shunday edi. U qismma-qism o'sgan: har qismda yangi bo'lim qo'shilgan, eskisi o'chirilmagan. Har bo'lim o'z vaqtida to'g'ri edi. Birgalikda — chalkash.

Hayotiy o'xshatish: mehmonxona. Kirishda — qabulxona. U yerda xona raqami, nonushta vaqti va Wi-Fi paroli bor. Shahar tarixi, menyu, favqulodda chiqish rejasi — boshqa joylarda, lekin qabulxonada ularga yo'l ko'rsatiladi. README — qabulxona.

Bu dars — texnik yozish haqida: kod yonidagi matnni o'quvchi tez topadigan va to'g'ri tushunadigan qilib yozish.

2. README tuzilmasi

2.1 Yangi odamning savollari tartibida

README'ni o'qigan odam ketma-ket savol beradi. Bo'limlar shu tartibda tursin:

Savol Bo'lim
Bu nima? sarlavha va 1–2 gap
Nima qila oladi? imkoniyatlar
Qanday ishga tushiraman? tez boshlash
Kundalik buyruqlar? buyruqlar jadvali
Batafsil qayerda? hujjatlar xaritasi
Qanday yordam beraman? hissa qo'shish
Ishlatsam bo'ladimi? litsenziya

GitHub asoslari darsida portfolio README'sini shunga o'xshash tartibda yozgan edingiz. Backend loyihada ikki narsa qo'shiladi: muhit (baza, Redis, .env) va buyruqlar ko'p.

2.2 Kanon README: boshi

Kanon README'ni qayta tuzdi. Boshi (kanon faylidan aynan):

text
# vazifalar-api

`vazifalar` ilovasining backend'i: vazifalar, hisob va xavfsizlik, integratsiyalar va AI yordamchi — bitta REST API.
NestJS 12 (Express 5), TypeScript, PostgreSQL 18 + pgvector, ixtiyoriy Redis.

Ikki gap. Birinchisi — nima va kim uchun. Ikkinchisi — texnologiyalar. O'quvchi 10 soniyada "bu menga kerakmi?" degan savolga javob oladi.

Keyin "Imkoniyatlar" — beshta qator: vazifalar, hisob, integratsiyalar, AI, prodakshn. Har qatorda kalit so'zlar: "kursorli sahifalash, ETag, Idempotency-Key", "argon2id, TOTP va passkey". Bu ro'yxat GitHub qidiruvida ham ishlaydi — kalit so'z bo'yicha loyihani topishadi.

2.3 Tez boshlash

README'ning eng muhim bo'limi. Kanon versiyasi:

bash
git clone <repo-manzili> && cd vazifalar-api
npm ci
docker run -d --name vazifalar-pg \
  -e POSTGRES_HOST_AUTH_METHOD=trust \
  -p 127.0.0.1:5432:5432 pgvector/pgvector:pg18
docker run -d --name vazifalar-redis \
  -p 127.0.0.1:6379:6379 redis:8
cp .env.example .env
npm run db:migrate && npm run db:seed
npm run start:dev

Telefon uchun qatorlar bo'lindi va qator oxiridagi izohlar olib tashlandi — buyruqlar aynan. Docker buyruqlarini 33-qismda to'liq o'rganamiz; hozir bilish shart emas: ular lokal Postgres va Redis'ni ishga tushiradi.

Yaxshi "tez boshlash" ning qoidalari:

  • Nusxalab ishlatsa bo'ladi. Har buyruq to'liq, "o'zingiz sozlang" yo'q.
  • Talablar oldin. Kanonda bitta qator: "Kerak: Node.js 24, Docker."
  • Natija aytiladi. Oxirgi buyruq izohida: http://127.0.0.1:3000/docs — Swagger UI. O'quvchi ishlaganini qanday bilishini biladi.
  • Xavf belgilanadi. Kanonda buyruqlardan keyin: "trust — faqat lokal, faqat 127.0.0.1 uchun." Parolsiz baza serverda — teshik.

Kanon bu bo'limni PR'da halol belgiladi. PR tavsifidagi tekshiruv ro'yxati:

text
- [x] `npm run check` yashil
- [x] README va docs dagi hamma nisbiy havolalar mavjud faylga (skript bilan)
- [ ] "Tez boshlash" toza mashinada — SINALMAGAN (kanon mashinasida konteynerlar boshqa portlarda)

Uchinchi qator belgilanmagan. Bu yaxshi PR'ning belgisi: nima tekshirilmaganini aytish. Ideal tekshiruv — yangi odam yoki toza mashina: README'dan boshqa hech narsa ko'rmasdan loyihani ishga tushirish.

Tekshirib ko'ring: README'da "Tez boshlash" bor, lekin cp .env.example .env qatori yo'q. Yangi odam nima bilan to'qnashadi?

Javob

.env fayli bo'lmaydi. Loyiha config'i Zod bilan tekshiriladi (Config validatsiyasi va namespace'lar darsidagidek) — majburiy o'zgaruvchi yo'q bo'lsa, ilova ishga tushganda xato beradi. Yoki sukut qiymatlar bilan noto'g'ri bazaga ulanadi. README'dagi bitta yo'qolgan qator yangi odamga soatlab qidiruvga tushadi.

2.4 .env.example — muhitning hujjati

.env.example — .env ning namunasi: o'zgaruvchi nomlari, sukut qiymatlar va izohlar. U git'da turadi, .env esa yo'q (.gitignore darsi). Kanon faylidan parcha:

text
# development | production | test
NODE_ENV=development
PORT=3000
# Faqat lokal. Docker ichida 0.0.0.0 (33-qism)
HOST=127.0.0.1
# Frontend manzillari, vergul bilan (production'da majburiy)
CORS_ORIGINS=http://localhost:5173
# fatal | error | warn | info | debug | trace | silent
LOG_LEVEL=info

Har o'zgaruvchi ustida izoh: mumkin bo'lgan qiymatlar (development | production | test) va qachon majburiy ("production'da majburiy"). Bu fayl — hujjat. Kanon faylining ikkinchi qatori shunday: "Bu yerda haqiqiy parol/kalit YO'Q va bo'lmasligi kerak."

Qoida: yangi muhit o'zgaruvchisi qo'shilsa — .env.example ham shu PR'da yangilanadi. Kanon PR shablonida bu alohida bandda turadi.

2.5 Badge va skrinshot

Badge (nishon) — README boshidagi kichik rasm: CI holati, versiya, litsenziya. GitHub Actions har workflow uchun badge beradi, manzil shakli https://github.com/<login>/<repo>/actions/workflows/<fayl>.yml/badge.svg (docs.github.com, "Adding a workflow status badge", 2026-11-04 da ochib o'qildi):

text
![CI](https://github.com/login/vazifalar-api/actions/workflows/ci.yml/badge.svg)

Kanon README'da badge yo'q. Sabab: sinov reposida Actions o'chirilgan — badge "failing" yoki "no status" ko'rsatardi. Badge faqat haqiqatni ko'rsatsa foydali. Yolg'on yashil nishon — nishonsizdan yomon.

Skrinshot va GIF — frontend loyihada README'ning eng kuchli qismi: ekran bir qarashda "bu nima" ni aytadi. Backend'da o'rnini Swagger UI rasmi yoki curl chiqishi bosadi.

Rasm repo ichida turadi (docs/rasmlar/) va nisbiy yo'l bilan ulanadi. Tashqi xizmatdagi rasm bir kun o'chib ketadi.

3. Diátaxis: to'rt xil hujjat

3.1 Muammo: hamma narsa bitta joyda

Eski README'da uch xil matn aralash edi: qanday ishga tushirish (qadamlar), qaysi buyruq nima qiladi (ma'lumotnoma) va nega build kerakligi (tushuntirish). Har o'quvchi o'ziga keragini qidirib, qolganini o'qib chiqardi.

Diátaxis — texnik hujjatlarni o'quvchining ehtiyoji bo'yicha to'rt turga ajratish usuli (diataxis.fr, muallifi Daniele Procida; 2026-11-04 da ochib o'qildi):

Tur O'quvchi nima qilyapti Savol
O'rganish (tutorial) o'rganyapti, qo'lda "Boshlab bera olasizmi?"
Qanday qilish (how-to) ishlayapti, aniq vazifa "X ni qanday qilaman?"
Ma'lumotnoma (reference) ishlayapti, ma'lumot kerak "Bu parametr nima?"
Tushuntirish (explanation) o'rganyapti, tushunmoqchi "Nega shunday?"

Bir xil mavzu to'rt turda to'rt xil yoziladi. Masalan, migratsiya: o'rganishda — "birinchi migratsiyangizni qo'shamiz" qadamlari; qanday qilishda — "mavjud bazaga migratsiya qo'llash"; ma'lumotnomada — npm run db:migrate buyrug'i va bayroqlari; tushuntirishda — nega expand-contract.

3.2 Kanon hujjatlar xaritasi

Kanon README'ning "Hujjatlar" bo'limi — Diátaxis jadvali. Mazmuni (kanon jadvalida birinchi qatorda arxitektura hujjatining bo'lim raqamlari bor edi — bu yerda bo'lim nomlari bilan berildi):

Turi Hujjat
O'rganish README'dagi "Tez boshlash"; docs/ARXITEKTURA.md — «Lokal ishga tushirish» va «Birinchi vazifa»
Qanday qilish docs/qanday/postgres-prisma-redis.md, docs/qanday/prodakshn-va-ai.md
Ma'lumotnoma API.md, /docs (OpenAPI), TESTLAR.md, .env.example, CHANGELOG.md
Tushuntirish docs/ARXITEKTURA.md, docs/XAVFSIZLIK.md, docs/AUTH-QAROR.md, docs/MAXFIYLIK.md

Rasmda:

flowchart LR
  R[README] --> T[O'rganish]
  R --> Q[Qanday qilish]
  R --> M[Ma'lumotnoma]
  R --> X[Tushuntirish]
  T --> A[ARXITEKTURA: lokal]
  Q --> D[docs/qanday/*]
  M --> P[API.md, OpenAPI]
  M --> C[CHANGELOG, .env.example]
  X --> S[ARXITEKTURA, XAVFSIZLIK]

README markazda turadi va hamma joyga yo'l ko'rsatadi, lekin o'zi tafsilotga kirmaydi. CHANGELOG.md — CHANGELOG va reliz avtomatikasi darsidan, ARXITEKTURA.md — Jamoadagi yangi loyihaga kirish darsidan.

3.3 Ko'chirish: o'chirmasdan

Eski README'dagi 26–31-qism bo'limlari qayerga ketdi? O'chirilmadi. docs/qanday/ dagi ikki faylga aynan ko'chirildi. Har fayl boshida izoh:

text
> README'dan ko'chirildi: README — kirish nuqtasi, bu — aniq vazifa uchun qo'llanma (Diátaxis: *how-to*).

Ikki sabab bor. Birinchidan, kimdir eski bo'limga tayanadi — matn yo'qolsa, uning bilimi ham yo'qoladi. Ikkinchidan, review oson: PR tavsifida "faqat ko'chirilgan bloklar: docs/qanday/*.md — eski README'dan aynan" deb yozildi. Reviewer ko'chirilgan matnni qayta o'qimaydi, faqat yangi README'ni o'qiydi.

Natija — o'lchov:

README hajmi: qayta tuzishdan oldin va keyin
  • eski README86 qator
  • yangi README57 qator
  • docs/qanday (2 fayl)ko'chirilgan bo'limlar48 qator

Manba: IlmHamroh kanon tajribasi, 2026-11-04: wc -l, vazifalar-api README.md va docs/qanday/*.md

README qisqardi, lekin bilim yo'qolmadi — tegishli joyga ko'chdi.

Tekshirib ko'ring: "Nega loyihada NestJS tanlangan, Express emas?" — bu matn Diátaxis'ning qaysi turiga kiradi va qayerda turishi kerak?

Javob

Tushuntirish (explanation): u "nega" savoliga javob beradi, aniq vazifani bajarishga yordam bermaydi. Joyi — arxitektura hujjati yoki alohida qaror yozuvi (ADR — Jamoada muloqot darsida ko'ramiz). README'da — eng ko'pi bilan bitta havola.

4. Havolalar: dastur bilan tekshirish

4.1 Nisbiy havola buziladi

Fayl ko'chganda unga olib boradigan havolalar buziladi. GitHub buzuq havolani ogohlantirmaydi — o'quvchi bosadi va 404 oladi. Kanon README'ni qayta tuzgach, README va docs/ dagi hamma nisbiy havolani skript bilan tekshirdi.

Havolani matndan ajratish — oddiy muntazam ifoda. Kod bloklari ichidagilar hisobga olinmaydi, tashqi manzil (https:) va sahifa ichidagi langar (#) — ham:

js
function nisbiyHavolalar(matn) {
  const kodsiz = matn.replace(/```[\s\S]*?```/g, "");
  const natija = [];
  for (const [, h] of kodsiz.matchAll(/\]\(([^)\s]+)\)/g)) {
    if (/^(https?:|mailto:|#)/.test(h)) continue;
    natija.push(h.split("#")[0]);
  }
  return natija;
}

const readme = `
Prodakshn — [qo'llanma](docs/qanday/prodakshn-va-ai.md).
[Diátaxis](https://diataxis.fr/) jadvali, [boshiga](#hujjatlar).
Lokal — [ARXITEKTURA](docs/ARXITEKTURA.md#5-lokal).
MIT — [LICENSE](LICENSE).
`;
console.log(nisbiyHavolalar(readme));

Konsolda:

text
[ 'docs/qanday/prodakshn-va-ai.md', 'docs/ARXITEKTURA.md', 'LICENSE' ]

Uchta nisbiy havola: tashqi manzil va #hujjatlar tashlandi, #5-lokal langari kesildi — fayl borligini tekshirish uchun faqat yo'l kerak. Keyingi qadam — har yo'l uchun fayl bormi, deb so'rash. Buni 3-mashqda node:fs bilan qilasiz.

4.2 Kanon tekshiruvi va bitta topilma

Biz kanon README'sini shunday skript bilan tekshirdik — loyihaning shu bosqichidagi barcha .md fayllar ustida:

text
14 fayl, 25 nisbiy havola, 0 buzuq

Keyin Code review darsidagi PR #15 suggestion'ini qo'lda qo'llab ko'rdik — README oxiriga MIT — [LICENSE](LICENSE).:

text
BUZUQ README.md: LICENSE
14 fayl, 26 nisbiy havola, 1 buzuq

Mana, muallif nega suggestion'ni shu PR'da qabul qilmaganining dalili: LICENSE fayli hali yo'q edi. Suggestion qabul qilinsa, README buzuq havola bilan merge bo'lardi. Litsenziya faylini Open source darsida qo'shamiz, havola o'sha PR bilan keladi.

5. CONTRIBUTING.md ni yakunlash

Yaxshi PR tayyorlash darsida faylning boshi va «Ish oqimi», Code review darsida «Review madaniyati» bo'limini yozdingiz. Ikki bo'lim qoldi. Kanon faylidan aynan:

text
## Kod uslubi

- TypeScript `strict`, `any` yo'q. ESLint va Prettier qoidalari `npm run lint` da.
- Identifikatorlar va izohlar — o'zbekcha (loyiha an'anasi); tashqi API maydonlari — o'zgarmaydi.
- Yangi muhit o'zgaruvchisi → `src/config.ts` (Zod) + `.env.example`. Sir hech qachon commit qilinmaydi.
- Migratsiya → `prisma/migrations/` (expand-contract: avval qo'shish, keyin olib tashlash — alohida reliz).

## Xato haqida xabar berish

Issue oching: qadamlar (takrorlash uchun), kutilgan va haqiqiy natija, versiya (`package.json` yoki commit), log parchasi (sirlarsiz). Xavfsizlik zaifligi — **ochiq issue EMAS**: [SECURITY.md](SECURITY.md).

«Kod uslubi» — review'da bahs bo'lmasin degan kelishuv: nimani linter qiladi, nimani odam kuzatadi. «Xato haqida xabar berish» — yaxshi issue'ning to'rt qismi. Oxirgi gap keyingi faylga olib boradi.

GitHub CONTRIBUTING.md ni taniydi: yangi issue yoki PR ochgan odam unga havolani ko'radi (docs.github.com, "Setting guidelines for repository contributors", 2026-11-04 da ochib o'qildi).

6. SECURITY.md — zaiflik haqida xabar

6.1 Nega ochiq issue emas

Kimdir loyihangizda zaiflik topdi: masalan, bitta foydalanuvchi boshqasining vazifalarini o'qiy oladi. U ochiq issue yozsa — tuzatish chiqqunga qadar butun internet buni ko'radi va hujumchilar birinchi bo'lib foydalanadi.

SECURITY.md — zaiflik haqida yopiq yo'l bilan xabar berish yo'riqnomasi. GitHub uni repo'ning xavfsizlik sahifasida "Security policy" sifatida ko'rsatadi. docs.github.com 2026-11-04 holatida bu tab Security and quality deb ataladi; ko'rinmasa — ⋯ menyusida.

6.2 Kanon fayli

Kanon faylidan aynan (telefon uchun 1-band ikki qatorga bo'lingan, kanonda ham shunday):

text
# Xavfsizlik siyosati

## Qo'llab-quvvatlanadigan versiyalar

| Versiya | Xavfsizlik tuzatishlari |
|---|---|
| 4.x (oxirgi minor) | ha |
| < 4.0 | yo'q |

## Zaiflik haqida xabar berish

**Ochiq issue, PR yoki izoh yozmang** — tuzatish chiqquncha hamma uni ko'radi.

1. GitHub'da repo → **Security** → **Report a vulnerability** (xususiy xabar; repo egasi yoqqan bo'lishi kerak). Yoqilmagan bo'lsa — egasiga
   profilidagi aloqa orqali, mavzu: `vazifalar-api zaiflik`.
2. Yozing: zaiflik turi, ta'sirlangan yo'l/fayl, takrorlash qadamlari, ta'sir (kim nimaga kira oladi). Haqiqiy foydalanuvchi ma'lumotini ilova qilmang.
3. Javob: 3 ish kuni ichida qabul qilindi xabari; tuzatish rejasi — 10 ish kuni ichida. Tuzatish chiqqach — CHANGELOG'da `security` deb, xohlasangiz ismingiz bilan.

Xavfsizlik modeli va tekshirilgan tahdidlar — [docs/XAVFSIZLIK.md](docs/XAVFSIZLIK.md), [docs/OWASP-API.md](docs/OWASP-API.md).

Uch qism: qaysi versiyalar tuzatiladi, qanday xabar berish (yopiq kanal), qachon javob kutish. Muddat va'dasi muhim: xabar beruvchi jim qolsa, sabri tugab, zaiflikni ochiq e'lon qilishi mumkin.

"Report a vulnerability" — GitHub'ning xususiy zaiflik xabari (private vulnerability reporting). Hujjatga ko'ra uni ochiq repo'ning egasi yoki administratori yoqadi. Xabar beruvchi yo'li: Security and quality → Report a vulnerability → forma → Submit report (docs.github.com, 2026-11-04 da ochib o'qildi; kanonda sinalmagan).

Kanon faylidagi 1-bandda tab nomi qisqa — "Security". Fayl matnini o'zgartirmadik, lekin o'z faylingizda bugungi nomni yozing: interfeys nomlari o'zgaradi, shuning uchun bunday hujjatni yiliga bir marta tekshiring.

6.3 Halol cheklov

Kanon bu faylni PR #14 da yubordi va tavsifda yozdi:

text
- Private vulnerability reporting repo sozlamasida YOQILMAGAN (sinov repo chegarasi) — SECURITY.md dagi 1-yo'l sinalmagan.

Faylda yo'l yozilgan, lekin sozlama yoqilmagan — bunday hujjat yolg'on va'da beradi. Kanon buni yashirmadi. O'z repo'ngizda esa sozlamani yoqing yoki 1-bandni faqat "profildagi aloqa" ga qisqartiring.

Tekshirib ko'ring: SECURITY.md bor, lekin kimdir baribir ochiq issue yozdi: "/v1/vazifalar/5 boshqa foydalanuvchining vazifasini qaytaradi". Siz — repo egasisiz. Birinchi nima qilasiz?

Javob

Issue matnini hammaga ko'rinmaydigan qiling (o'chiring yoki tahrirlab, tafsilotni olib tashlang) va muallifga rahmat aytib, yopiq kanalga — SECURITY.md dagi yo'lga — taklif qiling. Keyin tuzatish ustida ishlang. Sabab: tuzatish chiqquncha zaiflikni har kim o'qiy oladi. Muallifni ayblamang — u yaxshi niyatda yozgan; ehtimol fayl unga ko'rinmagan.

7. Hujumchi nigohi

Hujjat ham hujum yo'li bo'lishi mumkin:

  • README'dagi sir. "Tez boshlash" ga haqiqiy parol yoki API kalit yozib qo'yish — eng ko'p uchraydigan sizish. .env.example da ham faqat namuna qiymat bo'lsin. Kanon "Tez boshlash" parolsiz trust ishlatadi va uni ochiq belgilaydi: faqat 127.0.0.1.
  • Nusxalanadigan buyruq. O'quvchi README'dagi buyruqni o'ylamay nusxalaydi. Buyruq bazani 0.0.0.0 ga ochsa — hamma joyda ochiq baza paydo bo'ladi. Shuning uchun kanon portlarni 127.0.0.1:5432:5432 shaklida yozadi.
  • Zaiflik ochiq issue'da. SECURITY.md bo'lmasa, yaxshi niyatli odam ham zaiflikni ochiq yozib yuboradi. Fayl — oldindan berilgan javob.

8. Loyiha qadami: hujjatlar va ikki PR

8.1 Fayllarni yozish

Branch — docs/hissa-qoshish, oldingi ikki darsda boshlagan ishingiz:

  1. CONTRIBUTING.md ga «Kod uslubi» va «Xato haqida xabar berish» bo'limlarini qo'shing.
  2. Ildizda SECURITY.md yarating.

PR shabloni (Yaxshi PR tayyorlash darsida yozilgan) ham shu branch'da turibdi.

8.2 Birinchi commit va PR (1/2)

Bitta katta PR o'rniga ikkita: avval qoidalar fayllari, keyin README. Yaxshi PR tayyorlash darsidagi bo'lish qoidasi — har PR alohida ko'rib chiqiladi.

bash
git switch docs/hissa-qoshish
git add .github/pull_request_template.md CONTRIBUTING.md SECURITY.md
git commit -m "docs: CONTRIBUTING, SECURITY va PR shabloni (1/2)"

Biz loyihaning oldingi bosqichi ustida takrorladik:

text
[docs/hissa-qoshish 368d55b] docs: CONTRIBUTING, SECURITY va PR shabloni (1/2)
 3 files changed, 79 insertions(+)
 create mode 100644 .github/pull_request_template.md
 create mode 100644 CONTRIBUTING.md
 create mode 100644 SECURITY.md

SHA sizda boshqacha bo'ladi — muallif va vaqt farq qiladi. Keyin push va PR:

bash
git push -u origin docs/hissa-qoshish
gh pr create --base main --head docs/hissa-qoshish --fill

--fill — sarlavha va tavsifni commitdan oladi; tavsifni brauzerda shablon bo'yicha to'ldiring. Kanonda bu PR #14 bo'ldi: 4 fayl, +102 qator. Bitta fayl ortiq — sinov reposi monorepo, PR shabloni uning ildizidagi .github/ ga ham qo'yildi (GitHub shablonni repo ildizidan o'qiydi).

8.3 Ikkinchi commit va PR (2/2)

PR #14 merge bo'lgach, main dan yangi branch:

bash
git switch main
git pull
git switch -c docs/readme

README'ni «README tuzilmasi» bo'limidagidek qayta yozing, eski 26–31-qism bo'limlarini docs/qanday/ ga ko'chiring. docs/ARXITEKTURA.md dagi ikki havola ham aniqlashtirildi: README'ga — #tez-boshlash langari bilan, branch nomlash qatoriga — CONTRIBUTING.md ga havola. Havolalarni tekshiring (3-mashqdagi skript) va commit:

bash
git add README.md docs/
git commit -m "docs: README qayta tuzildi, qo'llanmalar docs/qanday ga (2/2)"

Biz ishga tushirdik:

text
[docs/readme 1340a9d] docs: README qayta tuzildi, qo'llanmalar docs/qanday ga (2/2)
 4 files changed, 89 insertions(+), 70 deletions(-)
 create mode 100644 docs/qanday/postgres-prisma-redis.md
 create mode 100644 docs/qanday/prodakshn-va-ai.md

+89 / −70 — kanon PR #15 dagi raqamlar bilan aynan. Keyin git push -u origin docs/readme va PR.

Kanon tekshiruvi ikkala commitdan keyin: tip, lint va build — 0 xato, Vitest 346 passed, 1 skipped — hujjat o'zgarishi kodga tegmadi, testlar oldingi bosqich bilan bir xil.

8.4 PR #15: review va merge

Kanon PR #15 da Code review darsidagi muammo: izohi yozildi, muallif issue #16 ochdi va muhokama yopildi. Merge paytida GitHub qiziq javob qaytardi:

text
non-200 OK status code: 502 Bad Gateway body: "<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body>\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n"
#15 MERGED 0ae90b7

Birinchi qator — server xatosi. Ikkinchisi — PR holati: MERGED. Amal bajarilgan, faqat javob yo'lda yo'qolgan. Saboq Jamoa workflow'lari darsidagidek: xato kelsa, avval holatni tekshiring (gh pr view), keyin qaytaring.

Ikki PR ham kursning sinov reposida: github.com/Sarvarbek0704/ilmhamroh-git-sinov/pull/14 va /pull/15.

9. Ko'p uchraydigan xatolar

9.1 README — tarix kitobi

Har qismda yangi bo'lim, eskisi qoladi. Belgi: bitta savolga README'ning uch joyida javob. Davosi: README — faqat hozirgi holat; tarix — CHANGELOG.md, tafsilot — docs/.

9.2 "Tez boshlash" sinalmagan

Muallif kompyuterida hamma narsa bor edi: Node, baza, .env. README'da bir qadam unutilgan. Davosi: yangi odamga yoki toza mashinada sinatish; sinalmagan bo'lsa — PR'da ochiq yozish.

9.3 Buzuq nisbiy havola

Fayl ko'chdi, havola qoldi. GitHub ogohlantirmaydi. Davosi: havola tekshiruvchi skript (3-mashq) — PR'dan oldin yoki CI'da.

9.4 .env.example eskirgan

Kodda yangi AI_DEADLINE_MS bor, namunada yo'q. Yangi odam uni bilmaydi. Davosi: PR shablonidagi "yangi muhit o'zgaruvchisi — .env.example yangilandi" bandi.

9.5 Zaiflik ochiq issue'da

SECURITY.md yo'q — yaxshi niyatli odam zaiflikni hammaga yozdi. Davosi: fayl va (imkoni bo'lsa) GitHub'ning xususiy xabar sozlamasi.

10. Mashqlar

Mashqlar kurs/mashqlar/32/12-readme/ da. 2- va 3-mashq yechimlari Node 24.21.0 da tekshirilgan (biz ishga tushirdik).

1-mashq (oson): bo'shliqlarni to'ldiring

  • "X ni qanday qilaman?" savoliga javob beradigan Diátaxis turi —
  • Muhit o'zgaruvchilarining git'dagi namunasi — .env.
  • Zaiflik haqida yopiq xabar berish yo'riqnomasi fayli —
  • Hissa qo'shish qoidalari fayli —
  • Kanon README'si qayta tuzilgach necha qator bo'ldi? —
Yechim
  • qanday qilish (how-to) — aniq vazifa, qadamlar; kanonda docs/qanday/.
  • example — git'da turadi, .env esa yo'q.
  • SECURITY.md — GitHub uni xavfsizlik sahifasida (Security and quality) ko'rsatadi.
  • CONTRIBUTING.md — GitHub issue va PR ochilganda unga havola beradi.
  • 57 — 86 dan; tafsilot docs/qanday/ ga ko'chdi.

2-mashq (o'rta): README auditi

readmeAuditi(matn, kerakli) funksiyasini yozing. kerakli — majburiy ## sarlavhalar ro'yxati. Funksiya qaytarsin: yoq — README'da topilmagan sarlavhalar, tezBoshlashdaKod — "Tez boshlash" bo'limida kamida bitta ```bash bloki bormi. Bo'lim — o'z sarlavhasidan keyingi ## gacha bo'lgan matn. Ishora: sarlavhalarni matchAll(/^## (.+)$/gm) bilan yig'ing; bo'limni split(/^## /m) bilan ajrating (RegExp asoslari va metodlari).

Yechim
js
function readmeAuditi(matn, kerakli) {
  const bor = [...matn.matchAll(/^## (.+)$/gm)]
    .map((m) => m[1].trim());
  const yoq = kerakli.filter((s) => !bor.includes(s));
  const bolim = matn
    .split(/^## /m)
    .find((b) => b.startsWith("Tez boshlash"));
  const tezBoshlashdaKod = bolim ? bolim.includes("```bash") : false;
  return { yoq, tezBoshlashdaKod };
}

const KERAKLI = [
  "Tez boshlash", "Buyruqlar", "Hujjatlar", "Litsenziya",
];
const eski = [
  "# vazifalar-api", "## Ishga tushirish", "```bash", "npm ci", "```",
  "## Buyruqlar", "## Tuzilma", "## PostgreSQL bilan (26-qism)",
].join("\n");
const yangi = [
  "# vazifalar-api", "## Imkoniyatlar", "## Tez boshlash",
  "Kerak: Node.js 24, Docker.", "```bash", "npm ci", "```",
  "## Buyruqlar", "## Hujjatlar", "## Hissa qo'shish",
  "## Litsenziya",
].join("\n");
console.log(readmeAuditi(eski, KERAKLI));
console.log(readmeAuditi(yangi, KERAKLI));

Konsolda:

text
{
  yoq: [ 'Tez boshlash', 'Hujjatlar', 'Litsenziya' ],
  tezBoshlashdaKod: false
}
{ yoq: [], tezBoshlashdaKod: true }

Eski README'ning bo'limlar ro'yxati (qisqartirilgan) — uchta majburiy bo'lim yo'q, "Ishga tushirish" bor-u, "Tez boshlash" nomi bilan emas. Kelishilgan nom muhim: auditor dastur ham, odam ham uni qidiradi. Yangi README — hammasi joyida. Bunday tekshiruvni CI'ga qo'yish mumkin.

3-mashq (qiyin): havola tekshiruvchi

havolalarniTekshir(papka) funksiyasini yozing: papkadagi (ichki papkalar bilan) hamma .md fayllarni o'qiydi, nisbiy havolalarni ajratadi («Nisbiy havola buziladi» bo'limidagi nisbiyHavolalar()) va mavjud bo'lmagan fayllarni "fayl: havola" ko'rinishida qaytaradi. Havola yo'li — havola turgan fayl papkasiga nisbatan. Sinash uchun vaqtinchalik papkada kichik loyiha yarating: README.md → docs/qanday.md (bor), LICENSE (yo'q); docs/qanday.md → ../README.md (bor), rasm.png (yo'q).

Ishora: node:fs — mkdtempSync, mkdirSync, writeFileSync, readFileSync, readdirSync(p, { recursive: true }), existsSync, rmSync; node:path — join, dirname; node:os — tmpdir() (fs chuqur: kataloglar, stat, glob va watch darsi). Natijada vaqtinchalik yo'l chiqmasin — papkaga nisbatan yo'l yozing va Windows'dagi \ ni / ga almashtiring.

Yechim
js
import {
  mkdtempSync, mkdirSync, writeFileSync, readFileSync,
  readdirSync, existsSync, rmSync,
} from "node:fs";
import { join, dirname } from "node:path";
import { tmpdir } from "node:os";

function nisbiyHavolalar(matn) {
  const kodsiz = matn.replace(/```[\s\S]*?```/g, "");
  const natija = [];
  for (const [, h] of kodsiz.matchAll(/\]\(([^)\s]+)\)/g)) {
    if (/^(https?:|mailto:|#)/.test(h)) continue;
    natija.push(h.split("#")[0]);
  }
  return natija;
}

function havolalarniTekshir(papka) {
  const buzuq = [];
  const fayllar = readdirSync(papka, { recursive: true })
    .map((f) => f.replaceAll("\\", "/"))
    .filter((f) => f.endsWith(".md"))
    .sort();
  for (const f of fayllar) {
    const matn = readFileSync(join(papka, f), "utf8");
    for (const h of nisbiyHavolalar(matn)) {
      const yol = join(papka, dirname(f), h);
      if (!existsSync(yol)) buzuq.push(`${f}: ${h}`);
    }
  }
  return { fayllar: fayllar.length, buzuq };
}

const p = mkdtempSync(join(tmpdir(), "havola-"));
mkdirSync(join(p, "docs"));
writeFileSync(join(p, "README.md"),
  "[Qo'llanma](docs/qanday.md#boshlash)\n" +
  "MIT — [LICENSE](LICENSE).\n");
writeFileSync(join(p, "docs", "qanday.md"),
  "[Orqaga](../README.md)\n![Ekran](rasm.png)\n");
console.log(havolalarniTekshir(p));
rmSync(p, { recursive: true });

Konsolda:

text
{
  fayllar: 2,
  buzuq: [ 'README.md: LICENSE', 'docs/qanday.md: rasm.png' ]
}

Ikki buzuq havola. docs/qanday.md dagi ../README.md to'g'ri topildi — chunki yo'l fayl papkasidan (docs/) hisoblandi. Agar papka ildizidan hisoblasangiz, ../README.md loyihadan tashqariga chiqib, xato natija berardi. #boshlash langari kesildi — fayl bor, langar alohida tekshiruv. Rasm havolasi (![…](…)) ham ushlandi: muntazam ifoda ]( dan boshlanadi.

11. Real ishda

  • Qayerda uchraydi: har ochiq loyihada README va CONTRIBUTING bor. Katta loyihalarda hujjat sayti alohida (Docusaurus, VitePress, MkDocs) — ko'pincha Diátaxis tuzilmasi bilan. diataxis.fr ga ko'ra usul "yuzlab hujjat loyihalarida" qo'llangan; saytda Cloudflare, Gatsby va Vonage jamoalarining fikri bor (2026-11-04).
  • Docs-as-code: hujjat kod yonida, git'da, PR va review bilan. Havola tekshiruvi va imlo tekshiruvi CI'da yuradi.
  • Ish izlashda: portfolio loyihasining README'si — ishga oluvchi birinchi ko'radigan narsa. Yaxshi README "bu odam boshqalar uchun ham yozadi" degan signal.
  • Intervyu savollari: "Yangi loyihaga README yozsangiz, unda nima bo'ladi?", "Hujjat eskirishiga qanday qarshi turasiz?", "Zaiflik topilsa, qanday xabar berasiz?"

Xulosa

  • README — kirish eshigi: nima, imkoniyatlar, tez boshlash, buyruqlar, hujjatlar xaritasi, hissa, litsenziya.
  • "Tez boshlash" nusxalab ishlatiladi, natijasini aytadi, xavfni belgilaydi va toza mashinada sinaladi.
  • Diátaxis: o'rganish, qanday qilish, ma'lumotnoma, tushuntirish — har biri o'z joyida; README ularga yo'l ko'rsatadi.
  • .env.example — muhitning hujjati; CONTRIBUTING.md — qoidalar; SECURITY.md — zaiflik uchun yopiq yo'l.
  • Fayl ko'chirilsa — o'chirmang, ko'chiring; nisbiy havolalarni dastur bilan tekshiring.
  • Kanon: README 86 → 57 qator, 25 havola, 0 buzuq; ikki PR — #14 (qoidalar) va #15 (README).

Keyingi dars: Jamoada muloqot: sinxron va asinxron — qachon yozish, qachon qo'ng'iroq; issue shablonlari va qaror yozuvi jamoaning yozma xotirasiga aylanadi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
README va loyiha hujjatlari: texnik yozish, Diátaxis va SECURITY.md — IlmHamroh