সরাসরি পর্বে যান
পর্ব ৮৬ · ৯৩-এর মধ্যে · মডিউল ১৩

AI দিয়ে ফুল-স্ট্যাক — কোড লেখানো, review আর যাচাই

AI-Assisted Full-Stack Development — Prompting with Context, Recurring Failure Modes, Package Checks and Verification

Taught in Bangla, this lesson explains what AI coding assistants can and cannot do, a method of context, plan, small steps, running and reading, the outdated-API mistake in a real run, invented packages and typosquatting checked with npm view, code that runs but leaks secrets, skips server permission checks or adds N+1, verification as the core skill, test-first prompting and AI pull request review, and privacy and licences.

এই পর্বে যা শিখবেন

  • ফুল-স্ট্যাক কাজে AI সহকারী কোথায় সত্যিই কাজের, আর কোথায় চোখ বন্ধ করে মানা বিপজ্জনক
  • কাজ থেকে merge পর্যন্ত একটি পদ্ধতি: প্রসঙ্গ, পরিকল্পনা, ছোট ধাপ, চালানো আর পড়া
  • এই কোর্স জুড়ে দেখা AI-এর ভুলগুলো এক জায়গায়, প্রতিটির একটি আসল উদাহরণসহ
  • অচেনা package install-এর আগে যাচাই, আর typosquatting কেন supply chain-এর ঝুঁকি
  • একটি পূর্ণ উদাহরণ: checkout-এ কুপন কোড, একটি নমুনা AI উত্তর, review আর আসল test-এ সংশোধনের প্রমাণ

১ · AI সহকারী কী পারে, কী পারে না

এই কোর্সের প্রায় প্রতিটি পর্ব শেষ হয়েছে “AI-এর যুগে” নামের একটি অংশ দিয়ে। পর্ব ১৩-এ দেখেছেন cleanup ছাড়া effect, পর্ব ২৭-এ Zod 3-এর পুরোনো error.errors, পর্ব ৩৯-এ Prisma 6-এর ধাঁচের client, পর্ব ৫২-এ server আর client-এর সীমানার ভুল, পর্ব ৫৪-এ অনুমতি ছাড়া Server Action, পর্ব ৭২-এ পাস করা অথচ কিছুই না ধরা test, আর পর্ব ৭৮-এ secret-এর নামে NEXT_PUBLIC_. এই পর্ব সেই টুকরোগুলো জোড়া দিয়ে একটি কাজের পদ্ধতি বানাবে।

প্রথমে যন্ত্রটি চিনে নিই। একটি AI coding assistant বিপুল পরিমাণ লেখা আর কোড থেকে শেখা একটি language model-এর ওপর চলে। আপনি একটি prompt দেন, অর্থাৎ লেখা নির্দেশ, আর সে সবচেয়ে সম্ভাব্য পরের লেখাটি তৈরি করে। মূল কথাটি এখানেই: সম্ভাব্য আর সঠিক এক জিনিস নয়। ইন্টারনেটে Next.js-এর Pages Router-এর কোড বহু বছর ধরে জমেছে, তাই সেই ধাঁচের কোড “সম্ভাব্য” মনে হয়, যদিও আপনার project App Router-এ।

দর্জির দোকানের একজন দক্ষ, খুব দ্রুত সহকারীর কথা ভাবুন। হাজারটা জামা সেলাই করেছেন, তাই মাপ না নিয়েও “সাধারণ মাপের” একটি পাঞ্জাবি দশ মিনিটে বানিয়ে দিতে পারেন। কিন্তু খদ্দেরের আসল মাপ তিনি জানেন না, আর ফ্যাশন গত বছরের পর বদলেছে কি না তা-ও না। ওস্তাদের কাজ হলো মাপ বলে দেওয়া, আর জামাটি গায়ে পরিয়ে দেখা। AI সেই সহকারী; মাপ মানে আপনার version আর শর্ত, আর গায়ে পরানো মানে কোড চালিয়ে যাচাই।

সাধারণত ভালোসাধারণত দুর্বল
পরিচিত ধাঁচের boilerplate: form, CRUD route, test-এর কাঠামোআপনার নির্দিষ্ট version-এর নতুন API, বিশেষ করে সাম্প্রতিক বদল
অচেনা কোড বা error বার্তা ব্যাখ্যা করাযা সে দেখেনি: আপনার database-এর আসল ডেটা, production-এর config
একটি কাজের কয়েকটি বিকল্প পথ দেখানোনিরাপত্তার অদৃশ্য শর্ত, যেমন “এই action কে ডাকতে পারবেন”
ছোট refactor আর নাম বদল, test থাকলেবড় পরিসরে সিদ্ধান্ত, যেখানে অনেক ফাইলের প্রসঙ্গ লাগে
Test-এর জন্য নমুনা ডেটা আর কিনারার মানের তালিকানিজের উত্তর যাচাই করা; “পাস করেছে” বললেও না চালিয়ে বলতে পারে

এখানে কোনো নির্দিষ্ট টুলের নাম নেওয়া হলো না, আর “সেরা” টুল বলেও কিছু নেই। টুলগুলো মাসে মাসে বদলায়; কেউ editor-এর ভেতরে লাইন পূরণ করে, কেউ chat-এ উত্তর দেয়, কেউ agent হিসেবে নিজে ফাইল বদলে command চালায়। এই পর্বের পদ্ধতি সবগুলোতেই খাটে, কারণ এটি টুলের ওপর নয়, প্রমাণের ওপর দাঁড়ানো।

মূল ধারণা

AI-এর উত্তর একটি খসড়া, সিদ্ধান্ত নয়। খসড়াটি আপনার project-এ ঢোকার আগে কয়েকটি ছাঁকনি পার হবে: type check, lint, test, নিরাপত্তার তালিকা আর আপনার নিজের পড়া। প্রতিটি ছাঁকনি আলাদা ধরনের ভুল ধরে। নিচের ছবিতে এই পর্বের আসল উদাহরণগুলো কোন ছাঁকনিতে আটকেছে, দেখুন।

AI-এর খসড়া থেকে merge: কোন ছাঁকনি কী ধরে

