Mikroramar i adminkonsolen

Leo Zhang headshotLeo Zhang
23 september 2026
7 min. läsning
facebookx-twitterlinkedin
Asana Engineering Spotlight

Varje Asana-implementering har en adminkonsol. Det är där IT-administratörer konfigurerar hur deras företag använder Asana, till exempel genom att justera lösenordskrav, roller och behörigheter, om filer kan bifogas från Dropbox och vem som kan se ett nytt projekt som standard.

adminkonsol

I takt med att Asana växte samlade adminkonsolen på sig åratal av anpassad logik och engångslösningar, vilket gjorde det allt dyrare att skapa och underhålla administrativa kontroller. Ta en administrativ inställning som exempel: standardsekretessen för nya projekt. En administratör väljer om ett nytt projekt ska vara synligt för hela organisationen, synligt för sitt team eller privat för inbjudna medlemmar. Det är enkelt att beskriva, men det finns mycket komplexitet som döljer sig bakom:

  1. Ingår den här funktionen i kundens abonnemang?

  2. Betalade de för den tidigare, slutade och fastnade på en inställning som de inte längre kan ändra?

  3. Är de en HIPAA- eller FedRAMP-kund, där endast roller med högre behörighet kan redigera den?

  4. Görs ett alternativ otillgängligt på grund av någon annan inställning?

  5. Ska en informationsbanner visas för att beskriva de nuvarande begränsningarna?

Alla team som ville lägga till en adminkontroll var tvungna att göra allt rätt. De flesta kom fram till att det inte var värt besväret, och med tiden blev klyftan mellan vad Asana kunde göra och vad en administratör kunde styra över allt större. Detta illustreras av att vissa kontroller endast kan konfigureras på företagsnivå, vilket gör det svårt för IT-administratörer att tillämpa kontrollen på endast en delmängd av sina användare.

Här är ett kodavsnitt för dialogrutan för projektets sekretessinställningar, som används för att avgöra om den ska inaktiveras och om en banner ska visas:

sekretessinställning för projekt

Det finns mycket logik att analysera där – funktionslicensiering, styrning, åsidosättningar på grund av implementeringsstruktur och användarroller, särskilt för granskare. För att vara noggrann måste man bygga upp testmatrisen i huvudet för att avgöra om den är korrekt.

Och det är bara dialogrutan. Huruvida raden överhuvudtaget visas på inställningssidan avgjordes någon annanstans, och dessutom på ett inkonsekvent sätt:

 funktionslicensiering, styrning, åsidosättningar på grund av implementeringsstruktur

Tre rader, tre mekanismer och styrningen finns inte alltid i samma fil. Så för att svara på frågan "vilka inställningar ser den här kunden egentligen?" var du inte bara tvungen att läsa varje rad, utan även att granska varje komponent. Den frågan dyker upp ganska ofta: kundsupport som försöker förklara varför en inställning försvann för en kund, en produktchef som vill ha ett rakt svar på om en ny kontroll är en snabb ändring eller en ändring som tar två veckor, en nyanställd som försöker hitta det enda stället som avgör vad en specifik användare kan se.

Om vi zoomar ut fanns det fyra saker som gjorde arbetet i adminkonsolen kostsamt:

  1. Kostsamt för granskning. Logiken fanns där författaren placerade den, så en PR kunde introducera ett särskilt beteende utan att det var uppenbart för en granskare, och det var inte lätt att verifiera korrektheten bara genom att läsa.

  2. Brist på standardisering döljde buggar. Vi hade långvariga buggar som var svåra att upptäcka. Många berodde på avvikelser mellan produktspecifikationen och genomförandet, orsakade av en stor mängd skräddarsydda implementeringar. Teamen fattade godtyckliga beslut, vilket ledde till att varje kontroll hade sina egna egenheter.

  3. Dyrt att ändra. För att göra en enda ändring för slutanvändaren var man tvungen att hitta varje ställe där en regel var kodad, och det fanns sällan en enda definitionsplats.

  4. Dyrt att testa. För att konfigurera testning krävdes djup kunskap om backend-tillstånden, och omfattande manuell testning av slutliga implementeringar var inte genomförbar på grund av antalet interagerande dimensioner.

Vi presenterar ramverken

Vi skapade ett deklarativt ramverk för administrativa kontroller som skulle fungera som en referenskälla i kodbasen. En kontroll anger nu vad den är:

 deklarativt ramverk för administrativa kontroller

