Lär dig hur du skapar funktionsspecar från kod med Claude Code genom att extrahera verkligt appbeteende från routes och komponenter, och sedan producera en levande spec och en lista med gap.

Folk är oense om vad en app gör för att de minns olika versioner av den. Support minns det senaste arga ärendet. Sälj minns demo-flödet. Ingenjörer minns vad funktionen var tänkt att göra. Fråga tre personer och du får tre säkra svar — och ingen av dem matchar nuvarande build.
Med tiden blir koden den enda källan som förblir aktuell. Dokumentation driver ifrån, ärenden stängs och snabba fixar hopar sig. En route får en ny valideringsregel. En UI-toggle ändrar ett standardvärde. En handler börjar returnera andra fel. Ingen uppdaterar specen för det känns frivilligt, och varje ändring känns för liten för att dokumentera.
Det skapar förutsägbara problem. Team levererar förändringar som bryter kantfall de inte kände till. QA testar happy path och missar regler dolda i handlers. Nya kollegor härmar beteende från UI utan att förstå verkliga begränsningar. Intressenter debatterar åsikter istället för att peka på överenskommet beteende.
Ett bra resultat är inte ett perfekt dokument. Det är delad tydlighet. Alla bör kunna svara: "Vad händer om jag gör X?" och "Vad garanterar systemet?" utan att gissa. Du får färre överraskningar, kortare granskningscykler och färre "Vänta, det gör det redan"-ögonblick eftersom teamet tittar på samma sanning.
När en spec matchar koden blir det säkert att planera förändringar. Du kan se vad som är stabilt, vad som är tillfälligt och vad som saknas innan du levererar.
En levande spec är en kort, redigerbar beskrivning av vad appen faktiskt gör idag. Det är inte ett engångsdokument. Den ändras när beteendet ändras, så teamet kan lita på den.
När folk pratar om funktionsspecar skrivna från kod (till exempel med Claude Code) är målet enkelt: läs verkligt beteende från routes, handlers och skärmar, och skriv det i klartext.
En användbar levande spec fokuserar på vad användaren ser och vad systemet lovar. Den bör täcka:
Vad den inte ska täcka är hur koden är organiserad. Om du börjar namnge filer och refaktor-planer går du in i implementationsdetaljer. Undvik:
En gaps-lista är separat. Det är en kort lista över avvikelser och oklarheter du hittar när du skriver specen.
Exempel: en route avvisar filer över 10MB, men UI:t säger 25MB. Det är ett gap tills teamet bestämmer vilken regel som är den riktiga och uppdaterar antingen koden eller specen.
Börja smått. Om du försöker dokumentera hela appen slutar du med en hög anteckningar ingen litar på. Välj en skiva användare kan beskriva i en mening, som "bjuda in en kollega", "köp" eller "återställ lösenord". Bra scope är ett enda funktionsområde, en modul eller en användarresa från ingång till utfall.
Välj din ingångspunkt baserat på var sanningen bor:
Innan du läser kod, samla några inputs så mismatch blir uppenbara snabbt: existerande API-dokumentation, gamla produktanteckningar, supportärenden och kända smärtpunkter folk klagar över. Dessa överskrider inte koden men hjälper dig att upptäcka saknade tillstånd som fel, kantfall och behörigheter.
Håll spec-formatet tråkigt och konsekvent. Team samarbetar snabbare när varje spec läses på samma sätt.
Använd denna struktur upprepade gånger så förblir era funktionsspecar läsbara, jämförbara och enkla att uppdatera.
Börja med serverns ingångspunkter. Routes och handlers visar "vad appen gör" i konkreta termer: vem kan anropa det, vad måste de skicka, vad får de tillbaka och vad ändras i systemet.
Lista routes i scope och mappa varje en till ett användarintention. Skriv inte "POST /api/orders." Skriv "Lägg en order" eller "Spara utkast." Om du inte kan namnge intentionen i vanligt språk är det redan ett spec-gap.
När du läser varje handler, fånga inputs och valideringsregler som användar-facing krav. Inkludera obligatoriska fält, tillåtna format och regler som ger verkliga fel. Till exempel: "E-post måste vara giltig", "Antal måste vara minst 1", "Startdatum får inte vara i det förflutna."
Skriv auth- och rollkontroller på samma sätt. I stället för "middleware: requireAdmin," dokumentera: "Endast admins kan avboka vilken order som helst. Vanliga användare kan bara avboka sin egen order inom 10 minuter." Om koden kontrollerar ägarskap, feature flags eller tenant-gränser, ta med det också.
Notera sedan outputs och utfall. Vad returnerar framgång (ett skapat ID, ett uppdaterat objekt)? Hur ser vanliga fel ut (401 ej inloggad, 403 ej tillåtet, 404 ej hittad, 409 konflikt, 422 valideringsfel)?
Slutligen, dokumentera bieffekter eftersom de är del av beteendet: poster som skapas eller uppdateras, mail eller notiser som skickas, events som publiceras, bakgrundsjobb som köas och allt som triggar andra flöden. Dessa detaljer förhindrar överraskningar när team senare förlitar sig på specen.
Routes berättar vad appen kan göra. Komponenter berättar vad användarna faktiskt upplever. Behandla UI:t som en del av kontraktet: vad visas, vad blockeras och vad händer när något går fel.
Börja med att hitta ingångsskärmar för funktionen. Leta efter sidkomponenten, layout-wrappern och några "decision"-komponenter som styr hämtning, behörigheter och navigation. Där lever ofta det verkliga beteendet.
När du läser komponenter, fånga regler användaren känner: när åtgärder är inaktiverade, obligatoriska steg, villkorliga fält, laddningstillstånd och hur fel visas (fältfel inline vs toast, automatisk retry, "försök igen"-knappar). Notera även state- och cache-beteende som föråldrade data visas först, optimistiska uppdateringar eller "senast sparat"-tidsstämplar.
Var uppmärksam på dolda flöden som tyst ändrar vad användaren ser. Sök efter feature flags, experiment-buckets och admin-only-grindar. Notera även tysta omdirigeringar, som att skicka utloggade användare till inloggning eller skicka användare utan åtkomst till en uppgraderingsskärm.
Ett konkret exempel: på en "Change Email"-skärm dokumentera att Spara är inaktiverad tills e-posten är giltig, en spinner visas under förfrågan, framgång triggar en bekräftelsebanner och backend-valideringsfel renderas under inputfältet. Om koden visar en flagga som newEmailFlow, notera båda varianterna och vad som skiljer dem åt.
Skriv varje UI-flöde som korta steg (vad användaren gör, vad UI:t gör tillbaka) och håll villkor och fel intill steget de påverkar. Det gör specen läsbar och gör gaps lättare att upptäcka.
Råanteckningar från routes och komponenter är användbara men svåra att diskutera. Skriv om vad du observerade till en spec som en PM, designer, QA och ingenjör kan läsa och enas om.
Ett praktiskt mönster är en user story per route eller skärm. Håll det litet och specifikt. Till exempel: "Som en inloggad användare kan jag återställa mitt lösenord så jag kan återfå åtkomst." Om koden visar olika beteende beroende på roll (admin vs användare), dela upp det i separata stories i stället för att gömma det i fotnoter.
Skriv sedan acceptanskriterier som speglar verkliga kodvägar, inte det ideala produkten. Om handlern returnerar 401 när token saknas, är det ett kriterium. Om UI inaktiverar skicka tills ett fält är giltigt, är det ett kriterium.
Inkludera dataregler i klartext, särskilt de som överraskar: begränsningar, sortering, unika fält, obligatoriska fält. "Användarnamn måste vara unika (kontrolleras vid spar)" är tydligare än "unik index."
Kantfall är ofta skillnaden mellan ett trevligt dokument och ett användbart. Nämn tomma tillstånd, null-värden, retries, timeouts och vad användaren ser när ett API-anrop misslyckas.
När du stöter på oklarheter, markera dem i stället för att gissa:
Dessa markörer blir snabba teamfrågor i stället för tysta antaganden.
En gaps-lista är inte en andra Jira. Det är en kort, evidensbaserad lista över var kod och avsiktligt beteende inte matchar, eller där ingen tydligt kan förklara vad "korrekt" är. Rätt gjort blir den ett verktyg för enighet, inte en planeringsstrid.
Var strikt med vad som räknas som ett gap:
När du loggar ett gap, inkludera tre delar så det förblir jordat:
Bevis är vad som håller listan borta från åsikter. Exempel: "POST /checkout/apply-coupon accepterar utgångna kuponger, men CouponBanner.tsx blockerar dem i UI:t. Påverkan: intäkter och användarförvirring. Typ: bug eller saknat beslut (bekräfta avsedd regel)."
Håll den kort. Sätt en hård gräns, till exempel 10 poster för första genomgången. Om du hittar 40 problem, gruppera dem i mönster (valideringsinkonsekvenser, behörighetskontroller, tomma tillstånd) och behåll bara de viktigaste exemplen.
Undvik datum och planering i gaps-listan. Om du behöver ägarskap, håll det lättviktigt: notera vem som bör fatta beslut (produkt) eller vem som kan verifiera beteendet (engineering), och flytta riktig planering till backloggen.
Välj ett litet, högtrafikerat område: checkout med rabattkoder och fraktalternativ. Målet är inte att skriva om hela produkten, utan att fånga vad appen gör idag.
Börja med backend-routes. Där visar reglerna sig ofta först. Du kan hitta routes som POST /checkout/apply-promo, GET /checkout/shipping-options, och POST /checkout/confirm.
Från de handlersna, skriv beteende i vanligt språk:
Sen kollar du UI-komponenter. En PromoCodeInput kan visa att totals bara uppdateras efter ett lyckat svar och fel renderas inline under input. En ShippingOptions-komponent kan autovälja billigaste alternativet vid första laddning och trigga en full prisuppdatering när användaren ändrar det.
Nu har du en läsbar spec och en liten gaps-lista. Exempel: felmeddelanden skiljer sig mellan promo-route och UI ("Invalid code" vs "Not eligible"), och ingen kan peka på en tydlig regel för avrundning av skatt (per rad eller totalt för ordern).
Vid planering enas teamet om verkligheten först och beslutar sedan vad som ska ändras. I stället för att bråka om åsikter, granskar ni dokumenterat beteende, väljer en inkonsekvens att åtgärda och lämnar resten som "känt nuvarande beteende" tills det är värt att ta upp igen.
En spec hjälper bara om teamet håller med om att den speglar verkligheten. Gör en kort genomgång med en ingenjör och en produktperson. Håll det kärnfullt: 20–30 minuter fokuserat på vad användaren kan göra och vad systemet svarar.
Under genomgången, gör uttalanden till ja/nej-frågor. "När en användare träffar denna route, returnerar vi alltid 403 utan session?" "Är detta tomtillstånd avsiktligt?" Det skiljer avsiktligt beteende från slumpmässigt inträffade förändringar.
Enas om vokabulär innan du redigerar något. Använd de ord som användaren ser i UI:t (knapptexter, sidtitlar, felmeddelanden). Lägg bara till interna namn när de hjälper ingenjörer att hitta koden (routenamn, komponentnamn). Det förhindrar mismatch som att produkt säger "Workspace" medan specen säger "Org."
För att hålla det aktuellt, gör ägarskap och rytm explicit:
Om du använder ett verktyg som Koder.ai kan snapshots och rollback hjälpa dig jämföra "före" och "efter" när du uppdaterar en spec, särskilt efter en större refaktor.
Det snabbaste sättet att förlora förtroende för en spec är att beskriva produkten du vill ha, inte produkten du har. Håll en hård regel: varje påstående måste stödjas av något du kan peka på i kod eller en riktig skärm.
En annan fälla är att kopiera kodens form i dokumentet. En spec som läser "Controller -> Service -> Repository" är inte en spec, det är en mappkarta. Skriv i användar-vänliga termer: vad triggar åtgärden, vad ser användaren, vad sparas och hur ser fel ut.
Behörigheter och roller ignoreras ofta tills slutet, och då faller allt ihop. Lägg till accessregler tidigt, även om de är röriga. Tala om vilka roller som kan se, skapa, redigera, ta bort, exportera eller godkänna och var regeln kontrolleras (endast UI, endast API eller båda).
Hoppa inte över icke-happy paths. Verkligt beteende gömmer sig i retries, partiella fel och tidsbaserade regler som utgångstider, cooldowns, schemalagda jobb eller "endast en gång per dag"-begränsningar. Behandla dessa som förstklassiga beteenden.
Ett snabbt sätt att hitta gaps är att kontrollera för:
Slutligen, håll din gaps-lista i rörelse. Varje gap ska märkas som en av: "unknown, needs decision," "bug, fix," eller "missing feature, plan." Om inget får en etikett stagnerar listan och specen slutar vara "levande."
Gör en snabb genomgång för tydlighet, täckning och handlingsbarhet. Någon som inte skrev den ska förstå vad funktionen gör idag och vad som fortfarande är oklart.
Läs specen som en ny kollega på dag ett. Om hen kan sammanfatta funktionen på en minut är du nära. Om hen fortsätter fråga "var börjar detta?" eller "vad är happy path?" — skärp inledningen.
Kontrollera:
Varje gap ska vara specifikt och testbart. I stället för "Felhantering oklart", skriv: "Om betalningsleverantören returnerar 402, visar UI:t en generisk toast; bekräfta önskat meddelande och retry-beteende." Lägg till en nästa åtgärd (fråga produkt, lägg till test, kolla loggar) och notera vem som bör svara.
Starta med en liten, användar-synlig del (till exempel “återställ lösenord” eller “bjud in en kollega”). Läs igenom routes/handlers för att fånga regler och utfall, och läs sedan UI-flödet för att beskriva vad användaren faktiskt ser (inaktiverade tillstånd, fel, omdirigeringar). Skriv upp det i en konsekvent mall och logga oklarheter separat i en gaps-lista.
Standard: behandla nuvarande kodbeteende som sanningskällan och dokumentera det.
Om beteendet verkar oavsiktligt eller inkonsekvent, "fixa" det inte i specen — markera det som ett gap med bevis (var du såg det och vad som händer), och få ett beslut om att uppdatera antingen koden eller specen.
Håll det tråkigt och upprepningsbart. En praktisk mall är:
Detta gör specs läsbara och gör avvikelser enklare att upptäcka.
Skriv regler som användarvänliga krav, inte kodnoter.
Exempel:
Få med vad som triggar ett fel och vad användaren ser när det händer.
Fokusera på vad som är observerbart:
Bieffekter är viktiga eftersom de påverkar andra funktioner och support/ops-förväntningar.
Om UI blockerar något som API:t tillåter (eller tvärtom), logga det som ett gap tills ett beslut fattas.
Dokumentera:
Kom överens om en regel och uppdatera både kod och spec så allt överensstämmer.
Håll gaps-listan kort och evidensbaserad. Varje punkt bör ha:
Undvik att schemalägga eller göra det till en andra backlog.
Dokumentera dem uttryckligen i stället för att dölja dem.
Inkludera:
Dessa är ofta var överraskningar och buggar dyker upp.
Håll det kort: en 20–30 minuters genomgång med en ingenjör och en produktperson.
Gör uttalanden till ja/nej-frågor (t.ex. “Returnerar vi alltid 403 när användaren inte har session?”). Enas om vokabulär baserat på UI:t (knappar, titlar, felmeddelanden) så alla menar samma sak.
Placera specen nära koden och gör uppdateringar till en del av leveransen.
Praktiska standarder:
Målet är små, frekventa ändringar—inte stora omskrivningar.