Fallstudie
Tidbok
Onlinebokning för småföretag. Kunden väljer tjänst, person och tid på hemsidan, personalen ser dagen i en vy. Byggt i C# och .NET 8, med en databas som inte släpper igenom två bokningar på samma tid.
- Roll
- Allt: regler, databas, API, gränssnitt, tester, drift
- Byggt med
- C#, .NET 8, ASP.NET Core, SQLite, JavaScript
- Status
- Öppen testmiljö på Render
- Kvalitet
- 49 tester, körs före varje bygge
Problem
En frisör med sax i handen kan inte svara i telefon. En liten klinik har en person i receptionen som gör tre saker samtidigt. För sådana verksamheter är bokningen det viktigaste på hela hemsidan, och det som oftast saknas.
De färdiga bokningstjänsterna kostar varje månad och ser sällan ut som resten av sajten. Jag ville bygga något jag själv kan lägga på en kunds hemsida med två rader kod, i kundens färg, och förstå in i minsta detalj.
Vem använder det
Kunden väljer tjänst, person eller "första lediga", dag och tid. Dagar utan tider är utgråade med skälet: stängt, fullbokat eller juldagen. Bekräftelsen har ett bokningsnummer, en kalenderfil och en egen länk för att avboka.
Personalen ser dagen med en kolumn per person, blockerar lunch eller en sjukdag, avbokar åt kunden och ändrar tjänster, priser och arbetstider själv. Överst står veckans beläggning och hur många som avbokat.
Min roll
Jag byggde allt själv: reglerna för lediga tider, databasen, API:t, bokningssidan, adminvyn, widgeten, testerna och driftsättningen. Verksamheterna i testmiljön har samma tjänster, priser och personal som två av exempelsajterna, så att hela kedjan från hemsida till bokning går att prova.
Arkitektur
Tre projekt. En kärna med regler och modell utan databas eller webb, ett datalager mot SQLite och ett webbprojekt med ett minimalt API för bokningen och Razor Pages för adminvyn.
- Lediga tider är rena funktioner. Schema, upptagen tid och klockslag in, lediga tider ut. Samma funktion visar tiderna och kontrollerar bokningen, så de kan aldrig säga olika saker.
- Röda dagar räknas fram. Påsk, midsommar och alla helgons dag flyttar sig varje år. Det sköts av Helgdagar, ett litet bibliotek jag skrev för just det här.
- Avbokningslänken sparas som hash. Den som kommer åt databasen kan ändå inte avboka någon annans tid.
- Kunduppgifter gallras. Namn, telefon och meddelande tas bort 30 dagar efter besöket. Bokningen står kvar i statistiken utan koppling till personen.
- Strikt CSP. Inga inline-skript och inga inline-stilar. Verksamhetens färg kommer som en egen liten stilmall.
Svåraste delen
Två kunder som klickar på samma tid i samma sekund. Det vanliga felet är att båda läser "ledigt" och båda sparar. Här tas databasens skrivlås innan något läses, schemat hämtas på nytt inne i låset och tiden kontrolleras en gång till. Ett test skickar tjugo samtidiga bokningar på samma tid och kräver att exakt en går igenom.
Miljön jag byggde i nådde inte NuGet, så det vanliga paketet för SQLite gick inte att hämta. Jag skrev ett tunt lager direkt mot SQLite:s C-API i stället, med parametrar för all SQL. I ett team hade jag tagit EF Core, och lagringen ligger bakom ett gränssnitt så att bytet är en klass.
På en kunds hemsida
En skript-rad och en knapp. Knappen öppnar bokningen i en ruta ovanpå sidan, så besökaren lämnar aldrig kundens sajt. Bokningssidan är den enda delen som får bäddas in på andra sajter. Admin och avbokning går aldrig att rama in.
Resultat
En fungerande testmiljö med två påhittade verksamheter, en salong och en tandvårdsklinik, med scheman, luncher och bokningar tre veckor bakåt. Man kan boka som kund, avboka med länken, och logga in som personal för att se samma bokning dyka upp i dagsvyn. 49 tester täcker reglerna och hela flödet mot en riktig databasfil, och Docker-bygget stannar om något av dem fallerar.
Medvetna begränsningar: inga bekräftelser via e-post eller SMS än, och testmiljön läses in på nytt när tjänsten startar om, eftersom gratisnivån saknar beständig disk. Nästa steg är utskick, påminnelser dagen innan och betalning vid bokning.
Länkar
Testa Tidbok · Källkoden på GitHub · Helgdagar
Gratisnivån somnar när ingen använt den på en stund. Första sidladdningen kan ta upp till en minut.