Siirry sisältöön

Tapaustutkimus

Bluumo: Kaksipuolinen hyvinvointimarkkinapaikka

Rooli: Itsenäinen full-stack-kehittäjä ja käyttökokemussuunnittelijaKesto: Noin 12 viikkoa (ensimmäinen versio)Asiakas: Bluumo (suomalainen hyvinvointialan startup-yritys)Tila: Live-demoympäristö; natiivisovellukset beetavaiheessa
Expo 54React NativeReact 19TypeScriptSupabaseVisma PayEdenredClaude APIAgoraUpCloud

Laajuus

181,000+

TypeScript-rivit

482

Tiedostot

120+

Näytöt / sivut

123

Uudelleenkäytettävät komponentit

80

Reunatoiminnot (Deno)

112+

Palvelu- ja apumoduulit

2,199+

Git-komitit

2

Aktiiviset maksupalveluntarjoajat

3 / 7

Kielet (live / infra)

3,937

Käännösavaimet

13

i18n-nimitilat

Ongelma

Perustaja johti hyvinvointipalveluita tarjoavaa startup-yritystä, jolla oli vain WordPress-esittelysivusto eikä lainkaan toiminnallisia valmiuksia. Jokainen puhelu, ajanvaraus ja lasku hoidettiin manuaalisesti. He tarvitsivat nopeasti käyttöönotettavan, tuotantokäyttöön soveltuvan kaksisuuntaisen markkinapaikan - jossa asiakkaat voivat etsiä ja varata hyvinvointipalveluiden tarjoajia ja tarjoajat hallita kalentereitaan ja tulojaan - sekä verkkosivustolla että mobiilisovelluksissa.

Mitä rakennettiin

Asiakaskäyttöliittymä (yli 11 näyttöä)

  • ·Palveluiden selaaminen luokkien, hinnan ja keston suodattimien avulla
  • ·Palveluntarjoajien haku arvioiden ja vertailutyökalujen avulla
  • ·Paikkatietopohjainen haku interaktiivisilla kartoilla
  • ·Saatavuustiedot reaaliajassa ja välitön varausvahvistus
  • ·Suomalaiset pankkisiirrot, korttimaksut, MobilePay, Edenred-hyvinvointikortit, KELAn korvauspalvelu
  • ·Toistuvien varauksien hallinta
  • ·Lahjakortin ostaminen ja PDF-tiedoston luominen
  • ·Suositteluohjelma, jossa palkkiot maksetaan automaattisesti
  • ·Bluumo Plus -tilauspaketti
  • ·Sovelluksen sisäiset äänipuhelut Agora-palvelun kautta
  • ·"Helmi" - Claude-teknologiaan perustuva tekoälykoncierge, joka auttaa varauksissa

Palveluntarjoajaportaalin (yli 13 näyttöä)

  • ·Asiakirjoihin perustuva todentaminen perehdyttämisvaiheessa
  • ·Monikielinen profiilien hallinta
  • ·Visuaalinen saatavuuskalenteri, joka synkronoituu Google-kalenterin kanssa
  • ·Dynaaminen hinnoittelu (ruuhka-ajat, alennukset, ajankohtaan perustuvat muutokset)
  • ·Reaaliaikaiset varausilmoitukset
  • ·Tulojen seuranta ja maksuhistoria (Holvin maksujärjestelmä on rakennettu, mutta ei vielä käytössä)
  • ·Varauksen tilaeteneminen alivaiheiden kautta visuaalisilla valmistumisilmaisimilla
  • ·'Merkitse valmiiksi' -toiminto palveluntarjoajan varaustyönkulun viimeistelyyn
  • ·Hallintatyökalujen ja palvelualueiden määrittämisen tarkastelu

Yritysten B2B-portaali

  • ·Yrityksen rekisteröinti hyväksymisprosessien avulla
  • ·Henkilöstöhallinto ja joukkotoiminnot
  • ·Hyvinvointipäivän varaus (yksittäiset ja ryhmävaraukset)
  • ·Kustannuspaikkojen seuranta, budjetinhallinta, esimiesten hyväksyntäjonot
  • ·Laskujen analysointi, käyttöraportointi, laskujen automaattinen luominen
  • ·Tarjouspyyntöjärjestelmä

Järjestelmänvalvojan hallintapaneeli (12 näyttöä)

  • ·Koko alustan kattavat avainmittarit ja analytiikka
  • ·Palveluntarjoajien todentamisen hallinta
  • ·Varauksien seuranta ja tukipyyntöjärjestelmä
  • ·Blogin julkaiseminen SEO-metatiedoilla
  • ·Kampanjoiden ja myynninedistämistoimien hallinta
  • ·Palautusten ja laskujen käsittely

Kuvakaappaukset

Tekninen arkkitehtuuri

FrontendExpo 54, React Native, React 19, TypeScript (strict mode) - yksi koodipohja iOS:lle, Androidille ja verkkosovelluksille Expo Routerin avulla
BackendSupabase (PostgreSQL, Auth) sekä 80 Deno-reunatoimintoa ja rivitason tietoturva neljälle käyttäjäroolille
PaymentsVisma Pay (suomalaiset pankit, kortit, MobilePay), Edenredin hyvinvointikortit; palvelinpuolen summavarmistus ja varaushinnan alaraja; tarjousalennukset, lahjakortit ja sosiaalirahastohyvitykset käsitellään palvelinpuolella; Smartum/Epassi odottaa tunnistetietoja
EmailMailgun (EU) ja yli 12 erilaista automaattista sähköpostityyppiä
AIClaude API - Helmi-concierge kolmella kielellä
VoiceAgora SDK ja turvallinen tunnisteiden luonti
i18n13 nimitilaa, 3 937 aktiivista käännösavainta - 3 kieltä käytössä (EN/FI/SV), 7 infrastruktuurissa
SEOReittikohtaiset metatiedot, OG/Twitter-kortit, dynaaminen sivukartta, JSON-LD blogikirjoituksille ja palveluntarjoajasivuille, FAQPage-schema, PNG OG -kuva sharp-kirjastolla
DeploymentUpCloud + Caddy nollakatvoksen sinivihreällä atomistisella deploylla; EAS natiivisovellusten rakentamiseen ja OTA-päivityksiin runtimeVersion-politiikalla

