Shopify-varastolokisovelluksen MVP kahdessa päivässä: arkkitehtuuri, sudenkuopat ja opit

Rakensin Shopify-kauppiaille varastotapahtumien lokisovelluksen MVP:n kahdessa päivässä AI-avusteisesti. Tässä arkkitehtuuri ja ne bugit, jotka melkein jäivät huomaamatta.

Huomio nimistä: Tämä kirjoitus perustuu omaan, oikeaan työhöni. Yritysten ja toimittajien nimet on keksitty, eikä luottamuksellista dataa jaeta. Opit, arkkitehtuurit ja virheet ovat aitoja ja sellaisenaan käyttökelpoisia.

Shopifyn varastosaldo kertoo, mitä varastossa on nyt – mutta ei miksi. Kun saldo heittää, kauppias haluaa tietää: oliko kyseessä myynti, palautus, manuaalinen korjaus vai synkkausvirhe? Rakensin tähän tarpeeseen varastotapahtumien loki- ja auditointisovelluksen, jonka MVP syntyi kahdessa intensiivisessä päivässä AI-avusteisella kehityksellä.

Tässä sen arkkitehtuuri ja tärkeimmät opit – erityisesti ne kohdat, joissa nopea eteneminen olisi ilman varovaisuutta tuottanut epäluotettavan tuotteen.

Arkkitehtuuri: baseline + webhookit + ledger

Sovelluksen ydin on kolmivaiheinen:

  1. Baseline-synkronointi. Asennuksen yhteydessä haetaan nykyinen varastotila kaikista sijainneista. Ilman baselinea tapahtumaloki alkaa tyhjästä eikä mikään täsmää.
  2. Webhook-pohjainen tapahtumien vastaanotto. Shopifyn inventory-webhookit kirjoitetaan ensin raakana talteen ja käsitellään vasta sitten. Raakatapahtuman ja käsitellyn tapahtuman erottaminen tekee virheistä korjattavia: jos käsittelylogiikassa on bugi, tapahtumat voi ajaa uudelleen.
  3. Ledger-tapahtumakäsittely. Raakadatasta muodostetaan tapahtumakirjanpito (ledger): kuka/mikä muutti, missä sijainnissa, kuinka paljon, mihin suuntaan. Tapahtumat rikastetaan tuote- ja sijaintimetadatalla, jotta loki on luettava ilman jatkuvia API-hakuja.

Tämän päälle rakentuivat kauppiaan työkalut: suodatettava dashboard (suodatus palvelimella, ei selaimessa – lokidata kasvaa nopeasti), CSV-vienti, ylläpitäjän muistiinpanot tapahtumiin sekä sähköpostihälytykset.

Ne kaksi ominaisuutta, jotka erottavat lelun tuotteesta

Retentio. Tapahtumaloki kasvaa rajatta, joten vanhojen tapahtumien siivous ajastettuina töinä oli pakko rakentaa heti – ja siihen hälytys, joka varoittaa kauppiasta ennen kuin dataa poistuu.

Reconciliation-tarkistukset. Lokisovelluksen pahin mahdollinen vika on, että loki itse valehtelee. Siksi sovellus vertaa säännöllisesti omaa laskennallista saldoaan Shopifyn ilmoittamaan saldoon ja nostaa esiin erot. Tämä health check löysi kehitysvaiheessa oikeita bugeja – juuri siksi se kannattaa rakentaa ennen julkaisua, ei sen jälkeen.

Sudenkuopat, joihin melkein astuin

Webhook-duplikaatit. Shopify (kuten käytännössä kaikki webhook-lähteet) toimittaa saman tapahtuman joskus kahdesti. Ilman dedupe-logiikkaa ledger näyttää tuplakirjauksia, ja kauppiaan luottamus on mennyttä ensimmäisellä viikolla. Dedupe kannattaa tehdä idempotenssiavaimella tapahtuman tunnisteesta – ei ajallisella heuristiikalla.

SQLiten samanaikaisuus. MVP pyöri SQLitellä, ja webhook-ryöppy + dashboard-luku samaan aikaan toi esiin lukitusvirheitä. Konfiguraatio kuntoon (WAL-tila, busy timeout) ja kirjoitukset jonoon – tai suoraan Postgresiin, jos kuormaa on odotettavissa.

Puuttuva scope. Sijaintikohtainen raportointi vaati read_locations-oikeuden, joka puuttui alkuperäisestä scope-listasta. Oppi: käy sovelluksen oikeudet läpi ominaisuuslistaa vasten ennen julkaisua, koska scope-muutos julkaisun jälkeen tarkoittaa kauppiaille uudelleenhyväksyntää.

AI-avusteisen vauhdin kääntöpuoli

Kahden päivän MVP ei syntynyt siksi, että AI kirjoittaa koodia nopeasti, vaan siksi, että etenin tiukasti kerroksittain: baseline → webhookit → ledger → UI → operatiivinen kovennus (retentio, reconciliation, oikeudet, tyhjät tilat). Jokainen kerros testattiin ennen seuraavaa.

Kolmantena päivänä korjasin silti dashboardin autentikointibugin ja webhook-dedupen reunatapauksen. Se on normaalia: AI-avusteinen kehitys siirtää painopistettä kirjoittamisesta katselmointiin ja verifiointiin. Vauhti on aitoa, mutta vain jos joku – sinä – tarkistaa saumakohdat.

Muistilista vastaavaan projektiin

  • Tallenna webhookit raakana, käsittele erikseen, dedupaa idempotenssiavaimella
  • Rakenna baseline-synkronointi ennen tapahtumakäsittelyä
  • Suodata ja sivuta palvelimella alusta asti
  • Retentio + hälytykset ja reconciliation-tarkistukset kuuluvat MVP:hen, eivät "myöhemmin"-listalle
  • Tarkista API-scopet ominaisuuslistaa vasten ennen julkaisua
  • Varaa aikaa kovennuspäivälle heti buildin jälkeen