जानिए कैसे routes और components से वास्तविक ऐप व्यवहार निकालकर Claude Code में कोड से फीचर स्पेक्स बनाते हैं, और फिर एक लिविंग स्पेक और गैप्स सूची तैयार करते हैं।

लोग इस बात पर अलग-अलग याद रखते हैं कि ऐप क्या करता है, क्योंकि हर किसी की याद अलग वर्ज़न पर टिकी रहती है। सपोर्ट को आखिरी गुस्से भरा टिकट याद रहता है। सेल्स को डेमो का रास्ता। इंजीनियरों को वह काम जो फीचर के लिए सोचा गया था। तीन लोगों से पूछो और तीनों आत्मविश्वास से जवाब देंगे — पर इनमें से कोई भी वर्तमान बिल्ड से मेल नहीं खाएगा।
समय के साथ, कोड ही एकमात्र स्रोत बन जाता है जो अद्यतित रहता है। डॉक्यूमेंट्स पीछे छोड़ देते हैं, टिकट बंद हो जाते हैं, और त्वरित फ़िक्स जमा हो जाते हैं। एक रूट में नई वैलिडेशन आ जाती है। UI टॉगल का डिफ़ॉल्ट बदल जाता है। हैंडलर अलग तरह की एरर लौटाने लगता है। कोई स्पेक अपडेट नहीं करता क्योंकि यह वैकल्पिक लगता है और हर बदलाव बहुत छोटा लगकर दस्तावेज़ करने योग्य नहीं दिखता।
इससे अनुमानित समस्याएँ पैदा होती हैं। टीमें ऐसे बदलाव भेजती हैं जो उन किनारों को तोड़ देते हैं जिनके बारे में उन्हें पता ही नहीं था। QA केवल हैप्पी पाथ टेस्ट करता है और हैंडलर्स में छिपी नियमों को मिस कर देता है। नए साथी UI से व्यवहार कॉपी कर लेते हैं बिना असली सीमाओं को समझे। स्टेकहोल्डर्स राय पर बहस करते हैं बजाय इस बात के कि सहमति वाले व्यवहार क्या हैं।
एक अच्छा परिणाम परफेक्ट डॉक्यूमेंट नहीं है। वह साझा स्पष्टता है। हर किसी को बिना अटकले के जवाब देना चाहिए: “अगर मैं X करूँ तो क्या होता है?” और “सिस्टम क्या गारंटी देता है?” आप कम सरप्राइज़, छोटे रिव्यू साइकिल और कम “रुको, ये तो पहले से करता है” वाली स्थिति पाएंगे क्योंकि टीम एक ही सच्चाई देख रही है।
जब स्पेक कोड से मेल खाता है, तो बदलाव योजनाबद्ध करना सुरक्षित हो जाता है। आप शिप करने से पहले देख सकते हैं कि क्या स्थिर है, क्या आकस्मिक है, और क्या गायब है।
लिविंग स्पेक आज ऐप असल में क्या करता है उसकी छोटी, संपादन योग्य व्याख्या है। यह एक बार का डॉक्यूमेंट नहीं है। यह हर बार व्यवहार बदलने पर अपडेट होता है ताकि टीम उस पर भरोसा कर सके।
जब लोग कोड से लिखे गए फीचर स्पेक्स की बात करते हैं (जैसे Claude Code का उपयोग करते हुए), लक्ष्य सरल है: routes, handlers और screens से वास्तविक व्यवहार पढ़ो, फिर उसे साधारण भाषा में लिख दो।
एक उपयोगी लिविंग स्पेक यह बताता है कि उपयोगकर्ता क्या देख सकता है और सिस्टम क्या वादा करता है। इसे शामिल करना चाहिए:
यह नहीं बताना चाहिए कि कोड कैसे व्यवस्थित है। यदि आप फ़ाइलों और रिफ़ैक्टर योजनाओं का नाम लेना शुरू कर दें, तो आप इम्प्लीमेंटेशन डिटेल में जा रहे हैं। बचें:
एक गैप्स लिस्ट अलग चीज़ है। यह एक छोटी सूची है जिसमें वे असंगतियां और अनिश्चितताएं दर्ज होती हैं जो स्पेक लिखते समय मिलीं।
उदाहरण: एक रूट 10MB से बड़े फाइलReject कर देता है, लेकिन UI कहता है 25MB। यह तब तक गैप है जब तक टीम तय नहीं कर लेती कि कौन सा नियम असली है और या तो कोड या स्पेक अपडेट कर दे।
छोटा शुरू करें। अगर आप पूरे ऐप को डॉक्यूमेंट करने की कोशिश करेंगे, तो अंत में भरोसेमंद नोट्स का ढेर रह जाता है। एक ऐसा हिस्सा चुनें जिसे उपयोगकर्ता एक वाक्य में बता सके, जैसे “टیم में आमंत्रण भेजना”, “चेकआउट”, या “पासवर्ड रीसेट”। अच्छे स्कोप एक फीचर एरिया, एक मॉड्यूल, या एंट्री पॉइंट से परिणाम तक का एक यूज़र जर्नी होते हैं।
सत्य कहां रहता है उसके आधार पर एंट्री पॉइंट चुनें:
कोड पढ़ने से पहले कुछ इनपुट इकट्ठा कर लें ताकि मिसमैच जल्दी दिखें: किसी भी मौजूदा API डॉक्स, पुराने प्रोडक्ट नोट्स, सपोर्ट टिकट, और “जानी-पहचानी परेशानियाँ” जो लोग बताते हैं। ये कोड को ओवरराइट नहीं करतीं, पर ये आपको उस स्टेट्स को नोटिस करने में मदद करती हैं जो गायब हो सकते हैं जैसे एरर, एज केस, और अनुमतियाँ।
स्पेक फ़ॉर्मेट को साधारण और सुसंगत रखें। टीमें तब जल्दी मिलती हैं जब हर स्पेक एक ही तरीके से पढ़ता है।
इस संरचना को बार-बार इस्तेमाल करें और आपकी फीचर स्पेक्स पठनीय, तुलना योग्य और अपडेट करने में आसान रहेंगी।
सर्वर एंट्री पॉइंट से शुरू करें। Routes और handlers बताते हैं कि "ऐप क्या करता है" ठोस रूप में: कौन कॉल कर सकता है, उन्हें क्या भेजना होगा, उन्हें क्या मिलता है, और सिस्टम में क्या बदलता है।
स्कोप में रूट्स की सूची बनाएं और हर एक को एक यूज़र इरादे से मैप करें। "POST /api/orders" न लिखें। "Place an order" या "Save a draft" लिखें। अगर आप plain शब्दों में इरादा नाम नहीं दे पा रहे तो वह पहले से ही एक स्पेक गैप है।
हर हैंडलर पढ़ते समय इनपुट और वैलिडेशन नियम यूज़र-फेसिंग आवश्यकताओं के रूप में कैप्चर करें। अनिवार्य फ़ील्ड, अनुमत फ़ॉर्मैट और वे नियम जो वास्तविक एरर पैदा करते हैं, शामिल करें। जैसे: “ईमेल मान्य होना चाहिए”, “Quantity कम से कम 1 होना चाहिए”, “Start date अतीत में नहीं हो सकता।”
Auth और role checks को भी इसी तरह लिखें। “middleware: requireAdmin” की जगह लिखें: “सिर्फ admins किसी भी ऑर्डर को cancel कर सकते हैं। सामान्य उपयोगकर्ता केवल 10 मिनट के भीतर अपने ऑर्डर को cancel कर सकते हैं।” अगर कोड ownership, feature flags, या tenant boundaries चेक करता है तो उन्हें भी शामिल करें।
फिर आउटपुट और आउटकम नोट करें। सफलता क्या लौटाती है (बनाया गया ID, अपडेट ऑब्जेक्ट)? सामान्य विफलताएँ कैसी दिखती हैं (401 not signed in, 403 not allowed, 404 not found, 409 conflict, 422 validation error)?
अंत में, साइड-इफेक्ट्स रिकॉर्ड करें क्योंकि वे व्यवहार का हिस्सा हैं: बनाए/अपडेट हुए रिकॉर्ड, भेजे गए ईमेल या नोटिफिकेशन्स, प्रकाशित इवेंट्स,Queued बैकग्राउंड जॉब्स, और जो कुछ भी अन्य फ्लो ट्रिगर करता है। ये डिटेल्स बाद में टीम के भरोसे को रोकने से बचाते हैं।
Routes बताती हैं कि ऐप क्या कर सकता है। Components बताते हैं कि उपयोगकर्ता असल में क्या अनुभव करते हैं। UI को कॉन्ट्रैक्ट का हिस्सा मानें: क्या दिखता है, क्या ब्लॉक होता है, और गलती होने पर क्या होता है।
सबसे पहले फीचर के एंट्री स्क्रीन ढूंढें। पेज कंपोनेंट, लेआउट रैपर, और कुछ “डिसीजन” कंपोनेंट ढूँढें जो fetching, permissions और navigation कंट्रोल करते हैं। यहीं अक्सर असली व्यवहार रहता है।
कम्पोनेंट पढ़ते समय वे नियम कैप्चर करें जो उपयोगकर्ता महसूस कर सकते हैं: कब actions disabled होते हैं, आवश्यक स्टेप्स, conditional fields, loading states, और त्रुटियाँ कैसे दिखाई देती हैं (इनपुट के नीचे इनलाइन एरर बनाम टोस्ट, ऑटो-रिट्राई, "try again" बटन)। साथ ही state और caching व्यवहार नोट करें जैसे stale data पहले दिखना, optimistic updates, या "last saved" टाइमस्टैम्प।
छिपे हुए फ्लो पर ध्यान दें जो चुपचाप उपयोगकर्ता अनुभव बदलते हैं। feature flags, experiment buckets, और admin-only gates खोजें। silent redirects भी नोट करें, जैसे लॉग-आउट उपयोगकर्ताओं को sign-in पर भेजना या बिना पहुंच वाले उपयोगकर्ताओं को upgrade स्क्रीन पर भेजना।
एक ठोस उदाहरण: "Change Email" स्क्रीन पर, दस्तावेज़ करें कि Save तब तक disabled रहता है जब तक ईमेल मान्य न हो, रिक्वेस्ट के दौरान एक spinner दिखता है, सफलता पर एक confirmation banner दिखता है, और बैकएंड वैलिडेशन एरर इनपुट के नीचे रेंडर होते हैं। अगर कोड में newEmailFlow जैसा फ्लैग दिखता है, तो दोनों वैरिएंट और उनके बीच का फर्क नोट करें।
हर UI फ्लो को छोटे कदमों में लिखें (यूज़र क्या करता है, UI उसके बदले में क्या करता है) और conditions तथा errors को उसी स्टेप के पास रखें जिन पर वे असर करते हैं। यह स्पेक को पठनीय रखता है और गैप्स को पकड़ना आसान बनाता है।
routes और components से निकले कच्चे नोट्स उपयोगी होते हैं, पर चर्चा के लिए कठिन। जो आपने देखा उसे ऐसे स्पेक में फिर से लिखें जिसे PM, designer, QA और engineer सभी पढ़ कर सहमत हो सकें।
एक व्यवहारिक पैटर्न है: हर रूट या स्क्रीन के लिए एक यूज़र स्टोरी। इसे छोटा और विशेष रखें। उदाहरण: “As a signed-in user, I can reset my password so I can regain access.” अगर कोड रोल के अनुसार अलग व्यवहार दिखाता है (admin बनाम user), तो इसे अलग स्टोरीज़ में बाँट दें बजाय कि इसे फुटनोट में छुपाने के।
फिर ऐसे acceptance criteria लिखें जो असली कोड पाथ्स को दर्शाते हों, न कि आदर्श प्रोडक्ट को। अगर हैंडलर token गायब होने पर 401 लौटाता है, तो यह एक criterion होना चाहिए। अगर UI submit को disable कर देता है जब तक फ़ील्ड वैध न हो, तो यह भी criterion होना चाहिए।
डेटा नियम साधारण भाषा में शामिल करें, ख़ासकर वे जो चौंकाते हैं: लिमिट्स, ऑर्डरिंग, यूनिकनेस, अनिवार्य फ़ील्ड। “Usernames must be unique (checked on save)” "unique index" कहने से ज़्यादा साफ़ है।
एज केस अक्सर अच्छा डॉक्यूमेंट और उपयोगी डॉक्यूमेंट के बीच फर्क होते हैं। empty states, null values, retries, timeouts, और जब API कॉल फेल हो तब दिखने वाली चीज़ों को उजागर करें।
जब आप अनजानियों पर पहुँचते हैं तो अनुमान न लगाएँ, उन्हें मार्क करें:
ये मार्कर्स छोटी टीम प्रश्नों में बदल जाते हैं बजाय कि मौन अनुमान के।
गैप्स लिस्ट एक दूसरा Jira नहीं है। यह कोड और इच्छित व्यवहार के बीच जहाँ जहाँ मेल नहीं है या कोई साफ़ निर्णय नहीं है, उसका छोटा, साक्ष्य आधारित रिकॉर्ड है। अच्छी तरह किया जाए तो यह सहमति का टूल बन जाता है, योजना की लड़ाई नहीं।
क्या गैप माना जाए इसमें सख्ती रखें:
जब आप गैप दर्ज करते हैं, तो इसे तीन हिस्सों में रखें ताकि यह भूतपूर्व रहे:
Evidence उस सूची को रायों से दूर रखता है। उदाहरण: “POST /checkout/apply-coupon accepts expired coupons, but CouponBanner.tsx UI में उन्हें ब्लॉक करता है. Impact: revenue और user confusion. Type: bug या missing decision (इरादा कन्फर्म करें).”
इसे छोटा रखें। पहली पास के लिए कड़ा कैप लगाएँ, जैसे पहले पास में 10 आइटम। अगर आप 40 इश्यूज़ पाते हैं, तो उन्हें पैटर्न में समूहित करें (validation inconsistencies, permission checks, empty states) और केवल प्रमुख उदाहरण रखें।
गैप्स लिस्ट में डेट्स और शेड्यूलिंग से बचें। अगर आपको मालिकाना चाहिए, तो हल्का रखें: नोट करें कि किसे निर्णय करना चाहिए (product) या कौन व्यवहार सत्यापित कर सकता है (engineering), और असली योजना को अपने बैकलॉग में ले जाएँ।
छोटा, हाई-ट्रैफ़िक स्कोप चुनें: promo codes और shipping options के साथ checkout। लक्ष्य पूरा प्रोडक्ट फिर से लिखना नहीं है, बस यह पकड़ना है कि ऐप आज क्या करता है।
बैकएंड रूट्स से शुरू करें। अक्सर नियम वहीं पहले दिखते हैं। आप ऐसे रूट्स पाएंगे: POST /checkout/apply-promo, GET /checkout/shipping-options, और POST /checkout/confirm।
उन हैंडलर्स से व्यवहार साधारण शब्दों में लिखें:
फिर UI कम्पोनेंट्स की जाँच करें। PromoCodeInput बता सकता है कि totals केवल सफल response के बाद रिफ्रेश होते हैं और एरर्स इनपुट के नीचे inline दिखते हैं। ShippingOptions कंपोनेंट पहली बार लोड पर सबसे सस्ता विकल्प auto-select कर सकता है और उपयोगकर्ता इसे बदलने पर पूरा price breakdown रिफ्रेश करवा सकता है।
अब आपके पास पठनीय स्पेक और एक छोटा गैप्स लिस्ट है। उदाहरण: promo route और UI के बीच एरर मैसेज अलग हैं ("Invalid code" vs "Not eligible"), और किसी के पास साफ़ tax rounding rule नहीं है (per line vs order total)।
योजना में, टीम पहले वास्तविकता पर सहमत होती है, फिर तय करती है कि क्या बदलना है। रायों पर बहस करने की जगह, आप डाक्यूमेंट किए गए व्यवहारों की समीक्षा करते हैं, एक असंगति चुनते हैं जिसे ठीक करना है, और बाकी को "वर्तमान व्यवहार" के रूप में छोड़ देते हैं जब तक कि उसे फिर से देखने की ज़रूरत न हो।
स्पेक तभी मदद करता है जब टीम सहमत हो कि यह वास्तविकता से मेल खाता है। एक इंजीनियर और एक प्रोडक्ट व्यक्ति के साथ एक छोटी रीड-थ्रू करें। इसे सीमित रखें: 20–30 मिनट सिर्फ यह देखने के लिए कि उपयोगकर्ता क्या कर सकता है और सिस्टम कैसे प्रतिक्रिया देता है।
रीड-थ्रू के दौरान, बयानों को हाँ/नहीं सवालों में बदल दें। “जब कोई इस रूट को हिट करता है, क्या हम session के बिना हमेशा 403 लौटाते हैं?” “क्या यह empty state इरादतन है?” यह इरादतन व्यवहार और समय के साथ आ गया व्यवहार अलग करता है।
सहमति से पहले शब्दावली पर सहमति बनाएं। UI में दिखाई देने वाले शब्दों (बटन लेबल, पेज टाइटल, एरर मैसेज) का प्रयोग करें। internal नाम केवल तभी जोड़ें जब वे इंजीनियरों को कोड खोजने में मदद करें (route names, component names)। इससे उत्पाद "Workspace" कहे और स्पेक "Org" कहे ऐसी असंगतियाँ नहीं होंगी।
इसे अद्यतित रखने के लिए मालिकाना और कैडेंस स्पष्ट करें:
अगर आप Koder.ai जैसा टूल use कर रहे हैं, snapshots और rollback आपको बड़े refactor के बाद “पहले” और “बाद” व्यवहार की तुलना करने में मदद कर सकते हैं।
स्पेक पर भरोसा खोने का सबसे तेज़ तरीका है वह उत्पाद लिखना जिसे आप चाहते हैं, न कि जो आपके पास है। एक कड़ा नियम रखें: हर कथन का समर्थन कुछ कोड या असली स्क्रीन में दिखाने योग्य होना चाहिए।
दूसरा आम जाल है कोड की संरचना को डॉक्यूमेंट में कॉपी कर देना। एक स्पेक जो पढ़ता है "Controller -> Service -> Repository" स्पेक नहीं है, यह फ़ोल्डर मैप है। उपयोगकर्ता-नज़रिए से लिखें: क्या कार्रवाई ट्रिगर करती है, उपयोगकर्ता क्या देखता है, क्या सेव होता है, और एरर कैसे दिखते हैं।
अनुमतियाँ और रोल अक्सर अंत में नज़रअंदाज़ की जाती हैं और फिर सब कुछ टूट जाता है। एक्सेस नियम पहले ही जोड़ दें, भले ही वे गंदे हों। यह बताएं कि कौन देख सकता है, बना सकता है, संपादित कर सकता है, हटा सकता है, एक्सपोर्ट या approve कर सकता है, और जहाँ नियम लागू होते हैं (UI केवल, API केवल, या दोनों)।
नॉन-हैप्पी पाथ्स को स्किप न करें। असली व्यवहार retries, partial failures, और time-based नियमों में छुपा रहता है जैसे expirations, cooldowns, scheduled jobs, या "दिन में केवल एक बार" जैसी सीमाएँ। इन्हें पहली श्रेणी का व्यवहार मानें।
गैप्स सतह पर लाने का एक तेज़ तरीका है इनकी जाँच करें:
अंत में, अपनी गैप्स सूची को आगे बढ़ाते रखें। प्रत्येक गैप को एक लेबल दें: "unknown, needs decision," "bug, fix," या "missing feature, plan." यदि कुछ लेबल नहीं होता तो सूची जाम हो जाती है और स्पेक फिर से "लिविंग" नहीं रहता।
स्पष्टीकरण, कवरेज और कार्रवाईयोग्यता के लिए एक तेज़ पास करें। जिसने इसे नहीं लिखा उसे भी यह समझ में आना चाहिए कि फीचर आज क्या करता है और क्या अस्पष्ट है।
नए साथी की तरह स्पेक पढ़ें। अगर वे एक मिनट में फीचर का सार बता देते हैं तो आप करीब हैं। अगर वे बार-बार पूछते हैं "यह कहाँ से शुरू होता है?" या "हैप्पी पाथ क्या है?" तो उद्घाटन भाग को कसें।
जाँचें:
हर गैप विशिष्ट और टेस्ट करने योग्य होना चाहिए। "Error handling unclear" के बजाय लिखें: "यदि payment provider 402 लौटाए तो UI generic toast दिखाता है; इच्छित संदेश और रिट्राई व्यवहार की पुष्टि करें।" एक अगला कदम जोड़ें (product से पूछें, टेस्ट जोड़ें, logs जांचें) और निर्धारित करें कि कौन जवाब देगा।
एक फीचर एरिया चुनें और इसे 60 मिनट में टाइमबॉक्स करें। कुछ छोटा पर असली चुनें (login, checkout, search, एक admin स्क्रीन)। एक वाक्य में स्कोप लिखें: क्या शामिल है और क्या बाहर है।
वर्कफ़्लो को एक बार end-to-end चलाएं: प्रमुख routes/handlers को skim करें, मुख्य UI फ्लो ट्रेस करें, और ऑब्ज़र्वेबल व्यवहार लिखें (inputs, outputs, validation, error states)। अगर अटक जाएँ तो प्रश्न को गैप के रूप में लॉग करें और आगे बढ़ें।
समाप्त होने पर, उस स्पेक को टीम के साथ साझा करें जहाँ वे टिप्पणी कर सकें, और एक नियम रखें: कोई भी शिप्ड व्यवहार परिवर्तन उसी डिलीवरी विंडो में स्पेक अपडेट करे, भले ही वह पाँच लाइन ही क्यों न हो।
गैप्स को बैकलॉग से अलग रखें। उन्हें "unknown behavior," "inconsistent behavior," और "missing tests" में ग्रुप करें, फिर हर सप्ताह संक्षेप में समीक्षा करके तय करें कि अब क्या महत्वपूर्ण है।
यदि ड्राफ्टिंग और iteration धीमी लगे, तो Koder.ai जैसा चैट-आधारित बिल्डर आपकी पहली वर्ज़न को तेज़ी से तैयार करने में मदद कर सकता है। फीचर बताएं, प्रमुख स्निपेट या रूट नाम पेस्ट करें, बातचीत में शब्दों को परिष्कृत करें, और ज़रूरत पर स्रोत एक्सपोर्ट करें। मकसद है गति और साझा स्पष्टता, बड़ा प्रोसेस नहीं।
Start with one small, user-visible slice (for example, “reset password” or “invite a teammate”). Read the routes/handlers to capture rules and outcomes, then read the UI flow to capture what users actually see (disabled states, errors, redirects). Write it up using a consistent template and log unknowns as a separate gaps list.
Default: treat current code behavior as the source of truth and document it.
If the behavior looks accidental or inconsistent, don’t “fix it” in the spec—mark it as a gap with evidence (where you saw it and what it does), then get a decision to update either the code or the spec.
Keep it boring and repeatable. A practical template is:
This keeps specs readable and makes mismatches easier to spot.
Write rules as user-facing requirements, not as code notes.
Examples:
Capture what triggers an error and what the user experiences when it happens.
Focus on what’s observable:
Side effects matter because they affect other features and support/ops expectations.
If the UI blocks something the API allows (or vice versa), log it as a gap until a decision is made.
Record:
Then agree on one rule and update both code and spec to match.
Keep the gaps list small and evidence-based. Each item should have:
Avoid scheduling or turning it into a second backlog.
Document them explicitly instead of hiding them.
Include:
These are usually where surprises and bugs come from.
Keep it short: a 20–30 minute read-through with one engineer and one product person.
Turn statements into yes/no checks (for example, “Do we always return 403 when not allowed?”). Align on vocabulary using the UI’s words (labels and messages) so everyone means the same thing.
Put the spec close to the code and make updates part of shipping.
Practical defaults:
The goal is small, frequent edits—not a big rewrite.