Varje fält här motsvarar en gren från dialogrutan ovan: requiredAdminRole är HIPAA-/superadministratörskontrollen, upsellBehavior är de två merförsäljningsgrenarna och churnBehavior är fallet med avhoppade kunder, vilket låter dem återställa standardinställningen och inget annat.

Som en del av detta exponerar ramverket hooks som teknikerna använder för att härleda kontrollens beräknade tillstånd. Ta en titt på hur samma dialogruta för projektsekretess ser ut nu:

dialogruta för projektsekretess

Bannerns if-kedja kollapsade till en gemensam komponent som drivs av en centraliserad hook. Ramverket hanterar den kombinatoriska logiken för alla olika scenarier, och de ämnesexperter som ansvarar för att underhålla det, och som har en djup förståelse för administrationsprodukten, kan tryggt göra genomgripande ändringar. Nu använder vi strikt typning för att vägleda implementerare att fylla i den obligatoriska information som krävs för att korrekt återge deras inställning i alla möjliga scenarier. Det viktiga är att de inte behöver förstå de invecklade aspekterna av dessa scenarier eller hur de samverkar.

Dessa inställningar är tillgängliga via rader i adminkonsolens användargränssnitt. Synligheten för dessa rader fick samma behandling, och det är här det andra ramverket kommer in i bilden. En rad i inställningsregistret beskriver inte sina egna synlighetsregler, utan kopplar den istället till de kontroller som representerar den:

PROJEKT_STANDARD_SEKRETESS_RAD

Kontrollmatrisen är mervärdet. Den innehåller samma ProjectDefaultPrivacy-objekt som dialogrutan skickar till useAdminConsoleControl, och registret kör det genom samma sanningskälla, så att sidan och dialogrutan inte kan vara oeniga. Förut beräknades det separat, så avvikelser kunde leda till två fellägen: en rad som är synlig men öppnar en dialogruta som du inte kan använda, och en inställning som en kund betalar för utan någon rad att nå den från. Genom att centralisera det eliminerades den här kategorin av buggar.

Tester som antog de centraliserade ramverken förbättrade PR-granskarnas upplevelse avsevärt. Ta till exempel testning av radsynlighet, som besvarar frågan ”vilka inställningar ser den här kunden faktiskt?” frågan från tidigare. I stället för testkod är ett scenario bara data: en persona, ett domäntillstånd och de sidor det visas på.

centraliserade ramverk förbättrade pull-begäranden

Och en rad listar bara vilka namngivna scenarier den måste visas i:

namngivna scenarier

Det finns inget render-anrop eller något påstående att skriva. En dynamisk testsvit läser katalogen och kontrollerar varje rad mot varje scenario som den anges i. Katalogen är nu det enda stället som anger vad en kund ser, kontrollerat av en maskin. Man behöver inte längre förlita sig på att en noggrann kodgranskare eller författaren korrekt identifierar och skriver sina egna testfall.

I AI-världen

Vi påbörjade det här arbetet i slutet av 2025 eftersom vi förutsåg behovet av att göra det möjligt för ingenjörer som inte är specialister att bygga med tillförsikt i adminkonsolen. Vid den tidpunkten var målet inte att optimera för LLM-prestanda, men det har visat sig att standardisering och effektivisering av upplevelsen för ingenjörer gör samma sak för AI-agenter.

Innan vi byggde dessa ramverk testade vi att använda AI för att lösa detta migreringsproblem, vilket tekniskt sett fungerade. Problemet var att varken agenten eller granskaren kunde avgöra om testerna faktiskt var korrekta, vilket innebar falsk tillförsikt och dolda brister. AI löser inte bristen på struktur, utan producerar bara mer kod, snabbare, ovanpå den struktur som redan finns där. Google gjorde ett liknande resonemang för Gos typsystem i AI-assisterad utveckling: statiska typer fungerar som ett automatiserat skyddsnät, eftersom LLM:er tenderar att hallucinera egenskaper och matcha typer felaktigt mellan filer. TypeScript är inte statiskt strikt på samma sätt som Go, men ett ramverk kan bygga samma garanti ovanpå det: definiera kontrollens typ en gång på ramverksnivå, och varje implementering måste passa den vid användningsplatsen.

När ramverken var klara började vi förbereda oss för att delegera och parallellisera. Jag använde vårt nya specifikationsdrivna utvecklingsverktyg [link placeholder: eng blog post on spec driven development: Asana Eng Blog – Spec-driven development: The Good Parts] för att bygga en färdighet som utför arbetet från början till slut. Den kodar hela konverteringen: definiera kontrollen, anropa hooken, ersätt bannrarna, uppdatera fragmenten, lägg till de nya deklarativa testerna, plus en självuppdaterande checklista och logg över gränsfall från tidigare konverteringar. Av alla cirka 150 migreringar behövde 91 % ingen revidering efter granskning.

