Oman tuloskehityksen seuranta

Kisa­kalenteri

Vuosien juoksudata — kisat, ennätykset ja tulokset yhdellä sivulla.

Kimmo AkkanenKlaukkala · · kisoja vuodesta 2013

Ennätykset

personal bests

Nopeimmat ajat

Pisimmät suoritukset

Matkakertymä

kisoja & kilometrejä

Konepellin alla

arkkitehtuuri & putki

Tämä sivu on täysin staattinen HTML-tiedosto, joka generoidaan öisin tietokannasta — käsin ylläpidettävää sisältöä ei ole.

Datakerros. Sivun data elää Neon Postgres -kannassa, joka on osa laajempaa henkilökohtaista datajärjestelmääni: samaan kantaan synkataan öisin koko Strava-historiani (activities-taulu, 03:07 UTC) sekä Garminin hyvinvointidataa, ja sinne on viety myös labramittauksia — kehonkoostumustulokset (InBody) ja juoksumaton kuntotestit vuodesta 2016 alkaen. Tämä sivu lukee kannasta yhden taulun, races: kategoria, virallinen chip-aika sekunneiksi johdettuna, päivämäärä tarkkuuksineen, nousumetrit, koordinaatit ja Strava-id, josta muodostetaan linkki tallenteeseen. Viralliset ajat ovat aina järjestäjän chip-aikoja, eivät GPS-kellon dataa.

Kirjaus. Uudet tulokset, tulevat kisat ja labramittaukset kirjataan kantaan Clauden ja Neon MCP -integraation kautta — luonnollisella kielellä, ilman SQL-käsityötä. Kun kisa on juostu, sanon tuloksen, ja INSERT tapahtuu oikeaan tauluun oikeilla johdannaisilla.

Build. GitHub Actions -workflow (cron 03:37 UTC + manuaalinen dispatch) ajaa Python-generaattorin, joka hakee rivit psycopg 3:lla, laskee ennätykset, PB-merkinnät ★, matkakertymät, paikkakoosteen ja kehityssarjat — sama kisa vähintään kolmesti juostuna muodostaa trendin, ja maantiematkoille lasketaan lisäksi ikävakioidut ajat (likimääräiset WMA-kertoimet, ikä kisapäivänä) — ja injektoi tuloksen JSON:ina HTML-templaattiin. Yksi ajo, yksi tiedosto.

Julkaisu. Valmis index.html työnnetään julkisen repon gh-pages-haaraan, jota GitHub Pages tarjoilee tässä osoitteessa (custom domain A-tietueilla, TLS Let's Encryptillä). Palvelinta tai tietokantayhteyttä ei sivulla ole — pelkkä nopea staattinen tiedosto.

Varmuuskopiot. Kanta dumpataan öisin (05:37 UTC, pg_dump, versiotunnistus palvelimelta) validoituna privaattiin repoon rotaatiolla: 7 päivittäistä, kuukausittainen ja vuosittainen. Kerran kuussa erillinen workflow palauttaa tuoreimman dumpin puhtaaseen Postgres-konttiin ja verifioi rivimäärät sekä sisällön — varmuuskopio jota ei koskaan palauteta on toivomus, ei vakuutus.

Frontend. Yksi HTML-tiedosto ilman frameworkkia. Maapallo on D3.js:n ortografinen projektio (world-atlas TopoJSON), joka pyörii animaatioloopissa ja tukee drag-rotaatiota sekä rulla-/nipistyszoomia. Kehityskäyrät ovat puhdasta käsin generoitua SVG:tä ilman kirjastoriippuvuuksia — absoluuttinen aika yhtenäisenä viivana, ikävakioitu katkoviivana samassa kuvaajassa. Laskuri seuraavaan kisaan ja ikä lasketaan selaimessa, joten ne pysyvät ajan tasalla buildien välilläkin.

Kehitys. Koodi on rakennettu tekoälyavusteisesti (Claude & ChatGPT) — arkkitehtuurista SQL:ään ja D3-koodiin. Nykyään muutokset tekee Claude Code paikallisena agenttina erillisellä kehityskoneella: se muokkaa koodia, generoi sivut ja tarkistaa ne selaimessa ennen kuin mitään julkaistaan. Pelisäännöt ovat selkeät: jokainen muutos kulkee omassa haarassaan pull requestin kautta, push ja merge vaativat aina ihmisen hyväksynnän, eikä päähaaraan pushata suoraan. Säännöt (aikavyöhyke, ajastusten järjestys, eheystarkistukset joita ei saa ohittaa) on kirjattu repoon agentin luettaviksi. Kehityskoneelta koodia ajetaan vain Neonin dev-haaraa vasten; tuotantokantaa käyttää ainoastaan GitHub Actions, joten yöajot eivät riipu kehityskoneesta.

Kun kisa on juostu, tulos kirjataan kantaan — aamulla sivu on ajan tasalla.