Tietoturvatarkastus (kesäkuu 2026)

Kesäkuussa 2026 toteutetussa riippumattomassa tietoturvatarkastuksessa havaittiin ja korjattiin joukko haavoittuvuuksia ennen kuin ne ehtivät levitä tuotantoympäristöön.

  • Palvelinpuolen maksutarkistus - maksusummat lasketaan uudelleen tietokannasta, ei asiakaspuolen hintoja luoteta
  • Varaushinnan alaraja estää alle raja-arvon hyökkäysyritykset
  • JWT-todentaminen lisätty kaikkiin reunafunktioihin
  • Tarjousalennukset, lahjakortit ja sosiaalirahastohyvitykset käsitellään palvelinpuolella
  • RLS:n avulla istunnon omistajille rajattu tekoälypohjainen chat
  • API-päätela­itteiden pyyntöjen määrän rajoittaminen
  • Blogisisällön XSS-suodatus
  • GDPR: viivästyneet poistot suoritettu, täydellinen tietojen vienti toimitettu
  • Supabasen tietoturvaneuvojan varoitukset: 105 - noin 36

Suorituskyky

  • ->Interaction Next Paint (INP) parani 1 280 millisekunnista alle 200 millisekuntiin StyleSheet-muistitoiminnon avulla
  • ->Raskaat toimet lykättiin välittömän visuaalisen palautteen vuoksi
  • ->OTA-päivitysten tuki EAS:n kautta, mikä mahdollistaa välittömät tuotantopäivitykset ilman sovelluskaupan tarkastusta

Mitä opin

Markkinapaikalla liikutellaan muiden ihmisten rahaa, mikä korostaa pienienkin virheiden seurauksia. Ne, jotka kirvelivät eniten, olivat kaikki hiljaisia.

Oletusarvon, joka tarkoittaa ”ei asetettu”, on oltava NULL

Jokaisesta varauksesta perittiin kiinteä 20 %:n provisio. Hinnoittelun laukaisija haarautui sen mukaan, oliko commission_rate-arvo annettu: arvo, joka ei ollut null, tarkoitti nimenomaista B2B-ohitusta, joten se ohitti sekä GMV-tason (24/22/20/18) että Bluumo Pro -alennuksen. Sarakkeella oli oletusarvo, joka ei ollut null, joten arvoa ei koskaan puuttunut ja ohitushaara voitti aina. Mitään virheitä ei ilmennyt, laskutoimitukset olivat oikein, mutta taulukon jokainen rivi oli väärä. Oletusarvon poistaminen mahdollisti sen, että puuttuva provisioarvo saatiin tallennettua NULL-arvona, jolloin laskutoimitus suoritettiin oikein. Jos haarautuma perustuu arvon olemassaoloon, skeeman on kyettävä ilmaisemaan juuri olemassaolo, ei arvoa.

Salliva varasääntö peittää ominaisuuden, joka ei ole koskaan toiminut

Etäisyyssuodatin ei suodattanut. Palveluntarjoajat otettiin mukaan, vaikka niillä ei ollut koordinaatteja, mikä on järkevä oletusasetus, eikä mikään koodipolku koskaan kirjoittanut palveluntarjoajan leveys- tai pituuspiiriä, joten jokainen palveluntarjoaja käytti varasuunnitelmaa ja näkyi millä tahansa säteellä. Toiminto näytti olevan toteutettu, palautti uskottavia tuloksia, mutta oli toimimaton. Varamenetelmä, joka sulkee tyhjän tapauksen pois, estää tyhjän tapauksen huomaamisen kokonaan.

Käyttöoikeuden peruuttaminen muuttaa select('*')-lauseen merkitystä

Taloudellisten sarakkeiden lukitseminen saraketason käyttöoikeuksien taakse aiheutti virheitä lukukyselyissä, joissa pyydettiin kaikkia tietoja. PostgREST ei voi hiljaisesti rajata select('*')-kyselyä niihin sarakkeisiin, jotka roolilla on oikeasti oikeus nähdä; ilman taulukotason SELECT-kyselyä se sen sijaan heittää virheilmoituksen. Korjaus on nimetä sarakkeet eksplisiittisesti jokaisessa kutsukohdassa, mikä on muutenkin parempi käytäntö, mutta opetus on se, että käyttöoikeuksien tiukentaminen on myös asiakaspuolen muutos, ei pelkästään tietokantapuolen.

Anna valinnaisten osien pettää, älä koko tapahtuman

Tämän alustan push-ilmoitukset palauttavat pelkän 500-virheen. Sen sijaan, että tämä näkyisi virheenä, niitä käyttävät prosessit siirtyvät sähköpostiin ja sovelluksen sisäisiin ilmoituksiin, ja nollattava palveluntarjoajan yhteystieto käyttää varasuunnitelmana tilin sähköpostiosoitetta sen sijaan, että viesti hylättäisiin. Se, että päätetään etukäteen, mitkä prosessin osat saavat epäonnistua huomaamatta ja mitkä eivät missään nimessä saa epäonnistua, on suurin syy siihen, miksi maksuprosessi tuntuu luotettavalta.

Linkit