Att starta en agent för att skriva en PR kräver inte mycket insats, och att granska den PR:en kräver inte heller mycket insats. Eftersom allt deklareras på ett förutsägbart sätt behöver granskarna inte vara experter på administration för att kontrollera om implementeringen överensstämmer med produktspecifikationen. Det viktigaste är att detta öppnar upp gruppen av kvalificerade granskare för en mycket bredare grupp av tekniker, vilket ökar takten mer än bara en bredare tratt högst upp som skapar PR:er. Vi är inte ensamma om att tänka om när det gäller granskning i vår tid: GitHub byggde om Copilots egen granskningsagent utifrån strukturerade PR-bevis för att hjälpa mänskliga granskare att snabbare komma fram till rätt frågor, vilket minskade deras granskningskostnader med cirka 20 %.

Den ursprungliga migreringen av cirka 150 punkter som omfattade flera ramverk planerades som ett manuellt, engångsarbete för utvecklare från början till slut. Genom att först bygga ramverken och sedan delegera migreringen till tekniker som övervakar agenter i efterhand kunde vi leverera hela insatsen mer än en månad tidigare än vad den ursprungliga planen krävde.

Vad händer nu?

Att bygga dessa ramverk var aldrig ett projekt i sig. Det uppstod ur nödvändighet, från en plan som behövde parallelliseras och skalas, med begränsad och föränderlig bemanning längs vägen, och utan att kräva att alla medverkande först skulle vara experter på området. Vi har redan sett att det fungerar utanför teamet som byggde det: 18 av de 66 kontrollerna i ramverket i dag skapades av tekniker från åtta olika team.

Nu letar vi efter nästa ställe där vi kan göra den här typen av investering. Om något är argumenten ännu starkare nu än de var innan vi började: ett välutformat, deklarativt ramverk gör inte bara granskningen enklare, det avgör om en agent producerar något tillförlitligt eller bara något snabbt. Det är också vad som kan göra autonom granskning plausibel: Cloudflare har byggt ett system där en AI-granskare godkänner ren kod och blockerar verkliga problem på egen hand, och det fungerar bara eftersom deras indata är tillräckligt strukturerade för att granskaren ska kunna lita på dem. Nästa bra fråga är om våra är tillräckligt strukturerade för att prova samma sak.


Om skribenten

Leo Zhang är programvaruingenjör i teamet för administrativa grunder, som ger IT-administratörer möjlighet att styra sina organisationer. För närvarande förbättrar han utvecklingsupplevelsen för andra produkttekniker i adminkonsolen genom att investera i de tekniska ramverk som ligger till grund för vår produkt.

Ett stort tack till teamet

Att utforma, implementera, testa och sprida dessa ändringar har varit en enorm teaminsats. Detta blev möjligt tack vare bidragen från andra tekniker i teamet för adminkonsolens grundfunktioner: Yunus Rahbar, Maryam Booshehrian, Saverio Castelli, Bronwyn Damm, Cindy Yu, Calvin Norton och Jaxsun McCarthy Huggan. Walter Li från Agent Success Tiger-teamet hjälpte till enormt mycket med att konfigurera rätt AI-verktyg för dessa migreringar.

Referenser

  1. Lan Cheng, Emerson Murphy-Hill, Mark Canning, Ciera Jaspan, Collin Green, Andrea Knight, Nan Zhang och Elizabeth Kammer, "What Improves Developer Productivity at Google? Code Quality," ESEC/FSE '22, november 2022. https://doi.org/10.1145/3540250.3558940

  2. ”Orchestrating AI Code Review at Scale”, Cloudflares blogg, april 2026. https://blog.cloudflare.com/ai-code-review/

  3. Napalys Klicius, ”Better tools made Copilot code review worse. Så här förbättrade vi den faktiskt”, The GitHub Blog, juli 2026. https://github.blog/ai-and-ml/github-copilot/better-tools-made-copilot-code-review-worse-heres-how-we-actually-improved-it/

  4. "Why Go is an Ideal Language for AI-Assisted Software Engineering", Google Developers Blog, augusti 2026. https://developers.googleblog.com/why-go-is-an-ideal-language-for-ai-assisted-software-engineering/

Relaterade artiklar

Asanas teknikfokus
teknik

Specifikationsdriven utveckling: Det positiva – och vad vi lärde oss efter tre månader