Each gate catches a different kind of mistake (examples from this lesson's lab)

AI-এর খসড়া থেকে merge পর্যন্ত ছয়টি ছাঁকনি AI-এর খসড়া ১ · Type check (tsc) বানানো field: TS2339 expiresAt ২ · Lint (ESLint) req: any — type-এর পাহারা বন্ধ ৩ · Test (Vitest, supertest) ১৩টির মধ্যে ১২টি নিয়মভঙ্গ ৪ · Mutation চিন্তা দুর্বল test ভুল কোডেও সবুজ ৫ · নিরাপত্তার তালিকা login ছাড়া 200, log-এ cookie ৬ · Network tab, SQL log বাড়তি field, N+1 query মানুষের review প্রতিটি লাইন বুঝে → merge
ছবি ৮৬.১ — কোনো একটি ছাঁকনি সব ধরে না। Type check বানানো field ধরে, কিন্তু ছাড়ের সীমা ভুল কি না জানে না; test নিয়ম ধরে, কিন্তু test নিজে দুর্বল হলে চুপ থাকে।

২ · কাজের পদ্ধতি — প্রসঙ্গ, পরিকল্পনা, ছোট ধাপ, চালানো, পড়া

“চেকআউটে কুপন যোগ করো” লিখে পাঠালে AI-কে অনেক কিছু অনুমান করতে হয়: কোন framework, কোন version, দাম টাকায় না পয়সায়, কুপন কতবার ব্যবহার করা যায়, login লাগে কি না। প্রতিটি অনুমান একটি সম্ভাব্য bug. তাই প্রথম ধাপ হলো অনুমানের জায়গা কমানো। একটি ভালো কাজের বিবরণে পাঁচটি জিনিস থাকে:

  1. Version আর stack: “Next.js 16.4, App Router, React 19, Prisma 7.10.1, Vitest 5.1.” এই এক লাইন পুরোনো API-র বড় অংশ আটকে দেয়।
  2. বিদ্যমান কোড: যে type, function বা ফাইলের সাথে নতুন কোড মিলবে, সেগুলো। না দিলে AI নিজের মতো field-এর নাম বানায়।
  3. শর্ত: দাম পূর্ণসংখ্যা পয়সায়, নতুন package নয়, secret client-এ নয়, প্রতিটি server-এর কাজের শুরুতে অনুমতি যাচাই।
  4. গ্রহণের test: acceptance test, অর্থাৎ কোন কোন ঘটনা পাস করলে কাজ শেষ। যেমন “৫০০ টাকার কম কার্টে EID10 বাতিল”।
  5. কী চাই না: Pages Router নয়, middleware.ts নয়, any নয়।

তারপর কোড নয়, আগে পরিকল্পনা চান: কোন ফাইল বদলাবে, কোন function, কোন test. পরিকল্পনা পড়তে দুই মিনিট লাগে, অথচ ভুল দিকে যাওয়া ৩০০ লাইনের কোড পড়তে এক ঘণ্টা। পরিকল্পনা ঠিক হলে কাজটি ছোট ধাপে ভাগ করুন, প্রতিটি ধাপ এমন যে একবারে চালিয়ে দেখা যায়। নিচের ডায়াগ্রামে একটি কাজের পুরো যাত্রা দেখুন।

  1. কাজের বিবরণversion + শর্তঅনুমান কমানো
  2. পরিকল্পনাফাইল + testকোড নয়, আগে নকশা
  3. Test আগে8 failedলাল দিয়ে শুরু
  4. ছোট ধাপএক functionচালিয়ে দেখা
  5. Diff পড়াপ্রতিটি লাইনবুঝে গ্রহণ
  6. PR আর mergeCI সবুজঅন্যের চোখ
কাজের বিবরণযা AI জানে না, তা লিখে দেওয়া
Stack: Express 5.3, TypeScript 6.0, Vitest 5.1
দাম: পূর্ণসংখ্যা পয়সা (pricePaisa)
EID10: ১০%, সর্বোচ্চ 20000, কার্ট ≥ 50000
শর্ত: login লাগবে, কার্ট নিজের হতে হবে
নতুন package নয়
AI-এর পরিকল্পনাআপনি পড়ে ঠিক করবেন
১. src/coupon.ts: applyCoupon(items, code, coupons, used, now)
২. src/app.ts: POST /api/checkout/coupon
৩. tests/coupon.test.ts, tests/api.test.ts
প্রশ্ন: now কেন argument? → test-এ সময় ঠিক রাখতে
Test আগেনিয়মগুলো সংখ্যায়
' eid10 ' → ছাড় 9000, মোট 81000
500000 → ছাড় 20000 (সীমা)
2026-11-11T18:00:00Z → expired
এখনো কোড নেই → সব লাল, এটাই প্রত্যাশিত
ছোট ধাপএকবারে একটি অংশ
ধাপ ক: applyCoupon → npx vitest run tests/coupon.test.ts
ধাপ খ: route → npx vitest run tests/api.test.ts
প্রতিটির পর: npx tsc --noEmit && npx eslint src
Diff পড়াযে লাইন বোঝেন না, তা গ্রহণ নয়
+ logs.push(JSON.stringify({ headers: req.headers }))
  ↑ cookie log-এ যাবে। কেন?
+ "dependencies": { "coupon-utils": "^1.0.0" }
  ↑ নতুন package চাইনি
Pull requestCI আর একজন মানুষ
CI: typecheck ✓ lint ✓ test 13/13 ✓
বিবরণে: “AI-এর সাহায্যে লেখা; নিয়ম আর test আমার”
Reviewer: অনুমতির পথ আর সময়ের সীমা আলাদা করে দেখলেন
  1. কাজের বিবরণ। Version, দামের একক, নিয়ম আর “নতুন package নয়”, এই কয়েকটি লাইনই AI-এর সবচেয়ে বড় অনুমানগুলো সরিয়ে দেয়। যা লেখেননি, AI তা নিজে বানাবে।
  2. আগে পরিকল্পনা। কোন ফাইল, কোন function, কোন test, শুধু এটুকু চান। এখানে প্রশ্ন করা সস্তা: now কেন argument, এর উত্তর জানলে বোঝেন test-এ সময় কীভাবে ঠিক রাখা হবে।
  3. Test আগে। নিয়মগুলো হাতে হিসাব করা সংখ্যায় test হয়ে গেল। কোড না থাকায় সব লাল; এটাই প্রমাণ যে test সত্যিই কিছু যাচাই করছে।
  4. ছোট ধাপ। আগে শুধু হিসাবের function, চালিয়ে দেখা; তারপর route. প্রতিটি ধাপের পর type check আর lint. একসাথে ৫টি ফাইল বদলালে কোন বদলে কী ভাঙল, বোঝা কঠিন।
  5. Diff পড়া। এই ধাপে দুটি ঝুঁকি চোখে পড়ল: header-সহ log আর একটি অচেনা package. যে লাইন বোঝেন না, সেটি জিজ্ঞেস করুন বা মুছুন; গ্রহণ করবেন না।
  6. PR আর merge. CI সব যাচাই আবার চালায়, আর একজন মানুষ নিয়মগুলো পড়েন। AI-এর সাহায্য নিলে PR-এর বিবরণে সেটি জানানো ভালো অভ্যাস, যাতে reviewer জানেন কোথায় বাড়তি সতর্কতা দরকার।

এই পদ্ধতির দুটি নিয়ম আলাদা করে মনে রাখুন। সব চালান: AI যদি বলে “এটি কাজ করবে” বা “test পাস করেছে”, অথচ সে কোডটি চালায়নি, সেই কথার কোনো মূল্য নেই। প্রতিটি লাইন পড়ুন: আপনার নামে যে কোড merge হয়, তার দায় আপনার। AI-এর লেখা বলে ভুল ক্ষমাযোগ্য হয় না, ক্রেতার টাকা কাটা গেলে কেউ জিজ্ঞেস করবেন না কোডটি কে লিখেছিল।

৩ · পুরোনো API — সবচেয়ে পরিচিত ভুল, আসল run-এ

AI-এর শেখার উপাদানে পুরোনো version-এর কোড বেশি, কারণ সেগুলো বছরের পর বছর ধরে লেখা হয়েছে। Framework দ্রুত বদলায়, তাই AI আত্মবিশ্বাসের সাথে গত version-এর কোড লেখে। ল্যাবে ইচ্ছা করে পুরোনো ধাঁচের কোড লিখে আসল টুলে চালালাম। লেখার সময়ের version: Node 24.15.0, Next.js 16.4.5, React 19.3.1, TypeScript 6.0.3, Prisma 7.10.1.

Next.js: middleware.ts আর params.id

একটি project-এ পুরোনো নামের middleware.ts আর Next.js 14-এর ধাঁচে params.id সরাসরি পড়া একটি পাতা রাখলাম। সত্যিকারের run:

~/old-next$ npx next build
▲ Next.js 16.4.5 (Turbopack)
⚠ The "middleware" file convention is deprecated. Please use "proxy" instead.
  To migrate automatically, run:
  npx @next/codemod@canary middleware-to-proxy .
  Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
  Creating an optimized production build ...
✓ Compiled successfully in 1155ms
  Running TypeScript ...
…
  Finished TypeScript in 1012ms ...
…
Route (app)
┌ ○ /
├ ○ /_not-found
└ ƒ /products/[id]
ƒ Proxy (Middleware)

Build সফল, শুধু একটি সতর্কবার্তা। proxy.ts হলো Next.js 16-এ middleware-এর নতুন নাম; পুরোনো নাম এখনো চলে কিন্তু deprecated. বড় বিপদটি অন্য জায়গায়: params.id নিয়ে build কিছুই বলেনি, কারণ পাতায় type লেখা ছিল { params: { id: string } }, আর TypeScript সেই ভুল ঘোষণাকেই মেনে নিয়েছে। next start চালিয়ে /products/7 চাইলাম:

~/old-next$ npx next start -H 127.0.0.1 -p 47861
GET http://127.0.0.1:47861/products/7
status 200 · x-shop: bazarghar
<h1>পণ্য </h1>

পাতা খুলল, status 200, কিন্তু পণ্যের নম্বর নেই। Next.js 15 থেকে params একটি Promise, তাই params.id হলো undefined. চলে, অথচ ভুল: AI-এর কোডের সবচেয়ে বিপজ্জনক রূপ। এখন Next.js 16-এর তৈরি করা route-সচেতন type PageProps<'/products/[id]'> দিয়ে একই ভুল লিখে next typegen আর tsc চালালাম:

~/old-next$ npx next typegen
✓ Types generated successfully
~/old-next$ npx tsc --noEmit
app/products/[id]/page.tsx(3,33): error TS2339: Property 'id' does not exist on type 'Promise<{ id: string; }>'.

এবার type check ধরল। শিক্ষাটি দুই স্তরের। এক, পুরোনো API ধরার জন্য type লাগে, কিন্তু type নিজে হাতে বানালে AI ভুল type-ও বানাতে পারে; framework-এর দেওয়া type বেশি নির্ভরযোগ্য। দুই, const { id } = await props.params লেখার পর একই tsc শূন্য error দিল। Routing-এর এই বদলগুলোর বিস্তারিত আছে পর্ব ৫১ আর পর্ব ৫৭-এ।

Prisma: version 6-এর schema, version 7-এর CLI

অনেক পুরোনো উত্তর schema-র ভেতরে database URL লেখে। Prisma 7.10.1-এ সত্যিকারের run:

~/old-prisma$ npx prisma validate
Prisma schema loaded from prisma\schema.prisma.
Error: Prisma schema validation - (validate wasm)
Error code: P1012
error: The datasource property `url` is no longer supported in schema files. Move connection URLs for Migrate to `prisma.config.ts` and pass either `adapter` for a direct database connection or `accelerateUrl` for Accelerate to the `PrismaClient` constructor. …
  -->  prisma\schema.prisma:8
 8 |   url      = env("DATABASE_URL")
Validation Error Count: 1

এখানে টুল নিজেই পথ দেখাচ্ছে: URL যাবে prisma.config.ts-এ, আর client বানাতে লাগবে একটি driver adapter. বিস্তারিত পর্ব ৩৯-এ। Error বার্তা পুরোটা পড়ার অভ্যাস এখানে কাজে লাগে; AI-কে শুধু “Prisma কাজ করছে না” বললে সে হয়তো আবার পুরোনো পথই দেখাবে।

যেগুলো নীরবে ভুল করে: Vitest আর MSW

কিছু বদল error দেয় না, শুধু আচরণ বদলায়। পর্ব ৭৩-এর ল্যাবে দেখেছেন, Vitest 5-এ clearMocks-এর ডিফল্ট true; Vitest 4-এর ধাঁচে লেখা test, যা আগের test-এর mock-এর ডাক গুনে চলত, নতুন version-এ অন্য ফল দেয়। আর পর্ব ৭৭-এর আসল run-এ MSW 3 পুরোনো option onUnhandledRequest নীরবে উপেক্ষা করেছিল, ফলে test-এর অনুরোধ সত্যিই network-এ বেরিয়ে গিয়েছিল। নতুন নাম onUnhandledFrame, আর tsc সেটি TS2353 দিয়ে ধরেছিল, যদি setup ফাইলও type check-এর আওতায় থাকে।

এ ধরনের নিয়ম মুখস্থ রাখা কঠিন, তাই অনেক দল একটি তালিকা রাখে আর যন্ত্রকে দিয়ে খোঁজায়। নিচে একটি শেখার মডেল: কয়েকটি ফাইলের কোডে পুরোনো ধাঁচ খোঁজে। এটি আসল linter নয়, শুধু ধারণা।

// Teaching model: flag code that was right in an older version.
const rules = [
  { file: /middleware\.ts$/, msg: 'Next.js 16: rename to proxy.ts' },
  { re: /from ['"]next\/router['"]/, msg: 'Pages Router import; App Router uses next/navigation' },
  { re: /getServerSideProps|getStaticProps/, msg: 'Pages Router data function; await in a Server Component' },
  { re: /\bparams\.\w+/, msg: 'Next.js 15+: params is a Promise; await it first' },
  { re: /url\s*=\s*env\(/, msg: 'Prisma 7: connection URL moves to prisma.config.ts' },
  { re: /new PrismaClient\(\)/, msg: 'Prisma 7: pass a driver adapter' },
  { re: /onUnhandledRequest/, msg: 'MSW 3: option is now onUnhandledFrame' },
  { re: /\brest\.(get|post)\(/, msg: 'MSW 2+: use http.get / http.post' },
  { re: /useFormState/, msg: 'React 19: renamed to useActionState' },
  { re: /\.error\.errors\b/, msg: 'Zod 4: use error.issues' },
];
const files = [
  { name: 'middleware.ts', code: 'export function middleware(req) {}' },
  { name: 'app/product/[id]/page.tsx',
    code: "import { useRouter } from 'next/router';\nexport default function P({ params }) {\n  return params.id;\n}" },
  { name: 'prisma/schema.prisma', code: 'datasource db {\n  provider = "postgresql"\n  url = env("DATABASE_URL")\n}' },
  { name: 'tests/setup.ts', code: "server.listen({ onUnhandledRequest: 'error' });" },
  { name: 'src/price.ts', code: 'export const add = (a, b) => a + b;' },
];
let total = 0;
for (const f of files) {
  const hits = [];
  for (const r of rules) {
    if (r.file && r.file.test(f.name)) hits.push(`  file  ${r.msg}`);
    if (!r.re) continue;
    f.code.split('\n').forEach((line, i) => {
      if (r.re.test(line)) hits.push(`  L${i + 1}    ${r.msg}`);
    });
  }
  total += hits.length;
  console.log(hits.length ? `${f.name}\n${hits.join('\n')}` : `${f.name}  ok`);
}
console.log(`${total} warnings. A rule list only knows what someone wrote into it.`);

আউটপুটে middleware.ts-এর পাশে file Next.js 16: rename to proxy.ts, পাতার ফাইলে দুটি: L1 Pages Router import; App Router uses next/navigation আর L3 Next.js 15+: params is a Promise; await it first. Schema-র L3-এ Prisma 7-এর সতর্কতা, setup ফাইলে MSW 3-এর। src/price.ts ok, আর শেষে 5 warnings. শেষ লাইনটিই আসল শিক্ষা: তালিকা শুধু সেই ভুল ধরে, যা কেউ আগে লিখে রেখেছে। পরের মাসের নতুন বদল এতে নেই, তাই আপনার version-এর release notes আর migration guide পড়ার বিকল্প এটি নয়। লেখার সময়ের Next.js 16 project-এ create-next-app একটি AGENTS.md রাখে, যা AI agent-কে node_modules/next/dist/docs/-এর docs পড়তে বলে, অর্থাৎ install করা version-এর docs project-এর ভেতরেই থাকে।

৪ · বানানো package আর typosquatting

AI কখনো এমন package-এর নাম দেয়, যা কোথাও নেই। নামটি বিশ্বাসযোগ্য শোনায়, যেমন next-coupon-guard, কিন্তু কেউ কখনো প্রকাশ করেনি। একে বলে package hallucination. ২০২৪ সালে প্রকাশিত আর USENIX Security ২০২৫-এ গৃহীত Spracklen ও সহকর্মীদের গবেষণা অনুযায়ী, তাঁদের পরীক্ষায় কোড-লেখা মডেলগুলোর প্রস্তাবিত package-এর প্রায় ১৯.৭% ছিল অস্তিত্বহীন, আর অনেক বানানো নাম বারবার একই রকম ফিরে আসত। এই হার মডেল আর সময়ভেদে বদলায়; সংখ্যাটি নয়, ঝুঁকির ধরনটি মনে রাখুন।

ঝুঁকিটি কোথায়? বানানো নাম install করলে আজ শুধু E404 আসে। কিন্তু নামটি যদি বারবার একই রকম আসে, একজন আক্রমণকারী সেই নামে ক্ষতিকর package প্রকাশ করে রাখতে পারেন। তখন পরের কেউ AI-এর পরামর্শ মেনে install করলে আক্রমণকারীর কোড তাঁর যন্ত্রে চলে। নিরাপত্তা জগতে ২০২৫ সালে এর একটি নাম চালু হয়েছে, “slopsquatting”, যা পুরোনো typosquatting-এর আত্মীয়: জনপ্রিয় নামের সামান্য ভুল বানানে package রাখা। ২০১৭ সালে npm থেকে crossenv নামের একটি package সরানো হয়েছিল, যা জনপ্রিয় cross-env-এর নামের নকল ছিল আর environment variable চুরি করত বলে npm জানিয়েছিল। এ দুটিই supply chain attack-এর রূপ; বড় ছবি আছে পর্ব ৫০ আর Supply chain পর্বে।

Install নয়, আগে npm view

npm view registry থেকে একটি package-এর তথ্য পড়ে, কিছু install করে না, কোনো script চালায় না। তিনটি নামে সত্যিকারের run (npm 11.12.1, ৪ নভেম্বর ২০২৬):

$ npm view zod name version license repository.url maintainers time.created time.modified
name = 'zod'
version = '4.6.7'
license = 'MIT'
repository.url = 'git+https://github.com/colinhacks/zod.git'
maintainers = 'colinhacks <…>'
time.created = '2020-03-07T21:19:15.387Z'
time.modified = '2026-10-12T16:29:38.042Z'
$ npm view zod versions --json   # গুনে দেখা হলো
1013

$ npm view bazarghar-coupon-validator
npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/bazarghar-coupon-validator - Not found
npm error 404  The requested resource 'bazarghar-coupon-validator@*' could not be found or you do not have permission to access it.

$ npm view expresss
expresss@0.0.0 | ISC | deps: none | versions: 1
temp test
maintainers:
- …
published over a year ago by …

তিনটি ফল তিনটি শিক্ষা দেয়। zod: ছয় বছরের পুরোনো, এক হাজারের বেশি version, পরিচিত repository, সর্বশেষ version এক মাসের কম পুরোনো; বিশ্বাসযোগ্য চিহ্ন, তবু docs আর repository নিজে খুলে মিলিয়ে নিন। bazarghar-coupon-validator: E404, নামটি নেই; AI-এর প্রস্তাব হলে সেটি বানানো। expresss, এক অক্ষর বেশি: নামটি আছে! এটি অন্য একজনের প্রকাশ করা একটিমাত্র version-এর package, বিবরণ “temp test”, Express-এর সাথে কোনো সম্পর্ক নেই। এটি ক্ষতিকর এমন কোনো ইঙ্গিত নেই, আর আমরা install-ও করিনি। শিক্ষাটি হলো, টাইপের একটি ভুলে আপনি সম্পূর্ণ অন্য কারও কোড চাইতে পারেন, আর npm install কোনো আপত্তি করবে না। (Maintainer-এর নাম আর ইমেইল এখানে “…” করে রাখা হলো।)

নামের মিল যন্ত্র দিয়েও মাপা যায়। Edit distance বলে একটি শব্দকে আরেকটিতে বদলাতে কতগুলো অক্ষর যোগ, মোছা বা বদল লাগে। নিচের শেখার মডেলটি অনুরোধ করা নামকে আপনার বিশ্বস্ত তালিকার সাথে মেলায়:

// Teaching model of a typosquatting check: compare a requested name
// with names you already trust, using Levenshtein edit distance.
function lev(a, b) {
  const row = Array.from({ length: b.length + 1 }, (_, j) => j);
  for (let i = 1; i <= a.length; i++) {
    let prev = row[0];
    row[0] = i;
    for (let j = 1; j <= b.length; j++) {
      const keep = row[j];
      row[j] = Math.min(row[j] + 1, row[j - 1] + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
      prev = keep;
    }
  }
  return row[b.length];
}
const trusted = ['express', 'react', 'react-dom', 'next', 'zod', 'prisma', 'vitest',
  'supertest', 'msw', 'dayjs', 'axios', 'lodash', 'cross-env'];
const requested = ['zod', 'expresss', 'raect', 'crossenv', 'lodahs', 'next-coupon-guard'];

for (const name of requested) {
  if (trusted.includes(name)) { console.log(`OK        ${name}`); continue; }
  let best = null, dist = Infinity;
  for (const t of trusted) {
    const d = lev(name, t);
    if (d < dist) { dist = d; best = t; }
  }
  if (dist <= 2) console.log(`LOOKALIKE ${name}  ~ ${best} (distance ${dist}) -> fix the spelling`);
  else console.log(`UNKNOWN   ${name}  (nearest ${best}, distance ${dist}) -> check the registry first`);
}

OK zod, কারণ নামটি বিশ্বস্ত তালিকায়। LOOKALIKE expresss ~ express (distance 1) আর LOOKALIKE crossenv ~ cross-env (distance 1): একটি অক্ষর যোগ বা মুছলেই আসল নাম। raect আর lodahs-এর দূরত্ব 2, কারণ পাশাপাশি দুটি অক্ষর অদলবদল সাধারণ Levenshtein-এ দুটি বদল হিসেবে গোনা হয়। শেষ লাইন UNKNOWN next-coupon-guard (nearest next, distance 13) -> check the registry first: কোনো চেনা নামের কাছাকাছি নয়, তাই এটি টাইপের ভুল নয়, হয় নতুন package, নয়তো বানানো নাম। দুই ক্ষেত্রেই registry আর repository না দেখে install নয়। Registry নিজেও নতুন নাম প্রকাশের সময় পরিচিত নামের সাথে মিল খোঁজে বলে জানা যায়, যেমন শুধু বিরামচিহ্নে আলাদা নাম আটকানো, তবে সেই ছাঁকনি নিখুঁত নয়।

একটি অচেনা package হাতে এলে যাচাইয়ের ধাপগুলো দেখুন। মানগুলো ওপরের আসল npm view run থেকে।

1AI: npm i next-coupon-guard2npm view next-coupon-guard3npm view expresss4npm view zod … time maintainers5repository, docs, install script6npm i zod  → lockfile, npm audit
যা দেখা হলো
নাম
registry-তে
চিহ্ন
সিদ্ধান্ত
  1. প্রস্তাব এল। AI একটি কুপন যাচাইয়ের package install করতে বলল। নামটি আগে শোনেননি। এই মুহূর্তে কিছুই চালাবেন না; npm i package-এর install script চালাতে পারে।
  2. নেই। npm view দিল E404. নামটি বানানো। কাজটি নিজের কোডে করুন, বা AI-কে বলুন কোনো package ছাড়া লিখতে। বানানো নাম কখনো “পরে কেউ প্রকাশ করলে” install করার জন্য package.json-এ রেখে দেবেন না।
  3. আছে, কিন্তু অন্য জিনিস। expresss-এ একটি version, বিবরণে লেখা “temp test”, আর Express থেকে দূরত্ব ১, অর্থাৎ টাইপের ভুল। নাম আছে মানেই ঠিক package নয়।
  4. পরিচিত চিহ্ন। zod: ২০২০ থেকে আছে, এক হাজারের বেশি version, সর্বশেষ release সাম্প্রতিক। বয়স আর ধারাবাহিকতা ভালো চিহ্ন, কিন্তু প্রমাণ নয়; জনপ্রিয় package-এর account-ও দখল হয়েছে।
  5. Repository আর docs. Registry-র repository link খুলে দেখুন সেটি আসল প্রকল্প কি না, docs-এ আপনার দরকারি API আছে কি না, আর package.json-এ postinstall আছে কি না।
  6. Install আর lockfile. Install-এর পরে lockfile-এর diff পড়ুন: কতগুলো নতুন dependency এল। npm audit চালান। চাইলে ignore-scripts দিয়ে আগে আলাদা ফোল্ডারে পরখ করুন।

৫ · চলে, কিন্তু বিপজ্জনক — secret, অনুমতি, N+1 আর locale

পুরোনো API অন্তত প্রায়ই error দেয়। পরের ভুলগুলো চুপচাপ থাকে: পাতা খোলে, test-এর সুখী পথ পাস করে, আর ক্ষতি হয় অনেক পরে। এগুলো ধরতে আপনাকে ইচ্ছা করে খারাপ অনুরোধ পাঠাতে হয়, বা উত্তরের ভেতরটা পড়তে হয়।

ভুলএই কোর্সের আসল উদাহরণকীভাবে ধরবেন
Secret ফাঁসNEXT_PUBLIC_ নামে secret build-এ জমে যায় (পর্ব ৭৮); এই পর্বের ল্যাবে log-এ পুরো header, cookie-সহBuild-এর JS আর HTML-এ নকল মান খোঁজা; diff-এ secret scanning
Server-এ authorization নেইLogin বা role যাচাই ছাড়া Server Action (পর্ব ৫৪); এখানে অন্যের কার্টে কুপন (IDOR)Cookie ছাড়া আর অন্য ব্যবহারকারীর cookie দিয়ে অনুরোধ
N+1 queryলুপের ভেতরে query, ১০টি অর্ডারে ১১টি SQL (পর্ব ৪২)Query log আর counter; ডেটা বাড়িয়ে মাপা
ফাঁপা testBranch coverage ১০০%, mutation score ২৩% (পর্ব ৭২)কোডে ইচ্ছা করে ভুল ঢুকিয়ে দেখা কোনো test লাল হয় কি না
Hydration mismatch আর localeLocale ছাড়া toLocaleString() (পর্ব ৫৬, পর্ব ৫৯)অন্য time zone-এ চালিয়ে তুলনা; timeZone স্পষ্ট লেখা
Error গিলে ফেলাcatch (e) { return [] } (পর্ব ৩৯)Diff-এ খালি catch খোঁজা

Locale-এর ভুলটি ল্যাবে এক লাইনে দেখা যায়। একই মুহূর্ত, ১১ নভেম্বর ২০২৬ UTC সন্ধ্যা ৭:৩০, server চলছে UTC-তে আর ক্রেতার browser ঢাকায়। সত্যিকারের run, Node 24.15.0:

$ TZ=UTC node -e "…"         # timeZone ছাড়া | timeZone: 'Asia/Dhaka'
server TZ=UTC  : 11/11/2026 | ১২/১১/২০২৬
$ TZ=Asia/Dhaka node -e "…"
browser Dhaka  : 11/12/2026 | ১২/১১/২০২৬

timeZone না দিলে server বলে ১১ তারিখ, browser বলে ১২ তারিখ; Next.js-এ এই পার্থক্যই hydration mismatch. timeZone: 'Asia/Dhaka' দিলে দুই জায়গায় একই ১২/১১/২০২৬. AI-এর লেখা তারিখের কোডে প্রায়ই locale আর zone কোনোটিই থাকে না, কারণ লেখকের নিজের যন্ত্রে সেটি ঠিকই দেখায়।

Secret-এর ভুল ধরার একটি অংশ যন্ত্রকে দেওয়া যায়। gitleaks-এর মতো scanner পরিচিত key-এর আকার আর এলোমেলোতা খোঁজে। নিচে একটি diff-এর শুধু যোগ করা লাইনে চালানো শেখার মডেল:

// Teaching model of a secret scan over the added lines of a diff.
const diff = `+++ b/src/pay.ts
+const key = "bzg_live_k7Qp2Xv9LmR4tW8nZc3YhJ6d";
+const label = "aaaaaaaaaaaaaaaaaaaaaaaa";
-const old = 1;
+NEXT_PUBLIC_PAYMENT_SECRET=example-secret
+logger.info({ msg: 'coupon', headers: req.headers });
+const url = process.env.DATABASE_URL;`;

function entropy(s) {
  const n = {};
  for (const ch of s) n[ch] = (n[ch] || 0) + 1;
  return Object.values(n).reduce((h, c) => h - (c / s.length) * Math.log2(c / s.length), 0);
}
const rules = [
  ['known key prefix', (l) => /\b[a-z]{3}_(live|test)_[A-Za-z0-9]{16,}/.test(l)],
  ['secret in a public variable', (l) => /NEXT_PUBLIC_\w*(SECRET|KEY|TOKEN)/.test(l)],
  ['logs headers or cookies', (l) => /log\w*[.(].*(headers|cookie)/i.test(l)],
  ['high-entropy string', (l) => (l.match(/["']([^"']{20,})["']/g) || [])
    .some((q) => entropy(q.slice(1, -1)) > 4)],
];
diff.split('\n').forEach((line, i) => {
  if (!line.startsWith('+') || line.startsWith('+++')) return;
  const hits = rules.filter(([, test]) => test(line)).map(([name]) => name);
  console.log(`${hits.length ? 'FLAG' : 'ok  '} line ${i + 1}: ${hits.join(', ') || '-'}`);
});
const k = 'k7Qp2Xv9LmR4tW8nZc3YhJ6d';
console.log('entropy of the key part:', entropy(k).toFixed(2), 'bits/char; of "aaaa...":',
  entropy('aaaaaaaaaaaaaaaaaaaaaaaa').toFixed(2));

ফল: FLAG line 2: known key prefix, high-entropy string, ok line 3: -, FLAG line 5: secret in a public variable, FLAG line 6: logs headers or cookies, ok line 7: -. মুছে ফেলা লাইন ৪ আর +++ শিরোনাম দেখাই হয়নি। শেষ লাইন: key-এর অংশের Shannon entropy 4.58 bit প্রতি অক্ষর, আর একই অক্ষরের সারির 0.00. লাইন ৭ ঠিক আছে, কারণ মানটি environment থেকে পড়া হচ্ছে, কোডে লেখা নেই। লাইন ৫-এর মান example-secret নিরীহ, তবু নিয়মটি নামের কারণেই ধরেছে: NEXT_PUBLIC_ নামের সবকিছু browser-এ যায়। এমন scanner দলে দুই রকম ভুল করে, আসল secret বাদ দেওয়া আর নিরীহকে secret বলা; তাই এটি একটি জাল, দেয়াল নয়।

৬ · যাচাই-ই মূল দক্ষতা

AI লেখার খরচ প্রায় শূন্যে নামিয়ে এনেছে। ফলে দামি হয়ে উঠেছে বিচার: কোনটি ঠিক, কোনটি নিরাপদ, আর কীভাবে প্রমাণ করব। এই কোর্সে যাচাইয়ের যে টুলগুলো শিখেছেন, সেগুলো এখন একসাথে একটি অভ্যাস:

Type check

Type checker বানানো field আর পুরোনো API-র আকৃতির ভুল ধরে, কোড না চালিয়েই। শর্ত: type নিজে সত্যি হতে হবে, any নয়।

npx tsc --noEmit

Lint

Linter সন্দেহজনক ধাঁচ ধরে: any, অব্যবহৃত মান, effect-এর dependency. AI-এর eslint-disable লাইন আলাদা করে খুঁজুন।

npx eslint src

Test, mutation চিন্তাসহ

প্রত্যাশা হাতে হিসাব করা সংখ্যায়। তারপর প্রশ্ন: কোডে একটি >= বদলে > করলে কোন test লাল হবে? উত্তর না থাকলে test দুর্বল।

npx vitest run

Network tab আর SQL log

Browser-এর DevTools-এ উত্তরের ভেতরে বাড়তি field আছে কি না; server-এর query log-এ একটি পাতায় কতগুলো SQL চলল।

DevTools · query log

Test-এর অংশটি সবচেয়ে প্রতারণাময়, কারণ AI-এর লেখা test প্রায় সবসময় সবুজ। Mutation testing-এর মূল চিন্তা হলো test-কে test করা: কোডে ইচ্ছা করে একটি ছোট ভুল, একটি mutant, ঢুকিয়ে দেখা কোনো test সেটি ধরে কি না। নিচের মডেলে একই নিয়মের একটি ঠিক আর একটি ভুল কোড, আর দুটি test suite:

// A weak test passes a wrong implementation. A stronger one does not.
// Rule: EID10 gives 10% off, rounded to whole paisa, at most 20000 paisa.
const right = (sub) => Math.min(Math.round(sub * 0.1), 20000);
const wrong = (sub) => sub * 0.1; // no rounding, no cap

function check(name, ok) { return (ok ? 'PASS ' : 'FAIL ') + name; }

const weak = (discount) => [
  check('discount is positive and below the subtotal',
    discount(90000) > 0 && discount(90000) < 90000),
];
const strong = (discount) => [
  check('900 taka cart -> 9000 paisa off', discount(90000) === 9000),
  check('5000 taka cart -> capped at 20000', discount(500000) === 20000),
  check('104999 paisa -> 10500, whole paisa', discount(104999) === 10500),
];

for (const [label, suite, impl] of [
  ['weak suite,   wrong code', weak, wrong],
  ['strong suite, wrong code', strong, wrong],
  ['strong suite, right code', strong, right],
]) {
  const lines = suite(impl);
  const failed = lines.filter((l) => l.startsWith('FAIL')).length;
  console.log(`${label}: ${lines.length - failed} passed, ${failed} failed`);
  for (const l of lines) console.log('   ' + l);
}
console.log('wrong(500000) =', wrong(500000), ' wrong(104999) =', wrong(104999));

weak suite, wrong code: 1 passed, 0 failed: “ছাড় শূন্যের বেশি আর মোটের কম” প্রায় যেকোনো ভুল কোডেও সত্য। strong suite, wrong code: 1 passed, 2 failed: ৯০০ টাকার কার্টে ভুল কোডও ঠিক উত্তর দেয় (এই কারণেই একটিমাত্র “সুখী” উদাহরণ যথেষ্ট নয়), কিন্তু সীমা আর রাউন্ডিংয়ের test লাল। strong suite, right code: 3 passed, 0 failed. শেষ লাইনে ভুলের আকার: wrong(500000) = 50000, সীমার আড়াই গুণ; আর wrong(104999) = 10499.900000000001, ভগ্নাংশ পয়সা, সাথে floating point-এর লেজ। Test-এর শক্তি আসে কিনারার মান থেকে: সীমার ঠিক ওপরে, রাউন্ডিংয়ের ঠিক মাঝে।

নিরাপত্তার অংশে একটি ছোট তালিকা প্রতিটি AI-এর বদলে চালান: (ক) প্রতিটি server-এর কাজের শুরুতে login, তারপর মালিকানা বা role; (খ) দাম, মালিক, ছাড় client থেকে নেওয়া নয়; (গ) input schema দিয়ে যাচাই; (ঘ) কোনো secret client-এর কোডে বা log-এ নয়; (ঙ) CORS বা CSP ঢিলা করে error থামানো নয়; (চ) নতুন dependency থাকলে তার কারণ জানা। পুরো তালিকা আছে পর্ব ৫০-এ, তত্ত্ব Broken access control পর্বে।

৭ · Test আগে লেখানো, আর AI-এর PR review

AI-কে কোড আর test একসাথে লিখতে দিলে একটি সূক্ষ্ম সমস্যা হয়: test প্রায়ই কোডের বর্তমান আচরণ দেখে লেখা হয়। কোড ভুল হলে test-ও সেই ভুল মেনে নেয়। তাই ক্রম উল্টে দিন: test-first. আগে নিয়মগুলো দিয়ে test লেখান, নিজে পড়ে প্রত্যাশিত সংখ্যাগুলো হাতে মিলিয়ে নিন, চালিয়ে দেখুন সব লাল। তারপর কোড লেখান, আর শর্ত দিন “test বদলাবে না”। Test-driven development-এর ধারণা নতুন নয়, Kent Beck ১৯৯০-এর দশকের শেষে Extreme Programming-এর অংশ হিসেবে এটি জনপ্রিয় করেন, আর ২০০২ সালের দিকে এ নিয়ে বই লেখেন; বিস্তারিত আছে TDD ও BDD পর্বে। AI-এর যুগে এর একটি নতুন সুবিধা: test হয়ে যায় আপনার আর AI-এর মধ্যে চুক্তি, যা AI নিজে বদলাতে পারে না।

একটি পরিচিত ফাঁদ: test লাল হলে agent-ধাঁচের টুল কখনো কোড না সারিয়ে test-এর প্রত্যাশা বদলে দেয়, বা test-টিকে .skip করে দেয়। তাই diff-এ test ফাইলের প্রতিটি বদল আলাদা করে পড়ুন। Test-এর প্রত্যাশা বদলানো একটি নিয়মের বদল; সেটি মানুষের সিদ্ধান্ত।

AI-এর লেখা pull request-এর code review মানুষের PR-এর মতোই, তবে কয়েকটি জায়গায় বাড়তি চোখ লাগে। সাধারণ নিয়ম আর review-এর মনস্তত্ত্ব আছে Software Engineering কোর্সের code review পর্বে আর pull request পর্বে। AI-এর PR-এ যেগুলো বিশেষ করে দেখবেন:

কী দেখবেনকেন
PR-এর আকারAI সহজে বিশাল diff বানায়; ৮০০ লাইনের PR কেউ মনোযোগ দিয়ে পড়েন না। ছোট ছোট PR চান।
package.json আর lockfileনতুন dependency, বানানো নাম, অদরকারি library
Test ফাইলের বদলপ্রত্যাশা বদলানো, .skip, .only, বড় snapshot update
Error-এর পথখালি catch, error গিলে ডিফল্ট মান, // @ts-ignore
অনুমতির পথপ্রতিটি নতুন route বা action-এ login আর মালিকানা
অপ্রাসঙ্গিক বদলকাজের বাইরে format বদল, নাম বদল; আসল বদল চাপা পড়ে
দাবি বনাম প্রমাণবিবরণে “সব test পাস” লেখা থাকলে CI-এর লগ দেখুন

৮ · পুরো উদাহরণ — checkout-এ কুপন কোড

এবার সবকিছু একসাথে। কাজ: বাজারঘরের checkout-এ কুপন কোড যোগ করা। ল্যাবে একটি ছোট Express project বানালাম, লেখার সময়ের version: Express 5.3.0, TypeScript 6.0.3, Vitest 5.1.0, supertest 7.3.1, ESLint 10.14.0, typescript-eslint 8.72.1. কোনো AI সেবা ডাকা হয়নি। নিচের prompt একটি উদাহরণ, আর তার পরের “নমুনা AI উত্তর” আমি নিজে লিখেছি, AI-এর সাধারণ ভুলগুলো এক জায়গায় দেখানোর জন্য। এটি কোনো AI-এর আসল উত্তর নয়।

প্রথমে একটি দুর্বল prompt, যেমনটা প্রায়ই লেখা হয়:

আমার Express অ্যাপের checkout-এ কুপন কোড যোগ করো। EID10 দিলে ১০% ছাড়, আর FLAT50 দিলে ৫০ টাকা ছাড়।

এই prompt-এ version নেই, দামের একক নেই, ছাড়ের সীমা নেই, সময়ের সীমা নেই, login-এর কথা নেই। এমন prompt-এ যে ধরনের উত্তর আসতে পারে, তার একটি নমুনা:

// নমুনা AI উত্তর (শেখানোর জন্য লেখা, আসল AI-এর উত্তর নয়)
export function applyCoupon(
  items: CartItem[],
  code: string,
  coupons: Coupon[],
  usedByUser: number,
  now = new Date(),
): CouponResult {
  const coupon = coupons.find((c) => c.code === code);
  if (!coupon) return { ok: false, reason: 'not_found' };
  if (new Date(coupon.expiresAt) < now) return { ok: false, reason: 'expired' };

  const subtotalPaisa = items.reduce((s, i) => s + i.pricePaisa * i.qty, 0);
  const discountPaisa =
    coupon.kind === 'percent' ? (subtotalPaisa * coupon.value) / 100 : coupon.value;

  return { ok: true, subtotalPaisa, discountPaisa, totalPaisa: subtotalPaisa - discountPaisa };
}
// নমুনা AI উত্তর (শেখানোর জন্য লেখা)
app.post('/api/checkout/coupon', (req: any, res: any) => {
  const { cartId, code } = req.body;
  logs.push(JSON.stringify({ msg: 'apply coupon', headers: req.headers, body: req.body }));

  const cart = carts.get(cartId);
  if (!cart) return res.status(404).json({ error: 'cart not found' });

  const used = usage.get(`${cart.userId}:${code}`) ?? 0;
  const result = applyCoupon(cart.items, code, coupons, used);
  if (!result.ok) return res.status(422).json(result);
  res.json(result);
});

Review: চোখে পড়া ভুল

কোডটি পরিষ্কার দেখায়, নাম সুন্দর, type আছে। এখন লাইন ধরে পড়ি:

  1. c.code === code: " eid10 " লিখলে মিলবে না। ক্রেতারা ছোট হাতের অক্ষর আর বাড়তি space লেখেন।
  2. coupon.expiresAt: আমাদের Coupon type-এ field-এর নাম endsAt; AI নিজে একটি নাম বানিয়েছে। undefined থেকে new Date হয় Invalid Date, আর তার সাথে যেকোনো তুলনা false, অর্থাৎ কুপন কখনো মেয়াদোত্তীর্ণ হবে না। শুরুর সময়ও যাচাই হয়নি।
  3. usedByUser নেওয়া হয়েছে, কিন্তু কোথাও ব্যবহার হয়নি: একজন ক্রেতা একবারের কুপন বারবার।
  4. সর্বনিম্ন কার্ট আর সর্বোচ্চ ছাড়ের সীমা নেই; শতাংশের ছাড়ে ভগ্নাংশ পয়সা; FLAT50 ছোট কার্টে মোট ঋণাত্মক করে।
  5. Route-এ login নেই, আর কার্টটি কার, তা দেখা হয়নি: যে কেউ যেকোনো cartId দিয়ে চেষ্টা করতে পারেন।
  6. Log-এ পুরো req.headers, তাতে session cookie. Log যাঁরা পড়তে পারেন, তাঁরা ক্রেতার session পেয়ে যান।
  7. req: any: TypeScript-এর পাহারা বন্ধ, input-এর আকার যাচাই নেই।

প্রমাণ: যাচাইয়ের টুলগুলো কী বলে

চোখে দেখা ভুল প্রমাণ নয়। আগে AI-এর ধাঁচের দুর্বল test, যা শুধু দেখে কুপন “কাজ করছে”। সত্যিকারের run:

~/bazarghar-coupon$ npx vitest run tests/coupon.weak.test.ts
 RUN  v5.1.0 ~/bazarghar-coupon
 Test Files  1 passed (1)
      Tests  1 passed (1)

সবুজ। এবার নিয়ম থেকে লেখা test: ৮টি নিয়মের unit test আর ৪টি API test, প্রত্যাশা হাতে হিসাব করা। নমুনা উত্তরের ওপর সত্যিকারের run (দীর্ঘ আউটপুট ছাঁটা):

~/bazarghar-coupon$ npx vitest run
 ❯ tests/coupon.test.ts (8 tests | 8 failed) 12ms
     × accepts lower case and spaces
     × caps the discount at 200 taka
     × rounds to whole paisa
     × rejects a cart below 500 taka
     × is not valid one second before Dhaka midnight on 1 Nov
     × expires exactly at Dhaka midnight on 12 Nov
     × can be used once per customer
     × never makes the total negative
 ❯ tests/api.test.ts (4 tests | 4 failed) 45ms
   × needs a login
   × does not let Bob use Alice's cart
   × applies EID10 to the owner cart
   × never writes the session cookie to the log

 FAIL  tests/api.test.ts > needs a login
AssertionError: expected 200 to be 401 // Object.is equality
 FAIL  tests/api.test.ts > does not let Bob use Alice's cart
AssertionError: expected 200 to be 404 // Object.is equality
 FAIL  tests/api.test.ts > never writes the session cookie to the log
+ {"msg":"apply coupon","headers":{"cookie":"sid=sess-alice-example", …
 FAIL  tests/coupon.test.ts > EID10 rules > caps the discount at 200 taka
-   "discountPaisa": 20000,
+   "discountPaisa": 50000,
 FAIL  tests/coupon.test.ts > EID10 rules > rounds to whole paisa
+   "discountPaisa": 10499.9,
+   "totalPaisa": 94499.1,
 FAIL  tests/coupon.test.ts > FLAT50 > never makes the total negative
+   "discountPaisa": 5000,
+   "totalPaisa": -2000,
…
 Test Files  2 failed | 1 passed (3)
      Tests  12 failed | 1 passed (13)

১৩টির মধ্যে ১২টি লাল; একমাত্র সবুজটি সেই দুর্বল test. “applies EID10 to the owner cart” লাল হয়েছে expected 422 to be 200 দিয়ে, কারণ test-এ ক্রেতা ছোট হাতে eid10 লিখেছিলেন। Type check আর lint, একই নমুনা কোডে, সত্যিকারের run:

~/bazarghar-coupon$ npx tsc --noEmit
src/coupon.ts(12,23): error TS2339: Property 'expiresAt' does not exist on type 'Coupon'.
~/bazarghar-coupon$ npx eslint src
src/app.ts
  9:40  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
  9:50  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
✖ 2 problems (2 errors, 0 warnings)

লক্ষ করুন, Vitest test চালানোর সময় type যাচাই করে না, শুধু type মুছে কোড চালায়। তাই expiresAt-এর ভুল test-এ দেখা গেছে আচরণ হিসেবে (কুপন কখনো মেয়াদোত্তীর্ণ হয় না), আর tsc-এ দেখা গেছে কারণ হিসেবে। আবার lint usedByUser-এর অব্যবহার ধরেনি, কারণ ESLint-এর ডিফল্ট নিয়ম শেষ ব্যবহৃত argument-এর আগের argument নিয়ে চুপ থাকে। এজন্যই একাধিক ছাঁকনি লাগে। নিচে ধাপে ধাপে দেখুন, প্রতিটি test নমুনা কোডের কোন লাইনে আটকায়।

10coupons.find((c) => c.code === code)12new Date(coupon.expiresAt) < now15(subtotalPaisa * coupon.value) / 10017totalPaisa: subtotalPaisa - discountPaisa9usedByUser (কখনো পড়া হয় না)Rcarts.get(cartId) — login ছাড়া
Test-এর ইনপুট আর ফল
ইনপুট
প্রত্যাশা
নমুনা কোড
  1. বড়-ছোট হাতের অক্ষর। ' eid10 ' আর 'EID10' হুবহু মেলে না, তাই not_found. Trim আর upper case না করায় আসল ক্রেতা কুপন পাবেন না।
  2. বানানো field. coupon.expiresAt হলো undefined, new Date(undefined) Invalid Date, আর তুলনা false. মেয়াদের পরের মুহূর্তেও কুপন ok.
  3. সীমা নেই। ৫০০০ টাকার কার্টে ১০% মানে 50000 পয়সা, কিন্তু নিয়ম বলে সর্বোচ্চ 20000. দোকান প্রতি অর্ডারে বাড়তি ৩০০ টাকা হারাত।
  4. ভগ্নাংশ পয়সা। 104999-এর ১০% হলো 10499.9. Payment gateway পূর্ণসংখ্যা চায়, আর হিসাবের খাতায় পয়সার ভগ্নাংশ জমতে থাকে। Math.round দিলে 10500.
  5. ঋণাত্মক মোট। ৩০ টাকার কার্টে ৫০ টাকার ছাড়ে মোট -2000 পয়সা। ছাড় কখনো subtotal-এর বেশি হবে না, এই নিয়ম কেউ লেখেনি।
  6. অব্যবহৃত argument. usedByUser function-এ ঢোকে, কিন্তু কোনো শর্তে নেই। একবারের কুপন সীমাহীন।
  7. Login নেই। Route কারও পরিচয় দেখে না, তাই cookie ছাড়া অনুরোধেও 200. আর অন্য ক্রেতার cookie দিয়ে Alice-এর কার্টেও 200, একটি IDOR.

সংশোধিত কোড

Review-এর পর, এবার নিয়ম আর শর্তসহ ভালো prompt দিয়ে বা নিজের হাতে, সংশোধিত কোড। প্রতিটি লাইন একটি নিয়মের সাথে মেলে:

export function normalizeCode(raw: string): string {
  return raw.trim().toUpperCase();
}

export function applyCoupon(
  items: CartItem[], rawCode: string, coupons: Coupon[], usedByUser: number, now: Date,
): CouponResult {
  const coupon = coupons.find((c) => c.code === normalizeCode(rawCode));
  if (!coupon) return { ok: false, reason: 'not_found' };

  const t = now.getTime();
  if (t < Date.parse(coupon.startsAt)) return { ok: false, reason: 'not_started' };
  if (t >= Date.parse(coupon.endsAt)) return { ok: false, reason: 'expired' };
  if (usedByUser >= coupon.perUserLimit) return { ok: false, reason: 'limit_reached' };

  const subtotalPaisa = items.reduce((s, i) => s + i.pricePaisa * i.qty, 0);
  if (subtotalPaisa < coupon.minSubtotalPaisa) return { ok: false, reason: 'min_subtotal' };

  let discountPaisa =
    coupon.kind === 'percent' ? Math.round((subtotalPaisa * coupon.value) / 100) : coupon.value;
  if (coupon.maxDiscountPaisa !== undefined) {
    discountPaisa = Math.min(discountPaisa, coupon.maxDiscountPaisa);
  }
  discountPaisa = Math.min(discountPaisa, subtotalPaisa);

  return { ok: true, subtotalPaisa, discountPaisa, totalPaisa: subtotalPaisa - discountPaisa };
}
app.post('/api/checkout/coupon', (req, res) => {
  const userId = sessionUser(req.headers.cookie);
  if (!userId) return res.status(401).json({ error: 'login required' });

  const { cartId, code } = req.body ?? {};
  if (typeof cartId !== 'string' || typeof code !== 'string' || code.length > 32) {
    return res.status(400).json({ error: 'invalid input' });
  }
  const cart = carts.get(cartId);
  if (!cart || cart.userId !== userId) return res.status(404).json({ error: 'cart not found' });

  const used = usage.get(`${userId}:${normalizeCode(code)}`) ?? 0;
  const result = applyCoupon(cart.items, code, coupons, used, new Date());
  logs.push(JSON.stringify({ msg: 'apply coupon', userId, cartId, ok: result.ok }));
  if (!result.ok) return res.status(422).json(result);
  return res.json(result);
});

কয়েকটি সিদ্ধান্তের কারণ। অন্যের কার্টে 403 নয়, 404: কার্টটি আছে কি না, তা-ও অন্যকে জানানো হয় না। মেয়াদের শেষ সময় “ঢাকার ১২ নভেম্বরের মধ্যরাত” UTC-তে 2026-11-11T18:00:00Z হিসেবে রাখা, আর তুলনা >=, অর্থাৎ শেষ মুহূর্তটি বাদ। now argument হিসেবে আসে, তাই test-এ সময় ঠিক রাখা যায়। ছোট এই উদাহরণে input যাচাই হাতে লেখা; বড় অ্যাপে পর্ব ২৭-এর মতো Zod schema ভালো। আসল দোকানে ব্যবহারের হিসাব database-এ আর একই transaction-এ বাড়াতে হবে, নইলে একসাথে দুটি অনুরোধে একবারের কুপন দুবার চলতে পারে (পর্ব ৪৩)। সংশোধিত কোডে সত্যিকারের run:

~/bazarghar-coupon$ npx tsc --noEmit && npx eslint src && echo "types and lint ok"
types and lint ok
~/bazarghar-coupon$ npx vitest run --reporter=verbose
 ✓ tests/coupon.weak.test.ts > applies the coupon 1ms
 ✓ tests/coupon.test.ts > EID10 rules > accepts lower case and spaces 1ms
 ✓ tests/coupon.test.ts > EID10 rules > caps the discount at 200 taka 0ms
 ✓ tests/coupon.test.ts > EID10 rules > rounds to whole paisa 0ms
 ✓ tests/coupon.test.ts > EID10 rules > rejects a cart below 500 taka 0ms
 ✓ tests/coupon.test.ts > EID10 rules > is not valid one second before Dhaka midnight on 1 Nov 0ms
 ✓ tests/coupon.test.ts > EID10 rules > expires exactly at Dhaka midnight on 12 Nov 0ms
 ✓ tests/coupon.test.ts > EID10 rules > can be used once per customer 0ms
 ✓ tests/coupon.test.ts > FLAT50 > never makes the total negative 0ms
 ✓ tests/api.test.ts > needs a login 25ms
 ✓ tests/api.test.ts > does not let Bob use Alice's cart 5ms
 ✓ tests/api.test.ts > applies EID10 to the owner cart 3ms
 ✓ tests/api.test.ts > never writes the session cookie to the log 0ms
 Test Files  3 passed (3)
      Tests  13 passed (13)

সবুজ test তখনই বিশ্বাসযোগ্য, যখন জানি তারা ভুল ধরতে পারে। তাই শেষ ধাপে সংশোধিত কোডে হাতে চারটি mutant ঢোকালাম, একবারে একটি, প্রতিবার পুরো suite চালিয়ে আবার আসল কোড ফেরত। একটি ছোট node script দিয়ে, সত্যিকারের run:

~/bazarghar-coupon$ node mutate.mjs
KILLED   t >= Date.parse(coupon.endsAt)  ->  t > Date.parse(coupon.endsAt)
         FAIL  tests/coupon.test.ts > EID10 rules > expires exactly at Dhaka midnight on 12 Nov
KILLED   discountPaisa = Math.min(discountPaisa, subtotalPaisa);  ->  (line removed)
         FAIL  tests/coupon.test.ts > FLAT50 > never makes the total negative
KILLED   !cart || cart.userId !== userId  ->  !cart
         FAIL  tests/api.test.ts > does not let Bob use Alice's cart
KILLED   usedByUser >= coupon.perUserLimit  ->  usedByUser > coupon.perUserLimit
         FAIL  tests/coupon.test.ts > EID10 rules > can be used once per customer

চারটি mutant-ই ধরা পড়ল, আর প্রতিটি ঠিক সেই test-এ, যা ওই নিয়মের জন্য লেখা। মালিকানার শর্ত মুছলে Bob-এর test লাল; এই প্রমাণ ছাড়া “authorization আছে” কথাটি শুধু একটি দাবি। Stryker-এর মতো টুল এই কাজ স্বয়ংক্রিয়ভাবে, শত শত mutant দিয়ে করে (পর্ব ৭২); এখানে হাতে চারটি দিয়ে ধারণাটি দেখা হলো।

৯ · গোপনীয়তা, লাইসেন্স আর শেখা বনাম কাজ ছেড়ে দেওয়া

যা কখনো পেস্ট করবেন না

Prompt-এ যা লেখেন, তা অন্য কারও server-এ যায়। সেবাভেদে সেটি সংরক্ষিত হতে পারে, মানুষ পড়তে পারেন, বা মডেল প্রশিক্ষণে ব্যবহার হতে পারে; নিয়ম জানতে সেই সেবার শর্ত আর আপনার প্রতিষ্ঠানের নীতি পড়ুন। তিনটি জিনিস কখনো এমন টুলে নয়, যেটি ব্যবহারের অনুমতি আপনার নেই: secret (key, password, .env-এর লেখা), ক্রেতার তথ্য (নাম, ফোন, ঠিকানা, অর্ডার; অর্থাৎ PII), আর প্রতিষ্ঠানের গোপন কোড. ২০২৩ সালে প্রকাশিত খবর অনুযায়ী একটি বড় ইলেকট্রনিক্স প্রতিষ্ঠানের কয়েকজন কর্মী অভ্যন্তরীণ source code একটি জনপ্রিয় chat সেবায় পেস্ট করেছিলেন, যার পর প্রতিষ্ঠানটি সাময়িকভাবে এমন টুলের ব্যবহার সীমিত করে। কাজের ধরনটিই ঝুঁকি, কোনো বিশেষ প্রতিষ্ঠান নয়।

বিকল্প সহজ: আসল মানের বদলে example-secret, আসল ক্রেতার বদলে বানানো নমুনা, পুরো repository-র বদলে ছোট একটি অংশ, যাতে গোপন ব্যবসায়িক যুক্তি নেই। আর agent-ধাঁচের টুলকে production database-এর URL বা deploy-এর key দেবেন না; least privilege-এর নীতি AI-এর বেলাতেও খাটে। AI-এর নিজস্ব নিরাপত্তা ঝুঁকি, যেমন prompt injection, নিয়ে বিস্তারিত আছে AI security পর্বে।

লাইসেন্স আর কৃতিত্ব — সতর্ক উত্তর

AI-এর লেখা কোডের মালিকানা আর লাইসেন্স নিয়ে আইন এখনো স্থির নয়, আর দেশভেদে আলাদা। কয়েকটি বিষয় তবু বলা যায়, সতর্কভাবে। এক, open source কোডের নিজস্ব software licence থাকে; কিছু লাইসেন্স কপিরাইট নোটিশ রাখতে বলে, আর GPL-এর মতো কিছু লাইসেন্স সেই কোড থেকে তৈরি কাজও একই শর্তে প্রকাশ করতে বলে। AI যদি কোনো পরিচিত প্রকল্পের কোড প্রায় হুবহু লিখে দেয়, লাইসেন্সের দায় তৈরি হতে পারে। দুই, কিছু টুলে এমন মিল খুঁজে সতর্ক করার বা আটকানোর ব্যবস্থা আছে। তিন, মার্কিন কপিরাইট অফিস ২০২৫ সালের একটি প্রতিবেদনে বলেছে যে শুধু AI-এর তৈরি অংশে কপিরাইট সুরক্ষা পেতে মানুষের সৃজনশীল অবদান লাগে; বাংলাদেশে বা আপনার দেশে নিয়ম কী, তা আইনজ্ঞের কাছ থেকে জানুন। বাস্তব পরামর্শ: প্রতিষ্ঠানের নীতি মানুন, বড় হুবহু অংশ দেখলে উৎস খুঁজুন, আর ক্লায়েন্টের কাজে AI ব্যবহারের নিয়ম চুক্তিতে স্পষ্ট করুন। পেশাগত নৈতিকতার বড় আলোচনা আছে professional ethics পর্বে।

শেখা, না কাজ ছেড়ে দেওয়া

শিক্ষার্থীদের জন্য সবচেয়ে বড় প্রশ্নটি প্রযুক্তিগত নয়। AI দিয়ে একটি অ্যাসাইনমেন্ট দশ মিনিটে শেষ করা যায়, কিন্তু তাতে মাথায় কী থাকল? যে দক্ষতা দিয়ে আপনি AI-এর ভুল ধরবেন, সেই দক্ষতাই তৈরি হয় নিজে ভুল করে, আটকে গিয়ে, error পড়ে। ইন্টারভিউতে বা লিখিত পরীক্ষায় AI থাকে না; থাকে আপনার বোঝা। কয়েকটি অভ্যাস কাজে লাগে:

  • আগে নিজে চেষ্টা, অন্তত ২০ মিনিট; তারপর AI-কে সমাধান নয়, ইঙ্গিত চান।
  • ব্যাখ্যা চান, উত্তর নয়: “এই error কেন আসছে, সম্ভাব্য তিনটি কারণ বলো; সমাধান লিখবে না।”
  • উল্টো দিক থেকে যাচাই: AI-এর ব্যাখ্যা পড়ে নিজের ভাষায় লিখুন, তারপর docs-এর সাথে মেলান।
  • AI-কে পরীক্ষক বানান: “React-এর useEffect নিয়ে আমাকে পাঁচটি প্রশ্ন করো, আমার উত্তরের ভুল ধরিয়ে দাও।”
  • নিয়মটি জানুন: প্রতিষ্ঠান বা পরীক্ষা AI-এর ব্যবহার নিষেধ করলে সেটি মানা সততার প্রশ্ন।

১০ · AI-এর যুগে: আপনার নিজের কাজের নিয়ম

এই পর্ব নিজেই একটি “AI-এর যুগে” অংশ, তাই এখানে পুরো কোর্সের শিক্ষা একটি prompt আর একটি চেকলিস্টে। প্রথমে কোর্স জুড়ে দেখা AI-এর ভুলের একটি সারাংশ:

AI-এর ভুলপ্রথম যাচাই
পুরোনো API: Pages Router, middleware.ts, Prisma 6-এর schema, Vitest 4-এর ডিফল্ট, MSW 2-এর optionনিজের version-এর docs আর migration guide; tsc, build-এর সতর্কবার্তা
বানানো package বা optionnpm view, docs-এ নাম খোঁজা, type error
অদরকারি dependencyBuilt-in দিয়ে হয় কি না; lockfile-এর diff
চলে কিন্তু secret ফাঁস করেBuild আর log-এ নকল মান খোঁজা; scanner
Server-এ অনুমতি নেইCookie ছাড়া আর অন্যের cookie দিয়ে অনুরোধ
Error লুকানোখালি catch, @ts-ignore, eslint-disable খোঁজা
“Test পাস করেছে” দাবিনিজে চালানো; ইচ্ছা করে একটি ভুল ঢুকিয়ে দেখা

নিচের prompt-টি যেকোনো ফুল-স্ট্যাক কাজের জন্য কাঠামো হিসেবে নিন। বন্ধনীর জায়গাগুলো নিজের কাজ দিয়ে ভরুন, আর কোনো আসল secret বা ক্রেতার তথ্য দেবেন না।

প্রসঙ্গ: আমার project [Next.js 16.4 App Router / Express 5.3], React 19, TypeScript 6.0, Prisma 7.10.1, Vitest 5.1. দাম পূর্ণসংখ্যা পয়সায়। বিদ্যমান কোড: [যে type আর function-এর সাথে মিলবে, শুধু সেটুকু] কাজ: [এক বাক্যে] গ্রহণের নিয়ম: [৩ থেকে ৮টি, প্রতিটি সংখ্যাসহ] নিয়ম: ১. এখনই কোড নয়। আগে পরিকল্পনা দাও: কোন ফাইল, কোন function, কোন test. আমি অনুমোদন দিলে তবেই কোড। ২. আগে গ্রহণের নিয়মগুলো থেকে test লেখো, প্রত্যাশা হাতে হিসাব করা সংখ্যায়। পরে test বদলাবে না। ৩. কোনো নতুন package নয়। একান্ত দরকার হলে নাম, কেন লাগবে আর npm-এ কী দেখে আমি যাচাই করব, তা বলো। ৪. প্রতিটি API কোন version-এর docs থেকে, বলো। Pages Router, middleware.ts, schema-র url বা অন্য পুরোনো নাম ব্যবহার করবে না। নিশ্চিত না হলে "অনিশ্চিত" লেখো। ৫. প্রতিটি server-এর কাজের শুরুতে login আর মালিকানা যাচাই; দাম আর মালিক কখনো client থেকে নয়; secret client-এ বা log-এ নয়। ৬. খালি catch, any, ts-ignore বা eslint-disable নয়। ৭. কোড নিজে চালাওনি, তাই "পাস করেছে" বলবে না। শেষে আমাকে চালানোর কমান্ডগুলো দাও: typecheck, lint, test, আর একটি কমান্ড যা অন্য ব্যবহারকারীর cookie দিয়ে অনুরোধ পাঠিয়ে দেখায় যে কাজটি থামে।

AI-এর লেখা কোড merge-এর আগে — চেকলিস্ট

আরও গভীরে: AI-এর লেখা কোডের নিরাপত্তা নিয়ে গবেষণা বেড়েছে। Pearce ও সহকর্মীদের “Asleep at the Keyboard?” (IEEE S&P ২০২২) নিরাপত্তা-সংবেদনশীল কিছু পরিস্থিতিতে একটি কোড-সহকারীর প্রস্তাবের বড় অংশে, প্রায় ৪০%, দুর্বলতা পেয়েছিল। Perry ও সহকর্মীদের ব্যবহারকারী-গবেষণা (ACM CCS ২০২৩) জানায়, সহকারী ব্যবহারকারীরা কিছু কাজে কম নিরাপদ কোড লিখেছিলেন অথচ নিজেদের কোডকে বেশি নিরাপদ ভেবেছিলেন। দুটিই নির্দিষ্ট সময় আর মডেলের মাপ; তবে “আত্মবিশ্বাস আর সঠিকতা আলাদা” এই শিক্ষা টুল বদলালেও খাটে।

পরীক্ষা ও ইন্টারভিউতে:

  • Package hallucination কেন নিরাপত্তার ঝুঁকি? → বানানো নাম আক্রমণকারী আগেই প্রকাশ করে রাখলে AI-এর পরামর্শে install করা মানে তাঁর কোড চালানো।
  • Install-এর আগে package যাচাইয়ের একটি কমান্ড? → npm view <name>: নেই হলে E404; থাকলে বয়স, version, maintainer আর repository দেখা।
  • Coverage ১০০% হলেও test দুর্বল হতে পারে কেন? → Coverage বলে লাইন চলেছে, ফল যাচাই হয়েছে কি না বলে না; mutation testing সেটি মাপে।
  • AI-কে কাজ দেওয়ার আগে কোন তথ্যগুলো দেবেন? → Version, বিদ্যমান কোড, শর্ত, গ্রহণের test আর কী চাই না।
  • AI-এর PR-এ কোন ফাইলের বদল আলাদা করে পড়বেন? → package.json, lockfile আর test ফাইল।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১AI সহকারী কি সত্যিই ডেভেলপারকে দ্রুত করে? গবেষণা কী বলে?

উত্তরটি “নির্ভর করে”, আর সেই নির্ভরতাটাই আকর্ষণীয়। প্রথম দিকের একটি নিয়ন্ত্রিত পরীক্ষায়, GitHub-সংশ্লিষ্ট গবেষকদের ২০২৩ সালে প্রকাশিত কাজে, অংশগ্রহণকারীদের JavaScript-এ একটি ছোট HTTP server লিখতে দেওয়া হয়েছিল; সহকারী পাওয়া দল উল্লেখযোগ্যভাবে কম সময়ে শেষ করেছিল। কাজটি ছিল নতুন, ছোট আর সুনির্দিষ্ট, ঠিক যেখানে AI সবচেয়ে ভালো।

২০২৫ সালের জুলাইয়ে METR নামের একটি গবেষণা সংস্থা ভিন্ন ধরনের একটি randomized controlled trial প্রকাশ করে। ১৬ জন অভিজ্ঞ open source ডেভেলপার নিজেদের চেনা, বড়, পরিণত repository-তে ২৪৬টি আসল কাজ করেছিলেন; প্রতিটি কাজে AI ব্যবহারের অনুমতি এলোমেলোভাবে দেওয়া বা না দেওয়া হয়েছিল। ফল চমকে দেওয়ার মতো: AI-সহ কাজে গড়ে প্রায় ১৯% বেশি সময় লেগেছিল। আরও চমকপ্রদ, অংশগ্রহণকারীরা কাজ শেষেও ভাবছিলেন AI তাঁদের প্রায় ২০% দ্রুত করেছে। METR নিজেই সতর্ক করেছে যে ফলটি সব ধরনের কাজে বা পরের প্রজন্মের টুলে খাটবে, এমন দাবি তারা করে না।

দুটি ফল পরস্পরবিরোধী নয়। বড় চেনা codebase-এ অভিজ্ঞ মানুষ এমনিতেই দ্রুত; সেখানে prompt লেখা, অপেক্ষা, আর AI-এর প্রায়-ঠিক উত্তর পড়ে সারানোর খরচ লাভকে ছাড়িয়ে যেতে পারে। অচেনা কাজে, নতুন library শিখতে, boilerplate-এ লাভ বেশি। আর অনুভূতি আর মাপের ফারাক একটি বড় শিক্ষা: “দ্রুত লাগছে” মানেই দ্রুত নয়, ঠিক যেমন “চলছে” মানেই ঠিক নয়।

দলের জন্য বাস্তব প্রশ্নটি তাই “AI ব্যবহার করব কি না” নয়, বরং কোন কাজে, আর মোট সময়ে review আর সংশোধন ধরে মাপলে কী দাঁড়ায়। দ্রুত লেখা কিন্তু ধীর review হলে লাভ review-এর টেবিলে হারিয়ে যায়।

মূল উপলব্ধি: উৎপাদনশীলতা মাপুন শেষ পর্যন্ত, merge আর production পর্যন্ত, শুধু লেখার মুহূর্ত পর্যন্ত নয়; আর নিজের অনুভূতির চেয়ে মাপকে বেশি বিশ্বাস করুন।

প্র ০২AI বানানো package-এর নাম দিলে সমস্যা শুধু install ব্যর্থ হওয়া। তাহলে একে নিরাপত্তার ঝুঁকি বলা কেন?

আজ install ব্যর্থ হয়, কিন্তু নামটি খালি থাকে, আর npm-এর মতো public registry-তে যে কেউ খালি নামে package প্রকাশ করতে পারেন। Spracklen ও সহকর্মীদের গবেষণা (USENIX Security ২০২৫) দেখিয়েছিল, তাঁদের নমুনায় প্রস্তাবিত package-এর প্রায় ১৯.৭% অস্তিত্বহীন ছিল, আর এর মধ্যে দুই লাখের বেশি আলাদা নাম ছিল। গুরুত্বপূর্ণ পর্যবেক্ষণ: অনেক বানানো নাম একই prompt-এ বারবার একই রকম ফিরে আসে। অর্থাৎ নামগুলো অনুমান করা যায়। একজন আক্রমণকারী জনপ্রিয় প্রশ্ন দিয়ে মডেলকে জিজ্ঞেস করে বারবার আসা বানানো নামগুলো সংগ্রহ করতে পারেন, তারপর সেই নামে install script-সহ package প্রকাশ করতে পারেন।

এটি নতুন কৌশলের নতুন রূপ। Typosquatting বহু পুরোনো: ২০১৭ সালে npm crossenv-সহ কয়েকটি package সরিয়েছিল, যেগুলো জনপ্রিয় নামের নকল ছিল আর environment variable পাঠিয়ে দিত বলে জানানো হয়েছিল। ২০২৪ সালে একজন নিরাপত্তা গবেষক AI-এর বারবার প্রস্তাব করা একটি বানানো Python package-এর নামে একটি ক্ষতিহীন খালি package প্রকাশ করে পরীক্ষা করেছিলেন বলে জানিয়েছিলেন; তাঁর হিসাবে সেটি কয়েক মাসে হাজার হাজারবার নামানো হয়েছিল। ২০২৫ সালে Python Software Foundation-এর নিরাপত্তায় কাজ করা Seth Larson এই ধরনকে “slopsquatting” নাম দেন বলে ব্যাপকভাবে উদ্ধৃত।

ঝুঁকিটি install-এর মুহূর্তেই বাস্তব হয়, কারণ npm package-এর postinstall script install-এর সময় আপনার যন্ত্রে, আপনার অধিকারে চলে: আপনার .env, SSH key, CI-এর token সবই নাগালে। AI agent নিজে command চালাতে পারলে মানুষের চোখ পড়ার আগেই এটি ঘটতে পারে।

প্রতিরক্ষা কয়েক স্তরের: নতুন নাম দেখলে npm view, repository আর docs; agent-এর install-এর অনুমতি সীমিত রাখা; CI-তে npm ci আর lockfile; install script বন্ধ রেখে পরখ; আর সদ্য প্রকাশিত version-এ কয়েক দিনের অপেক্ষার নিয়ম।

মূল উপলব্ধি: বানানো নাম আজকের bug, কালকের ফাঁদ। Package-এর নাম একটি বিশ্বাসের সিদ্ধান্ত, আর সেই সিদ্ধান্ত AI-এর হাতে নয়, আপনার হাতে থাকা উচিত।

প্র ০৩AI যদি লাখ লাখ open source প্রকল্প থেকে শেখে, তাহলে তার কোড তো গড়পড়তা ভালো হওয়ার কথা। নিরাপত্তার ভুল কেন হয়?

কারণ “গড়পড়তা” আর “নিরাপদ” এক জিনিস নয়। ইন্টারনেটের কোডের বড় অংশ টিউটোরিয়াল, উত্তর-প্রশ্নের সাইট আর শেখার প্রকল্প, যেগুলো ধারণা দেখাতে লেখা, production-এর জন্য নয়। একটি টিউটোরিয়ালে login যাচাই বাদ দেওয়া হয় যাতে মূল কথাটি পরিষ্কার থাকে; SQL-এ string জোড়া হয় কারণ পড়তে সহজ। মডেল সম্ভাব্য লেখা তৈরি করে, আর এমন কোড প্রচুর বলেই সম্ভাব্য।

গবেষণায় এর ইঙ্গিত আছে। ২০২১ সালে প্রকাশিত আর IEEE S&P ২০২২-এ উপস্থাপিত Pearce ও সহকর্মীদের “Asleep at the Keyboard?” গবেষণায় একটি কোড-সহকারীকে MITRE-এর পরিচিত দুর্বলতার তালিকা থেকে নেওয়া পরিস্থিতিতে কোড লিখতে দেওয়া হয়; উৎপন্ন প্রোগ্রামের প্রায় ৪০% দুর্বল পাওয়া যায়। Perry ও সহকর্মীদের ACM CCS ২০২৩-এর গবেষণায় মানুষের আচরণ মাপা হয়: সহকারী পাওয়া অংশগ্রহণকারীরা কয়েকটি কাজে কম নিরাপদ কোড লিখেছিলেন, অথচ নিজেদের কোড বেশি নিরাপদ বলে বিশ্বাস করেছিলেন। দুটি গবেষণাই নির্দিষ্ট মডেল আর সময়ের; নতুন মডেল হয়তো ভালো, কিন্তু মূল সমস্যাটি কাঠামোগত।

কাঠামোগত কেন? নিরাপত্তার নিয়ম প্রায়ই কোডে অদৃশ্য প্রসঙ্গের ওপর নির্ভর করে: এই action কে ডাকতে পারবেন, এই field কে দেখতে পারবেন, এই মান কোথা থেকে আসে। মডেল আপনার ব্যবসার নিয়ম জানে না, যদি না বলেন। এই পর্বের নমুনা কুপন কোডে প্রতিটি লাইন আলাদাভাবে “যুক্তিসংগত”, তবু login আর মালিকানার প্রশ্নটি কোনো লাইনেই নেই, কারণ prompt-এ ছিল না।

আরেকটি কারণ উৎসাহের দিক: AI-কে প্রায়ই error থামাতে বলা হয়। CORS error এলে origin: true, CSP-তে unsafe-inline, type error-এ any: error চলে যায়, ঝুঁকি থেকে যায় (পর্ব ৫০)।

মূল উপলব্ধি: নিরাপত্তা হলো প্রসঙ্গের নিয়ম, আর প্রসঙ্গ আপনার মাথায়। তাই নিয়মগুলো prompt-এ লিখুন, আর test দিয়ে প্রমাণ করুন, কারণ আত্মবিশ্বাসী চেহারার কোড আর নিরাপদ কোড আলাদা।

প্র ০৪AI-এর লেখা কোড কি নিজের বলে ব্যবহার করা যায়? লাইসেন্স আর কৃতিত্বের প্রশ্ন কতটা গুরুতর?

সৎ উত্তর হলো, আইন এখনো তৈরি হচ্ছে, তাই এখানে নিশ্চিত দাবি না করে প্রশ্নগুলো সাজাই। প্রথম প্রশ্ন মালিকানা: AI-এর তৈরি কোডে কপিরাইট কার? মার্কিন কপিরাইট অফিস ২০২৫ সালে প্রকাশিত একটি প্রতিবেদনে অবস্থান দিয়েছে যে কপিরাইট সুরক্ষার জন্য মানুষের সৃজনশীল অবদান লাগে; শুধু prompt দিয়ে তৈরি অংশ সাধারণত সেই শর্ত পূরণ করে না, তবে মানুষের বাছাই, বিন্যাস আর বদল সুরক্ষিত হতে পারে। অন্য দেশের অবস্থান আলাদা হতে পারে, আর বাংলাদেশের প্রেক্ষাপটে নির্দিষ্ট নিয়ম জানতে আইনজ্ঞের পরামর্শ নিন।

দ্বিতীয় প্রশ্ন উৎসের লাইসেন্স। মডেল কখনো কোনো প্রকল্পের কোড প্রায় হুবহু লিখে দিতে পারে, বিশেষ করে বিখ্যাত ছোট function. সেই প্রকল্প GPL হলে আর আপনার প্রকল্প বন্ধ উৎসের হলে, লাইসেন্সের শর্ত ভাঙার প্রশ্ন ওঠে। ২০২২ সালের নভেম্বরে যুক্তরাষ্ট্রে একটি কোড-সহকারীর বিরুদ্ধে open source লাইসেন্স ভঙ্গের অভিযোগে একটি class action মামলা হয়েছিল; প্রকাশিত খবর অনুযায়ী পরে বেশ কয়েকটি দাবি খারিজ হয়, আর বাকি অংশ নিয়ে প্রক্রিয়া চলেছে। মামলার চূড়ান্ত শিক্ষা এখনো স্পষ্ট নয়।

তৃতীয় প্রশ্ন সততা আর কৃতিত্ব। শিক্ষাপ্রতিষ্ঠান, চাকরির পরীক্ষা আর ক্লায়েন্টের চুক্তিতে AI ব্যবহারের নিয়ম থাকতে পারে। নিয়ম না থাকলেও স্বচ্ছতা ভালো অভ্যাস: PR-এর বিবরণে “AI-এর সাহায্যে লেখা” লিখলে reviewer জানেন কোথায় বাড়তি নজর দিতে হবে। কিছু open source প্রকল্প নিজেদের অবদানের নীতিতে AI-এর লেখা কোড নিয়ে নিয়ম ঠিক করেছে; অবদান রাখার আগে সেটি পড়ুন।

বাস্তব পথ: প্রতিষ্ঠানের নীতি মানুন; টুলের হুবহু-মিল সতর্কতা থাকলে চালু রাখুন; লম্বা, অদ্ভুতভাবে নিখুঁত অংশ দেখলে উৎস খুঁজুন; আর যে কোড বোঝেন না, তা নিজের নামে জমা দেবেন না।

মূল উপলব্ধি: আইন অনিশ্চিত হলে নিরাপদ অবস্থান হলো স্বচ্ছতা আর বোঝা। আপনি যা বোঝেন, বদলেছেন আর যাচাই করেছেন, তার দায় আর কৃতিত্ব দুটোই সবচেয়ে স্পষ্টভাবে আপনার।

প্র ০৫ক্যালকুলেটর আসার পর মানুষ হাতে গুণ করা ভুলে গেছে, তাতে ক্ষতি হয়নি। AI-এর বেলায় কোড লেখা ভুলে গেলে ক্ষতি কী?

উপমাটি অর্ধেক ঠিক। ক্যালকুলেটর নির্ভরযোগ্য: ২৩ × ৪৭ সবসময় ১০৮১. তাই হাতে গুণ ভুলে গেলেও ফল বিশ্বাস করা যায়। তবু লক্ষ করুন, ভালো প্রকৌশলী ক্যালকুলেটরের উত্তর দেখে মনে মনে আন্দাজ করেন, “মোটামুটি হাজারের কাছাকাছি হওয়ার কথা”; ভুল বোতাম চাপলে এই আন্দাজই ধরিয়ে দেয়। AI ক্যালকুলেটরের মতো নির্ভরযোগ্য নয়; এই পর্বের নমুনা উত্তরের মতো কোড দেখতে নিখুঁত হয়েও ১৩টির মধ্যে ১২টি নিয়ম ভাঙতে পারে। যে মানুষ নিজে কখনো ছাড়ের সীমা, সময়ের অঞ্চল বা অনুমতির পথ নিয়ে ভাবেননি, তাঁর কাছে সেই আন্দাজের যন্ত্রটাই নেই।

শেখার বিজ্ঞানেও এর সমর্থন আছে। মনোবিজ্ঞানী Robert Bjork আর Elizabeth Bjork-এর “desirable difficulties” ধারণা অনুযায়ী, কিছুটা কষ্ট করে মনে করা, নিজে চেষ্টা করে ভুল করা দীর্ঘমেয়াদি শেখাকে শক্ত করে, যদিও মুহূর্তে ধীর লাগে। উত্তর সরাসরি পেয়ে গেলে বোঝার অনুভূতি হয়, কিন্তু পরে নিজে করতে গেলে দেখা যায় কিছুই থাকেনি।

পেশার দিকেও প্রভাব আছে। ২০২২ সালের ডিসেম্বরে Stack Overflow AI-এর তৈরি উত্তর সাময়িকভাবে নিষিদ্ধ করেছিল, কারণ সেগুলো দেখতে বিশ্বাসযোগ্য কিন্তু প্রায়ই ভুল, আর যাচাইয়ের ভার পড়ছিল স্বেচ্ছাসেবকদের ওপর। দলের ভেতরেও একই হয়: যিনি নিজে বোঝেন না, তাঁর PR-এর যাচাইয়ের ভার পড়ে অন্যের ওপর। ইন্টারভিউতে প্রশ্ন আসে “এই কোডে bug কোথায়” বা “কেন এই নকশা”, যার উত্তর AI-কে জিজ্ঞেস করে দেওয়া যায় না।

তাই প্রশ্নটি AI ব্যবহার বনাম না-ব্যবহার নয়, বরং কোন কাজটি নিজের হাতে রাখবেন। শেখার সময় মূল ধারণাগুলো, যেমন state, request-এর যাত্রা, transaction, অনুমতি, নিজে লিখুন; AI-কে শিক্ষক আর পরীক্ষক বানান। দক্ষ হওয়ার পর পুনরাবৃত্ত কাজ AI-কে দিন, আর বিচারের কাজটি নিজের কাছে রাখুন।

মূল উপলব্ধি: AI-এর ভুল ধরার ক্ষমতা আসে নিজে সেই কাজ করার অভিজ্ঞতা থেকে। যে দক্ষতা দিয়ে যাচাই করবেন, সেটি AI-কে দিয়ে দিলে যাচাই করার কেউ থাকে না।

অনুশীলন

হিসাব, কমান্ড, সমালোচনা আর আউটপুট অনুমান, চারটিই আছে।

  1. হিসাব (দূরত্ব আর ছাড়): (ক) Levenshtein দূরত্ব হিসাব করুন: raect থেকে react, আর crossenv থেকে cross-env. (খ) EID10-এর নিয়ম: ১০%, পূর্ণসংখ্যায় রাউন্ড, সর্বোচ্চ 20000 পয়সা, কার্ট ন্যূনতম 50000. তিনটি কার্টে ছাড় আর মোট বের করুন: 104999, 250000 আর 49999 পয়সা।

    (ক) raect → react: দ্বিতীয় অক্ষর a-কে e আর তৃতীয় e-কে a বদল, দুটি বদল, দূরত্ব ২। (একটি অদলবদলকে এক ধাপ ধরা Damerau-Levenshtein-এ এটি ১ হতো।) crossenv → cross-env: একটি “-” যোগ, দূরত্ব ১।

    (খ) 104999 × 0.1 = 10499.9, রাউন্ড করে 10500; সীমার নিচে; মোট 104999 − 10500 = ৯৪৪৯৯ পয়সা। 250000 × 0.1 = 25000, সীমা 20000, তাই ছাড় 20000, মোট ২৩০০০০ পয়সা। 49999 পয়সা ন্যূনতম 50000-এর এক পয়সা কম, তাই কুপন বাতিল (min_subtotal), ছাড় ০, মোট ৪৯৯৯৯।

  2. কমান্ড (অচেনা package): AI একটি কাজে bd-phone-validator নামের package install করতে বলেছে। Install না করে কোন কোন কমান্ড চালাবেন আর প্রতিটির ফলে কী দেখবেন? Package যদি থাকে, install করার নিরাপদ ক্রম কী?

    প্রথমে npm view bd-phone-validator: E404 হলে নামটি নেই, অর্থাৎ বানানো; install নয়, কাজটি নিজের কোডে বা পরিচিত library দিয়ে। থাকলে npm view bd-phone-validator time maintainers repository.url versions: কবে তৈরি, কতগুলো version, শেষ release কবে, কে প্রকাশ করেন, repository আছে কি না। খুব নতুন, একটিমাত্র version, repository নেই, বা জনপ্রিয় নামের কাছাকাছি বানান, এগুলো সতর্কতার চিহ্ন। Repository খুলে package.json-এ postinstall দেখুন। নিরাপদ ক্রম: আলাদা ফাঁকা ফোল্ডারে npm i bd-phone-validator --ignore-scripts, ফাইলগুলো দেখা, তারপর আসল project-এ install, lockfile-এর diff পড়া আর npm audit. অনেক সময় দেখা যায় ১১ অঙ্কের নম্বর যাচাইয়ের জন্য package-এরই দরকার নেই।

  3. সমালোচনা (নকশা): নিচের নমুনা AI উত্তরে অন্তত ছয়টি সমস্যা ধরুন: “'use server'; export async function applyCoupon(formData) { console.log('env', process.env); const cartId = formData.get('cartId'); const discount = Number(formData.get('discount')); const cart = await prisma.cart.findUnique({ where: { id: cartId } }); try { await prisma.cart.update({ where: { id: cartId }, data: { total: cart.total - discount } }); } catch (e) {} redirect('/checkout'); }”
    • Login বা মালিকানা যাচাই নেই: যে কেউ যেকোনো cartId-এ action ডাকতে পারেন (পর্ব ৫৪)।
    • ছাড়ের পরিমাণ client থেকে: discount ফর্মে বদলে পাঠালে যেকোনো ছাড়।
    • কুপনের নিয়মই নেই: কোড, মেয়াদ, সীমা, ব্যবহারের সংখ্যা কিছুই দেখা হয়নি।
    • console.log(process.env): সব secret server-এর log-এ।
    • খালি catch: ব্যর্থ হলেও ব্যবহারকারী সফল ভাববেন।
    • Input যাচাই নেই: Number('abc') হয় NaN, মোট হয় NaN; cart null হলে crash.
    • মোট database-এ জমানো আর ছাড় বিয়োগ: বারবার ডাকলে বারবার কমে; মোট হিসাব করা উচিত দাম থেকে, প্রতিবার।
  4. আউটপুট অনুমান: এই নমুনা function আর কুপন দেওয়া আছে: applyCoupon(items, code, coupons, used, now) কোড হুবহু মেলায় (c.code === code), মেয়াদ দেখে new Date(coupon.expiresAt) < now দিয়ে, ছাড় (subtotal * value) / 100 বা স্থির value, আর মোট subtotal − discount. কুপন: { code: 'FLAT50', kind: 'fixed', value: 5000, endsAt: '2026-01-01T00:00:00Z' } (কোনো expiresAt নেই)। তিনটি ডাকের ফল কী? (ক) কার্ট 3000 পয়সা, কোড 'FLAT50', now ১ মার্চ ২০২৬. (খ) একই, কোড 'flat50'. (গ) কার্ট 12000, কোড 'FLAT50'.

    (ক) { ok: true, subtotalPaisa: 3000, discountPaisa: 5000, totalPaisa: -2000 }. মেয়াদ ১ জানুয়ারি শেষ, কিন্তু function পড়ে expiresAt, যা undefined; Invalid Date-এর সাথে তুলনা false, তাই মেয়াদোত্তীর্ণ ধরা হয় না, আর ছাড় subtotal-এর বেশি। (খ) { ok: false, reason: 'not_found' }, কারণ হুবহু তুলনায় ছোট হাতের অক্ষর মেলে না। (গ) { ok: true, subtotalPaisa: 12000, discountPaisa: 5000, totalPaisa: 7000 }. ফলটি “ঠিক” দেখায়, অথচ কুপনের মেয়াদ দুই মাস আগে শেষ। শুধু এই ঘটনাটি test করলে bug ধরা পড়ত না।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমAI-এর সাহায্যে একটি নতুন feature যোগ করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Version, শর্ত আর গ্রহণের নিয়মসহ কাজের বিবরণ লেখা
  2. কোড নয়, আগে পরিকল্পনা চেয়ে পড়া
  3. নিয়ম থেকে test লেখানো আর চালিয়ে লাল দেখা
  4. ছোট ধাপে কোড, প্রতিটির পরে type check, lint আর test
  5. Diff-এর প্রতিটি লাইন পড়া, package.json আর test ফাইলসহ
  6. Pull request, CI আর মানুষের review-এর পরে merge

একটি AI সহকারী npm i next-coupon-guard চালাতে বলল। npm view next-coupon-guard চালালে E404 Not Found এল। সবচেয়ে ঠিক সিদ্ধান্ত কোনটি?

  • কিছুক্ষণ পরে আবার install চেষ্টা করা, registry হয়তো ধীর
  • package.json-এ নামটি রেখে দেওয়া, পরে প্রকাশ হলে কাজে লাগবে
  • নামটিকে বানানো ধরে নিয়ে package ছাড়া বা পরিচিত package দিয়ে কাজটি করা
  • npm i next-coupon-guard --force চালানো

একটি কুপন function-এর জন্য AI এই test লিখেছে: expect(r.ok).toBe(true) আর expect(r.totalPaisa).toBeLessThan(r.subtotalPaisa). Test পাস করছে। এই test সম্পর্কে কোনটি সবচেয়ে সঠিক?

  • Test পাস করেছে, তাই function ঠিক আছে
  • ছাড়ের সীমা না মানা বা ভগ্নাংশ পয়সা দেওয়া ভুল কোডেও এটি পাস করবে
  • toBeLessThan Vitest-এ নেই, তাই test আসলে চলছে না
  • Coverage ১০০% হলে এই test যথেষ্ট

Next.js 16-এর একটি project-এ AI middleware.ts ফাইল লিখেছে। next build কী করবে?

  • Build ব্যর্থ হবে, middleware আর চলে না
  • ফাইলটি নীরবে উপেক্ষা করবে
  • ফাইলটির নাম নিজে থেকে proxy.ts করে দেবে
  • Build চলবে, কিন্তু সতর্ক করবে যে middleware নামটি deprecated, proxy ব্যবহার করুন

একটি Express route কার্টে কুপন বসায়। Login আছে, কিন্তু কার্টটি এই ব্যবহারকারীর কি না, যাচাই করে না। এই দুর্বলতা সবচেয়ে সরাসরি ধরবে কোন test?

  • ব্যবহারকারী B-এর cookie দিয়ে ব্যবহারকারী A-এর cartId পাঠিয়ে 404 বা 403 প্রত্যাশা করা
  • ব্যবহারকারী A নিজের কার্টে কুপন দিলে 200 প্রত্যাশা করা
  • Cookie ছাড়া অনুরোধে 401 প্রত্যাশা করা
  • tsc --noEmit চালানো

একটি AI সহকারীর সাথে কাজ করার সময় কোনটি prompt-এ দেওয়া নিরাপদ, যদি টুলটি ব্যবহারের অনুমতি থাকে কিন্তু secret বা ব্যক্তিগত তথ্য দেওয়ার নয়?

  • Error বোঝার জন্য পুরো .env ফাইল
  • ভুল ধরতে ১০ জন আসল ক্রেতার নাম আর ফোনসহ অর্ডারের তালিকা
  • Environment variable-এর নামগুলো, মানের জায়গায় example-secret
  • একটি bug বোঝাতে production server-এর পুরো log

Levenshtein দূরত্ব দিয়ে typosquatting খোঁজার একটি নিয়মে বিশ্বস্ত তালিকার কোনো নামের সাথে দূরত্ব ২ বা কম হলে সতর্ক করা হয়। expresss, raect আর next-coupon-guard (বিশ্বস্ত তালিকায় express, react, next আছে) কোনগুলোতে সতর্কতা আসবে?

  • তিনটিতেই
  • শুধু expresss আর raect
  • শুধু expresss
  • শুধু next-coupon-guard, কারণ তাতে next আছে

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. AI-এর উত্তর খসড়া, সিদ্ধান্ত নয়; সম্ভাব্য কোড আর সঠিক কোড আলাদা, আর merge হওয়া কোডের দায় আপনার।
  2. কাজ দিন version, বিদ্যমান কোড, শর্ত আর গ্রহণের test-সহ; আগে পরিকল্পনা, তারপর ছোট ধাপ, প্রতিটি ধাপ চালিয়ে।
  3. পরিচিত ভুল: পুরোনো API, বানানো package, secret ফাঁস, server-এ অনুমতি নেই, N+1, ফাঁপা test, locale; প্রতিটির যাচাই আলাদা।
  4. Install-এর আগে npm view: নেই হলে বানানো; এক অক্ষরের ভুলে অন্য কারও package.
  5. সবুজ test তখনই বিশ্বাসযোগ্য, যখন ইচ্ছা করে ঢোকানো ভুল সেটিকে লাল করে। শেখার সময় AI-কে শিক্ষক বানান, বদলি নয়।

পরের পর্বে: পর্ব ৮৭, একটি অ্যাপ বড় করা: বাজারঘর ১০০ থেকে ১০ লাখ ব্যবহারকারীতে গেলে কোন অংশ আগে ভাঙে, আর ধাপে ধাপে cache, replica আর queue কীভাবে যোগ হয়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান