[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"technology-pl-typescript":3,"technology-projects-pl-typescript":29,"mdc-dwcm8b-key":104},{"id":4,"title":5,"category":6,"content":7,"description":8,"extension":9,"faq":10,"icon":11,"links":12,"meta":21,"projects":22,"since":25,"stem":26,"updated":27,"__hash__":28},"technologies_pl\u002Fpl\u002Ftechnologies\u002Ftypescript.yml","TypeScript","frontend","TypeScript dodaje statyczne sprawdzanie typów do JavaScript. Używam go w aplikacjach Vue i Nuxt, w tym VetCard i tym portfolio, aby interfejsy komponentów oraz modele danych były łatwiejsze do zrozumienia i zmiany.\n\n## Co opisuję typami\n\n- **Komponenty** — parametry wejściowe, zdarzenia i wspólny stan.\n- **Modele API** — oczekiwaną strukturę danych placówek i rezerwacji.\n- **Wspólna logika** — argumenty i wyniki funkcji composable.\n\nW tym repozytorium działa też sprawdzanie typów w CI oraz schematy przetłumaczonej treści. Te kontrole uzupełniają się, ale odpowiadają za różne zadania.\n\n## Gdzie kończy się sprawdzanie statyczne\n\nTypy TypeScript są usuwane z wygenerowanego JavaScript. Adnotacja typu nie weryfikuje rzeczywistej odpowiedzi API. Dane zewnętrzne wymagają walidacji podczas działania aplikacji, a nieuzgodniona zmiana backendu nie pojawi się automatycznie jako błąd kompilatora.\n\n## Łatwiejsze utrzymanie\n\nPo zmianie zadeklarowanego modelu kontrola typów może wskazać niezgodne miejsca w kodzie. Pomaga to konsekwentnie zaktualizować formularze i szablony. Typowanie uzupełnia testy i walidację danych, zamiast usuwać potrzebę ich stosowania.\n","TypeScript w Vue i Nuxt: typowane komponenty, modele API i bezpieczniejsza refaktoryzacja z walidacją danych zewnętrznych.","yml",null,"i-simple-icons-typescript",[13,18],{"label":14,"to":15,"color":16,"icon":17},"typescriptlang.org","https:\u002F\u002Fwww.typescriptlang.org","neutral","i-heroicons-arrow-top-right-on-square",{"label":19,"to":20,"color":16,"icon":17},"Dokumentacja techniczna","https:\u002F\u002Fwww.typescriptlang.org\u002Fdocs\u002Fhandbook\u002F2\u002Fbasic-types.html",{},[23,24],"vetcard","vetspace","2020","pl\u002Ftechnologies\u002Ftypescript","2026-09-20","yxBKvm0_1AoQmXdv6t6c5rBnhQFUwscqBjIcur-YNII",[30,67],{"id":31,"title":32,"content":33,"date":27,"description":34,"extension":9,"featured":35,"image":36,"links":37,"meta":46,"stack":47,"stem":61,"tags":62,"url":40,"__hash__":66},"projects_pl\u002Fpl\u002Fprojects\u002Fvetcard.yml","VetCard","Publiczna część VetSpace — multi-tenant katalog klinik weterynaryjnych. Jeden deployment Nuxt SSR obsługuje wszystkie kliniki: strony klinik zoptymalizowane pod SEO, rezerwację wizyt online z proxy do własnego backendu tenant każdej kliniki, tematyzację pod markę kliniki oraz obsługę wielu oddziałów.\n\n## Kluczowe funkcje\n\n- **Jeden deployment — wiele klinik** — aplikacja routuje po slugu kliniki; żądania rezerwacji i slotów są proxy'owane do backendu tenant danej kliniki\n- **Katalog SEO-first** — 590+ klinik ze stronami SSR, danymi strukturalnymi i zlokalizowanymi trasami\n- **Branding każdej kliniki** — strona kliniki jest tematyzowana jej kolorem, z badge'em \"Powered by VetSpace\"\n- **Realny UX rezerwacji** — wolne sloty pokazują liczbę dostępnych lekarzy z kodowaniem kolorami\n- **Pełna lokalizacja** — ukraiński, angielski i polski z routingiem opartym na prefiksach\n\n## Stack technologiczny\n\n- **Frontend**: Nuxt 4 \u002F Vue 3, Tailwind CSS v4\n- **Backend**: Laravel catalog API + endpointy tenant do rezerwacji\n- **Renderowanie**: SSR dla stron SEO, CSR dla flow rezerwacji\n- **Testowanie**: testy jednostkowe Vitest + Cypress E2E na realnym backendzie\n","Multi-tenant katalog klinik weterynaryjnych: SEO strony klinik, rezerwacja wizyt online, branding każdej kliniki — jedna aplikacja Nuxt obsługuje wszystkie",true,"\u002Fhero\u002Fvetcard.avif",[38,42],{"label":39,"to":40,"color":41,"icon":17},"Live Demo","https:\u002F\u002Fvetcard.pro","primary",{"label":43,"to":44,"color":16,"icon":45},"Przegląd projektu","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-vetcard","i-simple-icons-github",{},[48,51,54,55,58],{"name":49,"icon":50},"Nuxt","i-simple-icons-nuxtdotjs",{"name":52,"icon":53},"Vue","i-simple-icons-vuedotjs",{"name":5,"icon":11},{"name":56,"icon":57},"Tailwind CSS","i-simple-icons-tailwindcss",{"name":59,"icon":60},"Laravel API","i-simple-icons-laravel","pl\u002Fprojects\u002Fvetcard",[49,52,63,64,65],"Multi-tenant","SEO","SSR","4Q1qMR6jtn2ViojU9Uk8TaztwOrlQBTjLNLBv9AASnE",{"id":68,"title":69,"content":70,"date":71,"description":72,"extension":9,"featured":35,"image":73,"links":74,"meta":85,"stack":86,"stem":100,"tags":101,"url":76,"__hash__":103},"projects_pl\u002Fpl\u002Fprojects\u002Fvetspace.yml","VetSpace","Dwustronna platforma weterynaryjna — katalog SEO klinik i CRM oparty na subskrypcji z wizytami i rekordami pacjentów. Publiczny katalog klinik zbudowany pod kątem pozyskiwania klientów przez SEO oraz CRM oparty na subskrypcji (wizyty, rekordy pacjentów) jako osobne aplikacje Vue\u002FNuxt na jednym API Laravel. Architektura database-per-tenant, subskrypcje Stripe przez Cashier, GraphQL + REST oraz analiza wizyt wspomagana AI przez dedykowany mikroserwis w Go.\n\n## Kluczowe funkcje\n\n- **Dwustronny lejek** - katalog SEO pozyskuje kliniki, a CRM w subskrypcji (wizyty, rekordy pacjentów) je utrzymuje\n- **Prawdziwa izolacja tenantów** - database-per-tenant trzyma dane każdej kliniki osobno, a eksport\u002Fusuwanie GDPR to operacja na bazie\n- **Dwa interfejsy API** - GraphQL dla złożonych zapytań katalogu, REST dla CRM — jedna baza kodu Laravel\n- **Billing od ręki** - subskrypcje Stripe przez Cashier: triale, zmiany planów, dunning\n- **AI tam, gdzie pomaga** - analizę wizyt wykonuje dedykowany mikroserwis w Go, nie obciążając głównego API\n\n## Stos technologiczny\n\n- **Backend**: Laravel (API)\n- **Frontend**: Vue\u002FNuxt (osobne aplikacje)\n- **Architektura**: Multi-tenancy database-per-tenant\n- **Płatności**: Stripe przez Cashier\n- **API**: GraphQL + REST\n- **AI**: Mikroserwis Go do analizy wizyt\n","2026-09-19","Dwustronna platforma weterynaryjna — katalog SEO klinik i CRM oparty na subskrypcji z wizytami i rekordami pacjentów","\u002Fhero\u002Fvetspace.avif",[75,77,80,83],{"label":39,"to":76,"color":41,"icon":17},"https:\u002F\u002Fvetspace.pro",{"label":78,"to":79,"color":16,"icon":45},"Przegląd API","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-api",{"label":81,"to":82,"color":16,"icon":45},"Przegląd frontendu","https:\u002F\u002Fgithub.com\u002FYurij2015\u002Fvetspace-frontend",{"label":84,"to":44,"color":16,"icon":45},"Przegląd VetCard",{},[87,89,90,91,94,97],{"name":88,"icon":60},"Laravel",{"name":52,"icon":53},{"name":49,"icon":50},{"name":92,"icon":93},"Stripe","i-simple-icons-stripe",{"name":95,"icon":96},"GraphQL","i-simple-icons-graphql",{"name":98,"icon":99},"AI","i-heroicons-sparkles","pl\u002Fprojects\u002Fvetspace",[102,88,52,63,92,98],"SaaS","xvJ2gsG93A4aTrZYPgp4UuQdQsPe-Ae8ups9tasKAD8",{"data":105,"body":106},{},{"type":107,"children":108},"root",[109,117,124,160,165,171,176,182],{"type":110,"tag":111,"props":112,"children":113},"element","p",{},[114],{"type":115,"value":116},"text","TypeScript dodaje statyczne sprawdzanie typów do JavaScript. Używam go w aplikacjach Vue i Nuxt, w tym VetCard i tym portfolio, aby interfejsy komponentów oraz modele danych były łatwiejsze do zrozumienia i zmiany.",{"type":110,"tag":118,"props":119,"children":121},"h2",{"id":120},"co-opisuję-typami",[122],{"type":115,"value":123},"Co opisuję typami",{"type":110,"tag":125,"props":126,"children":127},"ul",{},[128,140,150],{"type":110,"tag":129,"props":130,"children":131},"li",{},[132,138],{"type":110,"tag":133,"props":134,"children":135},"strong",{},[136],{"type":115,"value":137},"Komponenty",{"type":115,"value":139}," — parametry wejściowe, zdarzenia i wspólny stan.",{"type":110,"tag":129,"props":141,"children":142},{},[143,148],{"type":110,"tag":133,"props":144,"children":145},{},[146],{"type":115,"value":147},"Modele API",{"type":115,"value":149}," — oczekiwaną strukturę danych placówek i rezerwacji.",{"type":110,"tag":129,"props":151,"children":152},{},[153,158],{"type":110,"tag":133,"props":154,"children":155},{},[156],{"type":115,"value":157},"Wspólna logika",{"type":115,"value":159}," — argumenty i wyniki funkcji composable.",{"type":110,"tag":111,"props":161,"children":162},{},[163],{"type":115,"value":164},"W tym repozytorium działa też sprawdzanie typów w CI oraz schematy przetłumaczonej treści. Te kontrole uzupełniają się, ale odpowiadają za różne zadania.",{"type":110,"tag":118,"props":166,"children":168},{"id":167},"gdzie-kończy-się-sprawdzanie-statyczne",[169],{"type":115,"value":170},"Gdzie kończy się sprawdzanie statyczne",{"type":110,"tag":111,"props":172,"children":173},{},[174],{"type":115,"value":175},"Typy TypeScript są usuwane z wygenerowanego JavaScript. Adnotacja typu nie weryfikuje rzeczywistej odpowiedzi API. Dane zewnętrzne wymagają walidacji podczas działania aplikacji, a nieuzgodniona zmiana backendu nie pojawi się automatycznie jako błąd kompilatora.",{"type":110,"tag":118,"props":177,"children":179},{"id":178},"łatwiejsze-utrzymanie",[180],{"type":115,"value":181},"Łatwiejsze utrzymanie",{"type":110,"tag":111,"props":183,"children":184},{},[185],{"type":115,"value":186},"Po zmianie zadeklarowanego modelu kontrola typów może wskazać niezgodne miejsca w kodzie. Pomaga to konsekwentnie zaktualizować formularze i szablony. Typowanie uzupełnia testy i walidację danych, zamiast usuwać potrzebę ich stosowania."]